Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 28 mar 2024, o 23:12


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 
Autor Wiadomość
PostNapisane: 5 paź 2019, o 18:31 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Witam bardzo proszę o podpowiedz w temacie w jaki sposób mogę wygenerować zmianę (np wartości zmiennej) w odpowiedzi na na opadające zbocze impulsu z 1 na 0 na określony czas,
konkretnie 11,92 us .
Dla zobrazowania o co mi dokładniej chodzi - działanie podobne do przerzutnika monostabilnego .
Czyli tak zmienna np. flaga_clk=1 przychodzi zmiana stanu i flaga_clk=0 na czas 11,92 us.
Problem tylko jest taki że przerwanie INT0 i INT1 mam już zajęte a działam na procesorze ATMEGA 32.
Proszę o jakieś podpowiedzi.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2019, o 18:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

Jest jeszcze taki jeden mechanizm w procku który można wykorzystać do wygenerowania zewnętrznego przerwania. Zainteresuj się timerem1, pinem ICP1 i modułem Input Capture Unit tego timera. Co prawda mechanizm ten służy do innego celu ale kto zabroni użyć go do wywołania przerwania od zmiany stanu pinu...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2019, o 18:59 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Stosowałem takie przerwanie ale do określania czasu impulsów ISR(TIMER1_CAPT_vect), a podałbyś jaki przykład którym mógłbym się za wzorować?



Ostatnio edytowano 5 paź 2019, o 19:09 przez AKSELINEK, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2019, o 19:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

Skoro oba inty masz już zajęte to wspomniany mechanizm jest chyba jedynym dodatkowym źródłem umożliwiającym wywołanie przerwania w reakcji na zmianę stanu pinu dla tego procka. Możesz w obsłudze przerwania od ICP zmienić stan zmiennej oraz aktywować inny (bądź ten sam timer) na przerwanie od porównania, i jego porównanie ustawić na czas dokładnie taki jak potrzebujesz długość impulsu czyli te 11,92us, w przerwaniu od porównania z kolei zmienną wyzerować, wyzerować też i zatrzymać timer w przygotowaniu na wygenerowanie następnego impulsu.

------------------------ [ Dodano po: 24 minutach ]

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Wszystko powyższe pod warunkiem że uC jest pędzone odpowiednio szybkim zegarem by wyrobił w procedurach przerwania bo ~12us to dosyć krótki czas...

------------------------ [ Dodano po: 40 minutach ]

możesz też na żywca zrobić opóźnienie w przerwaniu od ICP, ~12us to krótki czas więc zapewne pozostałym procesom nie zaszkodzi.
Do opóźnienia będzie trzeba użyć albo _delay_loop albo wstawki asemblerowej i policzyć właściwe opóźnienie względem F_CPU.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2019, o 19:51 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Bardzo Ci dziękuję za podpowiedz , ale czy przed pętlą główną muszę oczywiście jeszcze ustawić

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


wyjaśnij mi jeszcze ten drugi sposób _delay_loop1() - co to dokładnie znaczy ? w nawiasie wpisać jakąś cyfrę ? czy tak rozumem że to jest sposób na bardzo krótkie opóżnienie czy tak?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2019, o 20:23 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

Przed pętlą główną musisz jeszcze wstępnie skonfigurować timer1 czyli ustawić go do pracy w porównanie, policzyć i ustawić wartość dla porównania, włączyć przerwanie od porównanie i wreszcie włączyć globalne przerwania.

_delay_loop1() jak również _delay_loop2() to dwie funkcje opóźniające z wbudowanej biblioteki delay_basic.h i są to ubrane w funkcje wstawki asemblerowe. Do pierwszej funkcji podaje się wartości od 0 - 255, do drugiej 0 - 65535. Opóźnienie jest zależne od F_CPU, i wynosi dla pierwszej funkcji (value+1)*3 takty zegara, gdzie value to wartość jaką przekazujemy do funkcji zgodnie z powyższymi zakresami. Wartość 0 to opóźnienie 3 taktów zegara. Dla drugiej krok opóźnienia wynosi 4 takty zegara zapewne ze względu na dwubajtowy argument funkcji.
W bluebooku Mirek użył tych funkcji np w soft_I2C.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2019, o 20:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Bardzo Ci dziękuję trochę mi rozjaśniłeś dzięki. W tygodniu wgram do procka i opowiem o wynikach.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 paź 2019, o 14:53 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Pozwolę sobie zwrócić uwagę na pewne kwestie.

Pomysł kolegi xentis na wykorzystanie pinu ICP jako substytutu pinu INT jest jak najbardziej słuszny. Niezależnie jednak od tego, który pin będzie wykorzystany, należy pamiętać o zwłoce pomiędzy zboczem narastającym na pinie, a momentem zmiany wartości zmiennej. Gdybyś korzystał tylko z tego jednego przerwania, ten czas byłby po pierwsze bardziej powtarzalny, po drugie zapewne pomijalny. Jako że jednak planujesz korzystać z innych przerwań, a zbocze na pinie może pojawić się np. w trakcie obsługi innego przerwania, czas reakcji może się zmieniać i być dość długi, w zależności od tego, ile będzie trwała obsługa innych przerwań. Jeśli to nie jest problemem, to OK.

Jeśli reakcją na zbocze ma być zmiana wartości zmiennej, a nie np. stanu na jakimś innym pinie, to niestety rozwiązanie z opóźnieniem typu "time-wasting" (delay) w przerwaniu raczej nie zda egzaminu, i to nie ze względu na czas. Taka zmiana wartości zmiennej przecież nie miałaby sensu, gdyby program w jakiś sposób na ten fakt nie zareagował. W takim przypadku:
xentis napisał(a):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
mikrokontroler nie będzie miał możliwości w jakikolwiek sposób zareagować na zmianę stanu zmiennej, chyba że zastosujemy zagnieżdżanie przerwań (czego raczej bym nie polecał początkującemu, tym bardziej w przypadku korzystania z delay). Ewentualnie reakcję na zmianę wartości zmiennej trzeba by też umieścić w procedurze obsługi przerwania, ale wtedy zastosowanie zmiennej flaga_clk raczej nie miałaby większego sensu.

Poniższy sposób jest może nieco bardziej skomplikowany, ale (imho) to zdecydowanie lepsze rozwiązanie, jeśli mikrokontroler ma mieć szansę "zauważyć" zmianę wartości zmiennej flaga_clk:
xentis napisał(a):
Możesz w obsłudze przerwania od ICP zmienić stan zmiennej oraz aktywować inny (bądź ten sam timer) na przerwanie od porównania, i jego porównanie ustawić na czas dokładnie taki jak potrzebujesz długość impulsu czyli te 11,92us, w przerwaniu od porównania z kolei zmienną wyzerować, wyzerować też i zatrzymać timer w przygotowaniu na wygenerowanie następnego impulsu


Ogólnie nie bardzo rozumiem całą koncepcję. 11,92us to dość krótki czas. Nawet przy zegarze 16MHz to tylko 190 taktów zegara. Aby zmiana wartości zmiennej nie pozostała niezauważona, musiałbyś zmienną flaga_clk testować co najmniej raz na 190 taktów, co może być trudne do osiągnięcia, szczególnie biorąc pod uwagę, że oprócz pętli głównej programu będziesz tam miał też obsługę innych przerwań. Flag używa się raczej w ten sposób, że w reakcji na zdarzenie (czyli np. na zbocze na jakimś pinie) taką flagę się ustawia, a zeruje dopiero po obsłużeniu takiej flagi.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 paź 2019, o 16:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

andrews napisał(a):
mikrokontroler nie będzie miał możliwości w jakikolwiek sposób zareagować na zmianę stanu zmiennej
Słuszna uwaga. trochę nie przemyślałem tego drugiego pomysłu - miałby sens gdyby było sterowanie pinem a nie ustawianie flagi.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 paź 2019, o 19:29 
Offline
Użytkownik

Dołączył(a): 29 paź 2017
Posty: 230
Pomógł: 26

AKSELINEK napisał(a):
Problem tylko jest taki że przerwanie INT0 i INT1 mam już zajęte a działam na procesorze ATMEGA 32.
Proszę o jakieś podpowiedzi.

Tak sobie popatrzyłem na dokumentacje ATMEGA32 i tam na nodze PB2 jest sygnał INT2 .
Może to uprości sprawę?

_________________
Jestem na GG 31324
Nowy soft, nowa nadzieja.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 paź 2019, o 19:39 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

JarekB napisał(a):
Tak sobie popatrzyłem na dokumentacje ATMEGA32 i tam na nodze PB2 jest sygnał INT2 .
Kolega to ma sokoli wzrok, też patrzyłem w notę i tego nie zauważyłem :lol:



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 paź 2019, o 20:44 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Bardzo dziękuję za zainteresowanie tematem. Chciałbym wspomnieć że nie upieram się na ustawianie zmiennej flaga_clk taka była jedynie moja myśl ale mogę również zmienić stan pinu mikrokontrolera.
Wprowadziłem w tym celu funkcję petla();
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Tworze pomału obsługę przerwania i mam taki zapis:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Kurcze wywala mi taki komunikat :(

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


a zwykły _delay wchodzi?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 paź 2019, o 22:02 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

aby funkcje _delay_loop działały jest potrzebny inklud biblioteki delay_basic.h tak jak pisałem wcześniej.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 paź 2019, o 00:27 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Wpisałem
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
i nie przyjmuje :(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 paź 2019, o 03:41 
Offline
Użytkownik

Dołączył(a): 14 sie 2016
Posty: 905
Pomógł: 39

A w katalogu util?

Wysłane ze srajfona

_________________
Moje porady są błędne,nie czytać,zbanować od razu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 paź 2019, o 06:27 
Offline
Użytkownik

Dołączył(a): 29 paź 2017
Posty: 230
Pomógł: 26

Może spróbuj tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Przy takich komunikatach jak opisałeś, czasem warto się rozejrzeć po komputerze.
Poszukałem katalogu util no bo skoro delay.h jest w katalogu to i pewnie delay_basic.h też tam siedzi.
No i siedział. :)
C:\Program Files\Atmel\AVR Tools\AVR Toolchain\avr\include\util


Autor postu otrzymał pochwałę

_________________
Jestem na GG 31324
Nowy soft, nowa nadzieja.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 paź 2019, o 20:15 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Wprowadziłem do przerwania funkcję _delay_loop1() ustawiłem na początek wartoś 100

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


funkcja petla() ma tylko pokazać czy zadziałała zmiana na pinie i wygląda tak:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


obserwuję opóżnienie na oscyloskopie i nie opóżnia nic :(
tzn. impuls widzę że się pojawia ale zmieniając wartość w funkcji _delay_loop1(100) nie ma reakcji?
Przed pętlą mam takie ustawienia:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Czy coś jeszcze mam ustawić?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 paź 2019, o 20:49 
Offline
Użytkownik

Dołączył(a): 29 paź 2017
Posty: 230
Pomógł: 26

Qurcze. Nie rozumiem tej pętli
A czemu nie tak na próbę?
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

W przerwaniu ustawiasz 1 czekasz pętle ustawiasz 0 masz impuls.

_________________
Jestem na GG 31324
Nowy soft, nowa nadzieja.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 paź 2019, o 21:33 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Zrobiłem Jarek jak kazałeś i:
Qurcze nie wiem dlaczego wywala mi taki komunikat? :(

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 paź 2019, o 01:58 
Offline
Użytkownik

Dołączył(a): 14 sie 2016
Posty: 905
Pomógł: 39

Przecież pisze jak byk, że znowu nie masz zainkludowanego pliku z "_delay_loop1", bo funkcja nazywa się "_delay_loop_1" a nie jak wpisałeś "_delay_loop1" - brakuje ci podkreślenia.
Czasami warto zajrzeć do pliku i samodzielnie rozwiązać problem, to tylko 3 sekundy szukania ;)


Autor postu otrzymał pochwałę

_________________
Moje porady są błędne,nie czytać,zbanować od razu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 paź 2019, o 07:47 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

QURCZE racja ale jestem zakręcony zrobiłem zwykłą literówe, muszę walnąć sobie RESETA :lol:



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 sty 2020, o 20:40 
Offline
Nowy

Dołączył(a): 04 gru 2018
Posty: 1
Pomógł: 0

witam
tak jak w opisie jestem początkującym a właściwie raczkującym w programowaniu i chciał bym zrozumieć przerwania i w tym celu próbowałem wykorzystać przerwanie INT0 i INT1 w Atmedze32 . W sumie próbowałem zrobić wszystko jak pan Mirek w poradniku ale nie mając Atmegi 328 wykorzystałem w zestawie uruchomieniowym Atmege 32 tylko nie wiem czemu program bez problemu obsługuje chyba przerwanie INT0 a INT1 już nie załączam kod programu jak by któryś z kolegów mógł mi powiedzieć cóż zrobiłem nie tak bo już nie wiem

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define LED1 (1<<PC6)
#define LED2 (1<<PC7)
#define SIGNAL1 (1<<PA2)
#define SIGNAL2 (1<<PA1)

#define LED1_ON PORTC |= (1<<PC6)
#define LED2_ON PORTC |= (1<<PC7)
#define LED1_TOG PORTC ^= (1<<PC7)
#define LED2_TOG PORTC ^= (1<<PC6)


int main(void){
DDRA |= SIGNAL1 |SIGNAL2;
DDRC |= LED1 |LED2;
PORTA |= SIGNAL1 |SIGNAL2;
PORTC |= LED1 |LED2;
GICR |= (1<<INT0);
GICR |= (1<<INT1);
MCUCR |= ISC00 |ISC10 |ISC11 |ISC01;

sei();
while(1){
PORTA ^= SIGNAL2 |SIGNAL1;
_delay_ms(1000);
}
}
ISR(INT0_vect){
LED1_TOG;
}

ISR(INT1_vect){
LED2_TOG;
}



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 sty 2020, o 22:33 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

Po pierwsze piny wyzwalające przerwanie masz podciągnięte do Vcc sprzętowo? Bo w programie nigdzie nie włączasz programowego podciągania... Wiszące piny bez podciągnięcia będą żyły własnym życiem przypadkowo wyzwalając przerwania.
Po drugie przy takiej konstrukcji programu możesz mieć problemy z jednoznacznym zaobserwowaniem efektów. Zauważ że wyzwalając przerwanie (zapewne przyciskiem lub zwierając przewody) nie zwracasz uwagi na fakt "drgania styków". Jako że w przerwaniu masz togle to w momencie gdy chcesz przełączyć diodę wyzwalając przerwanie, to tak na prawdę wyzwolisz je wielokrotnie, bo podczas wyzwalania pójdzie kilka impulsów na które procek zareaguje również kilkukrotnie, a stanie się to w bardzo krótkim czasie - w efekcie dla oka możesz zobaczyć albo faktyczną zmianę stanu bądź brak reakcji bo dioda wielokrotnie zmieni stan i zostanie akurat w stanie przed wyzwolenia.
Dla testu w przerwaniach zaraz po togle wstaw delaya 100 - 200ms. Oczywiście, w przerwaniu delayów unikamy ale dla testów nie zaszkodzi, a zobaczysz że zadziała.
W końcu po trzecie, na przyszłość nie bój się zakładać nowego własnego posta, zamiast dopisywać się z pytaniem pod czyimś i w dodatku nieco już zakurzonym ;) .



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 5 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO