Powód jest bardzo prosty: zmniejszenie zmiennej w pamięci nie jest operacją atomową. Co prawda za każdym razem następuje odczytanie zmiennej, zmniejszenie jej a następnie zapis, to jeśli przerwanie wystąpi pomiędzy odczytem a zapisem, to utracisz zmianę dokonaną w przerwaniu. W przypadku gdy przerwanie i funkcja main konkurują o jeden zasób, musisz...
słowo kluczowe "volatile"
Dopisz "volatile".
zadeklaruj jako static w przerwaniu - jako volatile Zmienne używane globalnie + w przerwaniach powinny być volatile. Wtedy kompilator ci ich nie "zniszczy". Doskonały opis volatile w http://mirekk36.blogspot.com/2011/08/tes...
Zmienną 'flaga' ustalasz w przerwaniu wiec powinna być volatile. p.s. Samych rejestrów nie sprawdzalem.
Jeśli to dla Ciebie takie jasne, to napisz dlaczego ma być volatile? Przerwanie nie modyfikuje zmiennej. Albert
Nie masz dostępu do zmiennej, czy po prostu odczyt zawsze zwraca tą samą wartość (efekt braku volatile przy deklarowaniu zmiennej używanej przez przerwanie)? Bez "volatile" kompilator zoptymalizuje odwołania do zmiennej "status" w funkcji main - zmienna nie jest nigdy odczytywana (kompilator nie uwzględnia tego, że może przyjść przerwanie - widzi tylko...
Wiem o tym, natomiast usunąłem w ten sposób zmienne volatile, docelowo tak nie będzie, to tylko w celach testów, jak tylko wrócę, narysuję algorytm. :D:D:D A w czym Ci przeszkadzały? Dla testów także nieodpowiednie. TMF pisząc: ... zmienne, które wykorzystujesz w przerwaniu są volatile, co sugeruje, że jeszcze gdzieś z nich korzystasz. ... ...miał...
A, że tak głupio spytam przerwanie w ogóle jest wywoływane?
W pierwszej kolejności zadeklaruj zmienne seconds , minutes oraz hours jako volatile . Modyfikujesz ich wartość w przerwaniu i odczytujesz w programie głównym (w tym czasie może wystąpić przerwanie). secondsBuffer , minutesBuffer oraz hoursBuffer musi być co najmniej 3. Funkcja itoa() dodaje znak końca łańcucha tekstowego.
Oznacz zmienne występujące w przerwaniach jako volatile.
a co jest nie tak z pętlą while(1) bo nie mogę się dopatrzeć To, że jest pusta. Stan zmiennej flaga sprawdzasz tylko raz na początku programu, po czym zapętlasz go w pustej pętli. Poza tym sprawdzanie if(flaga=1) jest błędem, zapewne miało być if(flaga==1) - przeczytaj ostrzeżenia kompilatora generowane w czasie kompilacji.
[syntax=c] ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {Time_out=0;}; int x; do { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { x=Time_out;); } while (x < 1000); [/syntax]
A nie prościej użyć break w pętli while który będzie wywoływany jeśli jakaś tam zmienna globalna się ustawi? Do tego przypominam że musi to być zmienna volatile.
Problem tkwi w miejscu gdzie są inicjowane wartości zmiennych do odnierzania czasu. Niestety nie :( Problem tkwi tu: /* TIMSK = 130; // globalne odblokowanie przerwań /* TIMSK |=(1<<TOIE1); Skąd wytrzasnąłeś te 130 :?: Piotrek PS A jaki to proc :?:
Możesz zmieniać ją w dowolnym miejscu programu o ile będzie to zmienna typu volatile. Przerwanie w takim przypadku należy zablokować na czas modyfikacji w pętli głównej jeśli zmienna jest co najmniej 2 bajtowa. Uchrania do przed przypadkiem wywołania przerwania pomiędzy zapisem kolejnych bajtów.
Jeżeli odwołujesz się do zmiennej w pętli głównej i w przerwaniu zadeklaruj ją jako volatile .
Jeszcze przy zmiennych występujących w przerwaniach dodaj modyfikator volatile .
Zgadza się, jeśli zmienna jest volatile, to kompilator musi bezwzględnie realizować wszystkie dostępy bez buforowania odczytu ani opóźniania zapisu. Jak by nie patrzeć, kompilator optymalizuje kod zakładając liniowy(sekwencyjny) sposób wykonywania: w obrębie danej funkcji (jaka by ona nie była: program główny, przerwanie czy cokolwiek innego) można...
Tak jak piszą koledzy - utworzyć lokalną kopię zmiennej counter, żeby nie była volatile w przerwaniu. Ale prawdziwa optymalizacja to zmiana algorytmu - jak pamiętam chodzi ci o 12-kanałowy PWM. Lepiej więc zrobić tablicę przechowującą stan kanałów w danej jednostce czasu, wtedy 16-kanałowy PWM to będzie tylko PORTB=channel[counter].lo; PORTD=channel[counter].hi....
Witam, zadeklaruj zmienną d jako: volatile unsigned char d; kompilator będzie wiedział, że zmienna ta może zostać zmieniona z zewnątrz(przerwanie). Poczytaj o volatile to się wyjaśni. Pozdrawiam wojt
Odnoszę się do kodu z postu #24. Zmienne 'wyslij' oraz 'ilosc' powinny mieć kwalifikator volatile ponieważ są używane w programie oraz w procedurze obsługi przerwania. [syntax=c] volatile int ilosc; volatile bool wyslij; [/syntax] Wywołanie funkcji serial() w pętli loop() może być wielokrotnie "przerwane" przez obsługę przerwania ENKODER_ISR() jeżeli...
Masz skasować flagę timera OCF0A [syntax=c]TIFR0 |= (1<<OCF0A); [/syntax] Możesz też włączyć przerwanie od Timera i zostawić pustą obsługę przerwania: [syntax=c] ISR (TIMER0_COMPA_vect, ISR_NAKED) { asm volatile("reti"); } [/syntax] Co spowoduje że cała obsługa przerwania sprowadzi się do RETI
Kolega el2010tmp ma rację - możesz zrealizować tego typu wielozadaniowość przy pomocy przerwań czasowych. 1. Przy pomocy biblioteki Timer1 definiujesz funkcję, która wykonuje się np. co 5 ms. 2. W tejże funkcji wywołujesz coś w stylu analogWrite(led_level++), aż led_level osiągnie żądany poziom maksymalny. 3. Komunikacja między funkcją przerwania a...
licznik0 i licznik1 muszą być zadeklarowane jako volatile
a słyszałeś kiedyś o zmiennych typu volatile ???? poczytaj sobie do czego służy słówko volatile a na pewno szybko poradzisz sobie z tym problemem
x i y muszą być zadeklarowane jako volatile.
Czy zmienna kierunek jest globalna i volatile? Już po pierwszym przerwaniu powinna przyjąć wartość 1 lub 2, a nie być cały czas 0. Czy zaobserwowałeś zwiększanie wartości zmiennej enkoderA ?
bo jest volatile a przecież ta funkcja ma związek z przerwaniami więc zmienna, która się podaje jako argument powinna być volatile. Nie musi. Nie wiem, dlaczego nie chcesz po prostu zrobic jak Ci napisałem. Masz gotowe dwa handlery. Dodatkowym plusem jest to, że będzie działać dwukierunkowo.
Z tym volatile w tym przypadku to pewne przegięcie, bo zarówno pola struktury (czemu nie sama struktura?), jak i zmienna o tym typie są volatile, co jest lekko bez sensu, acz nie jest błędem. Natomiast nie zgodzę się, że volatile nie powinno się definiować wewnątrz struktury. Jeśli dane pola wskazują np. na zasoby sprzętowe, albo w inny sposób ze swej...
Przerwanie ADC zbędne i szkodliwe, a w deklaracji k brak atrybutu volatile.
Na przyszłość proponuję podawać bardziej znaczace fragmenty programu. A wtym przypadku, domyślam się, że brakuje deklaracji jako volatile zmiennej współużywanej w przerwaniu. Jaki masz ustawiony poziom optymalizacji w kompilatorze?
nieulotna to volatile - czyli zmienna, która nie jest poddawana optymalizacji w odwołaniach do niej - i przydaje się głównie gdy są odwołania do tej zmiennej zarówno w przerwaniach i w programie głównym. Czyli jeśli z punktu widzenia programu głównego jest zmieniane niejawnie przez przerwanie. Wtedy volatile - ale nie dla wszystkich zmiennych globalnych...
Dla drive_state? Przecież nie modyfikuję go w przerwaniu. btn_state jest volatile.
ten kod który przesłałeś wygląda chyba OK. Ale mogą być inne przyczyny, np. jakieś niespodziewane RESETy po drodze, złe ustawienia USARTa, itp.
Oczywiscie, w takch przypadkach stosuje sie modyfikator volatile
http://www.elektroda.pl/rtvforum/topic35...
Nie potrzebujesz kolejnego licznika. Już masz jeden skonfigurowany do pracy cyklicznej i to w zasadzie już Ci mniej więcej wystarczy. Masz w tym momencie przerwanie co 1/18750sekundy czyli co jakieś 53,33(3)us. Jeśli chcesz zrobić opóźnienie w pętli głównej o na przykład 500ms to wystarczy, że poczekasz 500000/53,333=9375 takich przerwań. W tym celu...
a _delay_ms i _delay_us Ci nie wystarcza ? Do opóźnień nie trzeba wykorzystywać koniecznie przerwań timera. Można wykorzystać flagi timera (o ile się da, ale wszystko zależy). Poza tym, zmienna deb w Twoim programie zapewne nie jest volatile, ale wrzuciłeś nam NIC, także pomoc też nijaka
Poczytaj o zmiennych globalnych typu volatile. Zamykam
o volatile się zapomniało :P // no tak w przerwaniu :P a ruszasz coś układem? może źle jest cuś przylutowane ? Z taktowaniem może też coś nie tak? Może z zasilaniem? Może to wpływ wiatrów słonecznych ?
Kliknij tutaj: [url=http://avr-libc.nongnu.org/user-man...
Zarówno "temp" jak i "i" powinny być volatile.
IMO podłączenie powinno wyglądać tak: https://obrazki.elektroda.pl/8659379900_... ESP8266 ma GPIO w logice 3.3V (więc kolektor podłączony jest do +3.3V przez rezystor 200Ohm - 3kOhm ograniczający prąd), a zalecany prąd kolektora nie większy niż 27mA. Nie zapomnij o tym, aby licznik inkrementowany w przerwaniu miał modyfikator "volatile".
Jak zmienna używasz w przerwaniu i pętli głównej to musisz to zaznaczyć. "volatile int"
Chodzi o to, że zmienna volatile cały czas odczytywana jest z pamięci i ładowana do rejestru a zmienna bez volatile, ładowana jest tylko raz? Czy dobrze myślę? Dobrze myślisz. Ogólnie zmienna globalna volatile ma sens w sytuacji, gdy ze zmiennej korzystasz jednocześnie w programie głównym i w procedurze obsługi przerwania. W Twoim przypadku, gdy korzystasz...
Witam, Zmienna l (i wszystkie inne uaktualniane w przerwaniach) powinna być zadeklarowana jako volatile: volatile unsigned int l; Dzięki temu kompilator wie, że może ona zmienić wartość poza kontrolą kompilatora np. w przerwaniu. Takiej zmiennej kompilator np. nie usunie podczas optymalizacji Twojego programu :) PS. w PHP operatory wyglądają tak samo,...
Zacznij od volatile + przerwanie: http://mikrokontrolery.blogspot.com/2011...
Pomysł, żeby nadawać znak wtedy, gdy odbiornik jest gotowy i nie wiedząc, co jest w buforze nadawania, niekoniecznie musi być poprawny. Pomyśl, co będzie wysłane po odbiorze pierwszego znaku. Bufor odbioru ma u Ciebie raz 16, a raz 17 znaków. Cyz odebranodane ma atrybut volatile? Czy włączyłeś przerwanie UART? Takie inicjowanie UART działa poprawnie...
Wydaje mi się że po prostu użyj jakieś flagi i zmiennej globalnej która zapamięta wartość PORTC w momencie wejścia do przerwania. Aby rzeczywiste wartość ta była zachowane użyj zmiennej volatile char to znaczy wchodząc do przerwania funkcja będzie wykonywana na tej zmiennej a nie na jej kopii.
Nie musisz wywoływać ponownie, ponieważ w pętli sprawdzasz ten sam bufor pamięci, który jest wypełniany podczas przerwania. Ważne jest, aby bufor zadeklarowany był z modyfikatorem volatile, np. volatile uint8_t bufor[50];
no to ja mam znow pomysl na garsc poprawek [; w przerwaniu: 1. if (nr > 1) {nr = 0;} jak widze nr oznacza u ciebie jakby 'faze' danego bitu. zamiast wiec kombinowac z ta cala inkrementacja i sprawdzaniem, zrob po prostu XOR'a: nr^=1; tym sposobem bedzie ta zmienna rowna na zmiane 1 i 0. niemniej jednak zauwaz, ze twoja zmienna nr to jest ... ostatni...
Freddie, i to Ty zadajesz takie pytanie? Przecież to oczywiste, że wszystkie Twoje trzy zmienne _save_cośtam muszą być zadeklarowane jako volatile, bo są współużywane w przerwaniach. Inaczej kompilatorowi "brak kontekstu". Jeżeli taka deklaracja nie rozwiązuje problemu nieliczenia sumy kontrolnej (powinna), to trzeba szukać problemu tylko dla tego przypadku.
Mam jednak wciąż pytanie co do drugiej części, jeżeli zmienna jest volatile to dlaczego konieczne jest wyłączanie obsługi przerwań? Czy wynika to z tego, że to 4-bajtowy typ long i przerwanie może nastąpić w trakcie porównywania i zmienić wartość niesprawdzonych jeszcze bajtów? Dokładnie o to chodzi. Tu lepsze sa 32 bitowe procki, przy porównaniu long...
Nie wykonuje się bo kompilator pewnie usunął tę pętlę. Do zmiennej "i" dopisz jeszcze volatile.
magic word: volatile
Pamiętaj że sama transmisja też swoje trwa :) a poza tym nie pokazałeś funkcji printf (może ona bawi się w _delay_ms() ?) Zauważ również że przerwanie występuje niezależnie od transmisji, może dochodzić do takiej sytuacji ze raz przerwanie zmienić Ci wartość zmiennej tuż przed transmisją a raz tuż po niej i to spowoduje Twoje opóźnienia. Spróbuj blokować...
Zmienna "a" musi być "volatile".
Wpisać magiczne "volatile" volatile int sekunda=0;
1. Wszystkie zmienne modyfikowane w przerwaniu powinny być 'volatile'. 2. Po co wyłączać globalnie przerwania w procedurze obsługi przerwania? Poczytaj datasheet - one i tak są wyłączone. 3. Sugerowałbym nie żałować klawisza ENTER - kod, w którym w jednym wierszu jest kilka poleceń jest nieczytelny. 4. Rejestr UDR odczytujesz wielokrotnie w przerwaniu....
Chciałbym zmierzyć jak długo wykonuje się przerwanie od DMA po zakończeniu transmisji z I2S. Myślałem nad uruchomieniem jakiegoś timera, który będzie zliczał mikrosekundy, ale kiedy wykonuje się jedno przerwanie z najwyższym priorytetem to inne są hamowane. Dobrze kombinujesz! Ale trochę przekombinowujesz :). Nie potrzebujesz żadnych dodatkowych przerwań...
kli : Sprawdziłem na kompilatorze, który posiadam (avr-gcc 4.3.0) - kiedy zostanie wygenerowany taki kod, jaki wkleiłeś - na wszystkich poziomach optymalizacji oprócz -O0 jest generowany kod, który ja wkleiłem, tylko przy -O0 taki jak twój. Używanie "volatile" nie jest czymś opcjonalnym ("dzięki za uwagę, przyda się na przyszłość"), używając przerwań...
myślałem że mogę wpisać praktycznie częstotliwość taktowania procka. Po zastanowieniu wiem że to niemożliwe. Podzielnik przez 8 można włączyć. Dodano po 4 Nie każdy pływa z zamiarem udziału w olimpiadzie ;-) Jest coś takiego jak hobby, ciekawość... na różnym poziomie wiedzy. Tu użyj CubeMX. Prosto, szybko i przyjemnie. Dużo kursów jest na Forbocie,...
Przykład: https://godbolt.org/z/Rf93Wc Kod nie zadziała bo został zoptymalizowany. https://godbolt.org/z/p-EnvC Teraz kod zadziała, gdyż nie zostanie zoptymalizowany. Co do przykładu z timerami to tak, kod potrzebuje volatile aby nie zoptymalizować jednego odczytu z tego samego adresu w jednym scope. Jednak to nie jest powiedziane, że to musi przerwanie,...
No po prostu w RAMie, nie mowmy juz w jakim, to nas zreszta nie interesuje, jesli mamy mikrokontroler z pamiecia wewnetrzna avrki chyba maja, prawda?? :wink: Wlasnie tak zostanie to wykonane. Dane beda w rejestrze i tam bede sie "dodawac", natomiast w samej pamieci bedzie siedziec stara wersja. Dopiero po zakonczeniu kompilator prawdopodobnie zapisze...
twój program doskonale miga diodą zgodnie z zamierzeniem ale musisz poczekać nie sekundę a kilka minut bo z powodu niezerowania licznika count kolejne mrugnięcie zachodzi dopiero po przekręceniu inta :) (btw. w tej sytuacji volatile jest niepotrzebne)
#include <avr/io.h> #include <avr/interrupt.h> // funkcje sei(), cli() #include <stdlib.h> volatile int a=0; ISR(TIMER0_OVF_vect) { a+=1; } int main( void ) { //rejestry od timera 0 TCCR0 = _BV(CS02)|_BV(CS00);//pr... 1024 TIMSK = _BV(OCIE0); //włącza przerwanie...
A może masz gdzieś funkcję obsługi tego przerwania? Dodano po 4 Dodam, że korzystam z programowego bufora cyklicznego, który w przerwaniach odbiera dane od UDR. Jedyne co mi przychodzi na myśl to to, że przerwanie tak szybko się wykona (odebranie danych do bufora i skasowanie flagi RXC), że część programu: while ( !(UCSRA & (1<<RXC)) ); nawet...
Rozwiązanie drugie które napisałem, praktycznie w postaci aktualnej nadaje się do przerwań - dodać tylko jedną zmienną która będzie informować ile aktualnie odczytano bajtów i samą funkcję update_bit można wywoływać po razie w przerwaniu, jako trzeci argument podając odczytany bit. Równie dobrze można przekształcić rozwiązanie pierwsze wyciągając z...
uint8_t g_AktWyswietlacz = 0; uint8_t g_DaneWyswietlacza[4]; uint8_t g_DaneCom[4] = { (1<<COM1), (1<<COM2), (1<<COM3), (1<<COM4) }; Zadeklaruj te zmienne jako volatile.
Tu masz kod który korzysta z przerwań i co 1 sekundę ustawią zmienną s1_flag na 1. Musisz pamiętać, aby ją w funkcji głównej zerować, bo tak cały czas będzie ona usttawiona na 1. Ten kod jest tylko poglądowy, ma ci tylko przybliżyć co i jak z przerwaniami. [syntax=c]int main(void){ volatile uint8_t s1_flag, /********** KONFIGURACJA TIMERA2 do wygenerowania...
zapewnijmy atomowość względem czegokolwiek: Kod: __ASM volatile ("cpsid i"); //USART2->CR1&=(~USART_CR1_TXEIE); /* zablokuj przerwanie */ pt->dat++; //USART2->CR1|=USART_CR1_TXEIE; /* odblokuj przerwanie */ __ASM volatile ("cpsie i"); Od czegoś jest CMSIS _enable_interrupts(); itd. Powyższy kod nie gwarantuje pełnej atomowości.
Zmienną używaną w przerwaniu deklaruje się jako volatile (wykluczona z optymalizacji), inaczej będzie cyrk... volatile unsigned char licznik Ładniej by to wyglądało scalone... tzn... void czekaj(void) { licznik = 30; TCCR0 = 0x05; do{}while(licznik); } ISR(TIMER0_OVF_VECT) { licznik--; TCCR0 = 0; //wypadałoby...
Po pierwsze- funkcja obsługi przerwania powinna być poza main(). Po drugie zmienna licznik powinna być volatile. Reszta potem.
Bo nie tak się używa przerwań zewnętrznych. Można po pojawieniu się przerwania od zbocza narastającego wystartować timer, w przerwaniu zmienić na zbocze opadające i gdy pojawi się zbocze opadające zatrzymać timer, odczytać jego stan do zmiennej volatile wykasować i ponownie ustawić na zbocze narastające. Mozna też wykorzystać oba dostępne przerwania....
Czy zmienne które używasz w przerwaniu masz jako Volatile?
Czyli zmienne volatile tworzyć kiedy zmienna jest modyfikowana w przerwaniu i odczytywana w kodzie który nie wie kiedy wystąpi przerwanie jak loop . Owszem, ale sam specyfikator volatile w żaden sposób nie gwarantuje, że odczyt takiej zmiennej będzie atomowy tzn. może się zdarzyć, że przerwanie (modyfikujące wartość zmiennej) wystąpi w trakcie odczytu...
1. Zbędny atrybut volatile w deklaracji AdcVal. 2. Czy AWD jest jedynym źródłem przerwania ADC? 3. Kasować bit zgłoszenia przerwania należy na początku procedury obsługi przerwania. nie wiem, aj to jest W STM32, ale w wielu innych Cortexach Zgłoszenie przerwania nie zdąży się w takiej sytuacji skasować i powtórnie wejdziesz w obsługę przerwania.
Poczytaj o volatile
robisz w main: volatile int i=0; w stm32f4xx_it.h (czy jak tam się nazywa ten header z funkcjami przerwań): extern volatile int i;
Zmienne, które są dzielone między przerwaniami a resztą kodu muszą być deklarowane jako volatile. Zmienną "pozycja" zmieniasz zarówno w przerwaniu od INT0 jak i w innym miejscu w kodzie więc musisz użyć volatile.
A o volatile doczytałeś?
Czy zmienną counter (inkrementowaną prawdopodobnie w przerwaniu) masz zadeklarowaną jako volatile ? Jeśli nie, to kompilator najprawdopodobniej zoptymalizuje porównanie (counter<=nr) jako warunek zawsze spełniony lub zawsze nie spełniony do momentu zakończenia pętli, w której przecież żadna ze zmiennych porównywanych się nie zmienia.
Proponuje umieścić deklarację typu: volatile uint8_t DZIESIATKI, JEDNOSTKI; przed funkcją main. Tak zadeklarowana zmienna powinna być widoczna w przerwaniu oraz każdej innej funkcji.
Nie masz nawiasu masz średnik od razu, to jest bezsensu. Nie w tym problem - taki zapis jest poprawny; Skoro zmienna jest zmieniana w przerwaniu to obstawiam jak przedmówcy na brak atrybutu volatile.
Dobrze. Zmienna value_adc0 nie musi być volatile , chyba, że odwołujesz się do niej jednocześnie w programie głównym i w przerwaniu (przerwaniach).
Rozumie, że schematu nie musimy sprawdzać? W Twoim przypadku, wystarczy by tylko zmienna i była volatile, ponieważ jest używana zarówno w przerwaniu jak i poza nim. Ale to że pozostałe także zrobiłeś jako volatile, nie ma wpływu na niedziałanie programu. Zmienne liczenia PID używsz tylko w przerwaniu, to możesz zrobić z nich zmienne statyczne i deklarować...
Zawsze myślałem, że jak nie używam części analogowych to nie trzeba ich podłączać.. no ale mój błąd... No to właśnie wszedłeś w nową epokę :) A co do rezystorów na UDN to są one potrzebne? skoro sam UDN robi jako bufor podwyższający napięcie.. Nie pokazałeś na schemacie jakim napięciem zasilasz UDN, czyli de facto diody. Liczyłeś prądy LED? Jeszcze...
Oto kod: Nie wiem, czy to może być przyczyną, ale taka deklaracja oznacza "wskaźnik na ulotne dane", a potrzebny jest "ulotny wskaźnik" czyli [syntax=c] char * volatile wskaznik; [/syntax] Oczywiście volatile z przodu też może być niezależnie.
Efekt jest dokładnie taki jak kod - o to mogę się założyć. Twój kod ma po prostu błędy i tyle, więc czego oczekujesz? Poza faktem braku volatile "tu i tam", to zerowanie tej flagi w przerwaniu masz, ale gdzie masz jej ustawianie? Nigdzie. 4\/3!!
a SIG_OVER V LOW to przerwanie od czego niby jest? pozatym czas poznac slowko volatile temat o podobnym problemie - http://www.elektroda.pl/rtvforum/topic12... - czasem wypadaloby POSZUKAC troche na forum, a nie nowy temat od razu. pozatym - pytasz o AVRa, myslisz ze po co jest dzial o AVRach? 4\/3!!
O ile się nie wywali na aktualizowaniu zmiennych bez *volatile* ze środka przerwania, bo aż tak głeboko nie wnikałem Zmienna wymaga kwalifikatora volatile tylko wtedy, gdy jest używana zarówno w przerwaniu, jak i w programie głównym. No właśnie. A tutaj previous_millis jest aktualizowane z update(), więc w tym wypadku wewnątrz przerwania, oraz w attach()
Pierwsza sprawa jest taka, że zmienna odczytywana/zapisywana przez przerwanie i kod główny powinna być volatile. Druga zaś - 1ms delay w przerwaniu to nie jest szczególnie dobry pomysł... 4\/3!!
Mam jeszcze takie pytanie. Czy w tej funkcji callback powinienem używać zmiennych typu volatile?
Czy pamiętałeś o włączeniu portów w ODPOWIEDNIM rejestrze APBENR? volatile nie ma nic wspólnego z AVR. Tego atrybutu używa się np. wtedy, kiedy zmienna modyfikowana przez obsługę przerwania jest testowana przez inny fragment kodu. Pokaż kod procedury przerwania, bo coś tam narozrabiałeś.
jeżeli zmienna 'a' jest zadeklarowana jako globalna i jako volatile, to jest to ta sama zmienna zarowno dla main() jak i dla przerwania, więc w main() nie bedzie sie zerowac (no chyba ze wpiszesz ze a = 0 to oczywistym że sie wyzeruje)
(at)dodelow Przykład prostego generowania zmiany flagi co 4 sekundy (prosty sposób na przełączanie temperatura/czas z wcześnieszego kodu) przy założeniu przerwań timera co 4ms : deklaracje: [syntax=c] volatile uint16_t dzielnik; volatile bool sekundy_4; bool flaga_temperatura; [/syntax] kod w przerwaniu timera: [syntax=c]if (++dzielnik > 1000) {...
Raczej doczytał, bo wstawił przed deklaracjami zmiennych, a jeśli rozwiązaniem jest wstawienie volatile też wewnątrz struktury, to raczej nie jest to oczywiste bez doświadczenia z C.
Zacznijmy od tego, że problem wynikał stąd, że zmienna współdzielona przez przerwanie i wątek główny miała będą deklarację, bez atrybutu volatile. Jeśli przeniosłeś deklarację do procedury przerwania, atrybut volatile stał się zbędny. Po kilku wpisach na ten temat nawet nie zadałeś sobie trudu, by sprawdzić o co chodzi i wciąż błądzisz. Popatrz w startupxxx.s,...
O coś takiego mi chodziło. Teraz jest wywoływane przerwanie i procesor tylko je wykonuje ustawia flagę i ucieka do obsługi całego kodu. rxFlag i txFlag - musi być tylu volatile (int/char itp.) by była możliwość zmieniania ich wartości w przerwaniu. Masz tak ?? Sprawdzałeś w symulatorze jak program skacze po funkcjach ?? Zrób tak. skopiuj to wszystko...
volatile struct volatile przerwa static volatile
schematy radiomagnetofonów breve tufvassons spalić bezpiecznik kondensator
lampy elektronowe cezar quadro
Centrala Beninca Heady - Monitorowanie Stanu Bramy Pękające naczynka w dłoniach - diagnostyka i przyczyny