zamulający program na AVR

To znów ja, i pewnie znów z problemem, który ma jakieś banalne rozwiązanie. Postawnowiłem się w końcu przesiąść z mocno już leciwego GCC AVR (pakiet WinAVR) w wersji 20050214 na najnowszą jaka jest dostępna. Program na Mega 8, napisany na starej wersji, skompilował się bez błędów i ostrzeżeń (te dotyczące innego umiejscowienia niektórych bibliotek jak signal.h skrupulatnie wypełniłem). Niestety w rzeczywistym układzie jest totalna porażka - urządzenie zachowuje się, jakby nie było taktowane kwarcem 8MHz, lecz co najwyżej 10kHz. Cały program wykonuje się koszmarnie wolno, np. dane na wyświetlacz OLED wysyłane po I2C pojawiają się teraz znak po znaku, a wcześniej następowało to bez widocznego opóźnienia.

Coś się pozmieniało w bibliotekach, czy w w makefile powinienem coś dopisać bądź zmienić?

Reply to
badworm
Loading thread data ...

W dniu 2016-04-07 o 15:58, badworm pisze:

To sprawdź ustawienia bitów konfiguracyjnych uC - na jakim oscylatorze pracuje.

Reply to
szod

Dnia Thu, 7 Apr 2016 17:04:31 +0200, szod napisał(a):

Kompilator do fusebitów raczej dostępu nie ma. Przed chwilą porównałem prędkość zegara I2C dla wsadów z obu kompilatorów. Różnica jest kolosalna - dla nowego GCC to zaledwie 5kHz, dla starego ponad 80kHz. Kod generujący opóźnienia dla tej magistrali wygląda tak:

#include <avr\io.h>

#include <inttypes.h>

#include "harddef.h" #include "makra.h" #include "i2c.h"

// Wyliczenie czasu opóźnienia połówkowego i ćwiartkowego (cykle) #define I2C_nhalf (F_CPU/I2C_SPEED/2)

// Funkcja dłuższych opóźnień #if I2C_nhalf < 3 // Nic #elif I2C_nhalf < 8 static void i2c_xdelay(void) { NOP(); } #else #define I2C_delayloops (1+(I2C_nhalf-8)/3) #if I2C_delayloops > 255 #error Przyspiesz - bo sie nie wyrabiam ;) #endif static void i2c_xdelay(void) { asm volatile( \ "delayus8_loop%=: \n\t"\ "dec %[ticks] \n\t"\ "brne delayus8_loop%= \n\t"\ : :[ticks]"r"(I2C_delayloops) ); } #endif //I2C_nhalf >= 3

// Opóźnienia dla I2C static inline void i2c_hdelay(void) { #if I2C_nhalf < 1 return; // To jest funkcja inline, jeśli składa się tylko z "return" jest usuwana podczas optymalizacji #elif I2C_nhalf < 2 NOP(); #elif I2C_nhalf < 3 asm volatile( "rjmp exit%=\n\t" "exit%=:\n\t"::); #else i2c_xdelay(); #endif }

Reply to
badworm

W dniu 07.04.2016 o 17:37, badworm pisze:

F_CPU masz dobrze ustawione?

Reply to
Grzegorz Kurczyk

Dnia Thu, 7 Apr 2016 18:12:39 +0200, Grzegorz Kurczyk napisał(a):

Tak, F_CPU = 8000000. Rzecz polega na tym, że dokładnie ten sam projekt skompilowany na starym GCC chodzi prawidłowo, a na nowym - muli się.

Reply to
badworm

badworm pisze: [..]

Ja nie szprecham w C więc może się mylę, czy Ty nie używasz sprzętowego I2C ? Atmega 8 ma takowy i działa znakomicie. [..]

Reply to
AlexY

W dniu 2016-04-07 o 20:02, AlexY pisze:

i2c masz sprzętowy czy softowy? Mozesz pokazac biblioteki do TWI?

Reply to
wchpikus

wchpikus pisze:

Komu odpisujesz? Bo to raczej nie do mnie pytanie.

Reply to
AlexY

badworm snipped-for-privacy@post.pl napisał(a):

Może to jest kwestia optymalizacji? Czy nie lepiej te opóźnienia generować z pomocą timera lub też funkcjami bibliotecznymi? Rozumiem, że to jest programowe I2C i nie możesz użyć sprzętowego?

Reply to
Grzegorz Niemirowski

Co w tym jest?

Reply to
Marek

czyli co, napisałeś program, a kompilator przerobił go sobie na jakiś inny? dobrze, że nawet nie starałem się pojąć sukcesu kompilatora gcc...

Reply to
platformowe głupki

platformowe głupki snipped-for-privacy@go2.pl napisał(a):

Nic niezwykłego. Z optymalizacjami namęczyłem się trochę portując swój stary kod z IAR do GCC. Ostatnio też poznałem opcję -fsigned-char, bo okazało się, że znakowość dla char jest nieokreślona w standardzie i na ARM jest inaczej implementowana niż gdzie indziej.

Reply to
Grzegorz Niemirowski

ale dlaczego tak się dzieje, przeciez jest jakaś norma na język C, czemu te wstawki dla AVR są takie pojebane, jakieś totalne idiotyzmy jak się czyta avr-libc-user_manual... i wszyscy sobie to niby chwalą... dla mnie nie ma czego...

Reply to
platformowe głupki

platformowe głupki snipped-for-privacy@go2.pl napisał(a):

Właśnie podałem przykład gdy norma pozostawia coś bez doprecyzowania: The three types char, signed char, and unsigned char are collectively called the character types. The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char. ... Irrespective of the choice made, char is a separate type from the other two and is not compatible with either.

-ISO 9899:1999, sekcja "6.2.5 Types"

A są?

To jest całkiem dobry kompilator. Może nie idealny, ale całkiem w porządku i za darmo.

Reply to
Grzegorz Niemirowski

no nie wiem, cały czas odnoszę wrażenie że to jedna wielka prowizorka...

Reply to
platformowe głupki

pogadajmy o dokumentacji do avr-gcc... ja znam jedną (której nie byłem w stanie przeczytać bo była tak niechlujnie napisana): avr-libc-user_manual... gdzie znajdę te wszystkie rozszerzenia gcc dla AVR? istnieje jakiś w miarę kompletny tutorialek? doc?

Reply to
platformowe głupki

Dnia Fri, 8 Apr 2016 15:51:41 +0200, Grzegorz Niemirowski napisał(a):

Tak, to jest programowe I2C, na bazie bibliotek z kursu C, jaki był w EdW już dosyć daawno temu. Wygląda na to, że najszybciej będzie mi przejść na TWI, bo z tego, co widzę, to mam taką możliwość - odpowiednie piny są do zagospodarowania. Programowe I2C zostawię sobie docelowo do obsługi SHT11, bo ten układ zdaje się, że ma interfejs nie w pełni kompatybilny z prawdziwym I2C, a wolne taktowanie SCL raczej nie przeszkodzi.

Swoją drogą - spróbowałem manewru polegającego na skopiowaniu odpowiedniego pliku nagłówkowego dla MEGA324PA z nowego GCC do starego, z czystej ciekawości. Po zmianie wpisu o typie procesora w makefile program się niby skompilował i nawet bez błędów, ale mam poważne podejrzenia, że to tylko ściema. Nazwy rejestrów obsługujących np. porty USART różnią się, więc nie ma siły, by nie było błędów na etapie kompilacji - przerabiałem to kiedyś zmieniając MEGA 8 na MEGA162.

Reply to
badworm

badworm snipped-for-privacy@post.pl napisał(a):

Którego pliku i po co?

Z czego na co?

Trudno coś powiedzieć bez kodu. Zwykle robi się tak, że dołącza się plik <avr/io.h>. W pliku tym są warunkowe dołączenia plików nagłówkowych danego procesora na podstawie makra generowanego przez wybór danego mikrokontrolera parametrem -mmcu: #elif defined (__AVR_ATmega324PA__) # include <avr/iom324pa.h>

Jak sobie na siłę dołączysz avr/iom324pa.h to się pewnie skompiluje niezależnie od wyboru -mmcu.

Reply to
Grzegorz Niemirowski

Dnia Sat, 9 Apr 2016 00:26:27 +0200, Grzegorz Niemirowski napisał(a):

Plik iom324pa.h w katalogu /avr/include/avr/ - to chyba w plikach tam się znajdujących są definicje np. rejestrów we wszystkich obsługiwanych typach procesorów.

# MCU name MCU = atmega8

na

# MCU name MCU = atmega324pa

Początek pliku main.c wygląda u mnie tak:

#include <avr\io.h>

#include <stdio.h>

#include <stdlib.h>

#include <inttypes.h>

#include <avr\signal.h>

#include <avr\interrupt.h>

#include <avr\pgmspace.h>

#include <avr\eeprom.h>

#include <avr\delay.h>

A w wersji, która kompiluje się w najnowszym GCC bez błędów tak:

#include <avr\io.h>

#include <stdio.h>

#include <stdlib.h>

#include <inttypes.h>

//#include <avr\signal.h>

#include <avr/interrupt.h>

#include <avr\pgmspace.h>

#include <avr\eeprom.h>

#include <util/delay.h>

Jak wspomniałem, kiedyś próba bezpośredniego przeniesienia kodu z Mega 8 na Mega 162 tylko poprzez zmianę przytoczonego wyżej wpisu w makefile skończyła się błędami przy kompilacji, bo 162 ma dwa porty USART, a w związku z tym inne są nazwy rejestrów, obsługujących ten interfejs. Tutaj więc oczekiwałem podobnej reakcji, ale widzę iż zarówno nowe, jak i stare GCC żadnych problemów nie zgłaszają :/

Z obsługą TWI mam chwilowo jakiś problem, przykładowe funkcje znalezione w sieci (np. tutaj

formatting link
choć są bardzo proste, to chyba nie do końca mi działają. Mam wrażenie, że program się z jakiegoś powodu wysypuje dokumentnie. Póki co zostawiam ten temat do ogarnięcia na później, będę chciał najpierw przetestować funkcje obsługi TWI na spokojnie a dopiero potem dodać je do docelowego programu. Najważniejsza jest dla mnie teraz przesiadka na MEGA 324, bo z programowym I2C jakoś to wszystko działa, a nie załaduję przecież kodu dla Mega 8 do większego procka.

Reply to
badworm

Skompiluj:

DDRA = 0xff;

while(1) { PORTA = 0x00; PORTA = 0xff; }

I oceniaj częstotliwość na wyjściu. Powinno być bodaj f/4 bo cała pętla zajmuje 4 cykle. Pozwoli to wyeliminować oczywisty problem z fuse bitami.

Sprawdź czy masz w ogóle -O1/2 jako flagi kompilacji.

Ponadto pamiętaj że zazwyczaj delay() jest pisana przez ignorantów i wydziargana ręcznie aby działała na jakimś konkretnym kompilatorze.

Reply to
Sebastian Biały

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.