ATNEL tech-forum
https://forum.atnel.pl/

Jak wygenerować krótki impuls
https://forum.atnel.pl/topic22603.html
Strona 1 z 1

Autor:  AKSELINEK [ 5 paź 2019, o 18:31 ]
Tytuł:  Jak wygenerować krótki impuls

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.

Autor:  xentis [ 5 paź 2019, o 18:55 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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...

Autor:  AKSELINEK [ 5 paź 2019, o 18:59 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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ć?

Autor:  xentis [ 5 paź 2019, o 19:05 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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.

Autor:  AKSELINEK [ 5 paź 2019, o 19:51 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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?

Autor:  xentis [ 5 paź 2019, o 20:23 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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:  AKSELINEK [ 5 paź 2019, o 20:56 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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

Autor:  andrews [ 6 paź 2019, o 14:53 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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.

Autor:  xentis [ 6 paź 2019, o 16:28 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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.

Autor:  JarekB [ 6 paź 2019, o 19:29 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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ę?

Autor:  xentis [ 6 paź 2019, o 19:39 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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:

Autor:  AKSELINEK [ 6 paź 2019, o 20:44 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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?

Autor:  xentis [ 6 paź 2019, o 22:02 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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

Autor:  AKSELINEK [ 7 paź 2019, o 00:27 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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 :(

Autor:  Harry [ 7 paź 2019, o 03:41 ]
Tytuł:  Re: Jak wygenerować krótki impuls

A w katalogu util?

Wysłane ze srajfona

Autor:  JarekB [ 7 paź 2019, o 06:27 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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:  AKSELINEK [ 7 paź 2019, o 20:15 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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ć?

Autor:  JarekB [ 7 paź 2019, o 20:49 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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.

Autor:  AKSELINEK [ 7 paź 2019, o 21:33 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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.

Autor:  Harry [ 8 paź 2019, o 01:58 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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:  AKSELINEK [ 8 paź 2019, o 07:47 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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

Autor:  kris1975 [ 28 sty 2020, o 20:40 ]
Tytuł:  problem z przerwaniem INT0 I INT1 Atmega32

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;
}

Autor:  xentis [ 28 sty 2020, o 22:33 ]
Tytuł:  Re: Jak wygenerować krótki impuls

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 ;) .

Strona 1 z 1 Strefa czasowa: UTC + 1
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/