-
1. Data: 2011-02-09 12:54:01
Temat: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Robbo" <y...@m...com>
Witam,
Jakiś czas temu pytałem o sprawy związane z pomiarem częstotliwości
sinusoidy o częstotliwości od 2 do 150Hz oraz zmiennej amplitudzie (od kilku
V do 400V). Mam już układ elektroniczny przekształcający sinusoidę na
prostokąt (brana jest pod uwagę tylko dodatnia połówka, a ujemna jest
usuwana). Jest tu kilka rezystorów, mostek, tranzystor, dioda oraz
transformatorek. (Może działanie tego układu da się jeszcze ulepszyć, ale to
w sumie nie jest teraz tematem). Uzyskany z dodatniej połówki sinusoidy
prostokąt jest podawany na nóżkę PE7(INT7) mikrokontrolera ATmega128 (kwarc
16MHz). Dokładność pomiaru, którą chciałbym osiągnąć to 0,2Hz przy
częstotliwości 50Hz. Chciałem Was prosić o sprawdzenie mojego kodu, którego
zadaniem jest nieustanne mierzenie czasu trwania dodatniej połówki, a
następnie wypisywanie tej wartości na wyświetlacz. Kod, który napisałem
wygląda na działający, ale może ma jakiś ukryty błąd.
volatile unsigned long int timer = 100000;
volatile short actualTime;
./* procedura wywoływana 100000 razy na sekundę */
SIGNAL (SIG_OUTPUT_COMPARE2)
{
cli();
if (timer < 100000)
timer++;
sei();
}
/* wyzwalane zboczem narastającym i opadającym */
SIGNAL (SIG_INTERRUPT7)
{
cli();
if (PINE & PINE7) {
timer = 0;
TCCR2 = 0; // stop timera
TCNT2 = 0; // zerowanie licznika
TCCR2 = _BV(WGM21) | // start timera
_BV(C21); // (prescaler 8)
} else {
actualTime = timer;
}
sei();
}
int main(void)
{
char s[16];
initLCD();
cli();
EICRB |= _BV(ISC70);
EIMSK |= _BV(INT7);
TCCR2 = 0;
OCR2 = 19;
TIFR |= _BV(OCF2);
TIMSK |= _BV(OCIE2);
while (ASSR & _BV(OCR2UB))
;
sei();
while (1) {
if (timer == 100000)
LCDshowString("---");
else {
sprintf(s, "%d ", actualTime);
LCDshowString(s);
}
}
return 0;
}
***
Jak to się sprawuje:
Jako źródło sygnału podłączyłem po prostu zasilanie sieciowe 230V/50Hz.
Wczoraj wieczorem przed godziną 22 liczba na wyświetlaczu wynosiła 996
(ostatnia cyfra niekiedy migała na "5"). Potem zaczęło to rosnąć... 997/8. O
godzinie 22 było jakieś 999. Potem zaczęło spadać do 996. Teraz (godzina
13:40) mam 996/7.
***
W szczególności chciałem zapytać o to, czy poprawnie zastosowałem cli() i
sei() w procedurach obsługi przerwań. Ponadto chciałem zapytać, czy kod
wewnątrz while(1) jest poprawny i czy nie lepiej byłoby zapisać to tak:
while (1) {
unsigned long int timerLatch;
short actualTimeLatch;
cli();
timerLatch = timer;
actualTimeLatch = actualTime;
sei();
if (timerLatch == 100000)
LCDshowString("---");
else {
sprintf(s, "%d ", actualTimeLatch);
LCDshowString(s);
}
}
Chodzi o sytuację, w której w pętli głównej jest przetwarzana wartość
zmiennej timer albo actualTime (np. został odczytany pierwszy bajt) i w
trakcie nastąpi przerwanie, zmieni wartość zmiennej, obsługa przerwania się
skończy, zostanie dokończone przetwarzanie zmiennej timer albo actualTime --
wartość chyba będzie błędna (jeden bajt z poprzedniej wartości, reszta
bajtów po aktualizacji w przerwaniu).
Z góry dziękuję za rady.
Robbo
-
2. Data: 2011-02-09 13:02:15
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: RoMan Mandziejewicz <r...@p...pl>
Hello Robbo,
Wednesday, February 9, 2011, 1:54:01 PM, you wrote:
> Jakiś czas temu pytałem o sprawy związane z pomiarem częstotliwości
> sinusoidy o częstotliwości od 2 do 150Hz oraz zmiennej amplitudzie (od kilku
> V do 400V). Mam już układ elektroniczny przekształcający sinusoidę na
> prostokąt (brana jest pod uwagę tylko dodatnia połówka, a ujemna jest
> usuwana). Jest tu kilka rezystorów, mostek, tranzystor, dioda oraz
> transformatorek. (Może działanie tego układu da się jeszcze ulepszyć, ale to
> w sumie nie jest teraz tematem). Uzyskany z dodatniej połówki sinusoidy
> prostokąt jest podawany na nóżkę PE7(INT7) mikrokontrolera ATmega128 (kwarc
> 16MHz). Dokładność pomiaru, którą chciałbym osiągnąć to 0,2Hz przy
> częstotliwości 50Hz. Chciałem Was prosić o sprawdzenie mojego kodu, którego
> zadaniem jest nieustanne mierzenie czasu trwania dodatniej połówki, a
Ja bym liczył czas pomiedzy dwoma narastającymi zboczami. Ale ja
herbatę cukrem...
[...]
--
Best regards,
RoMan mailto:r...@p...pl
Nowa strona: http://www.elektronika.squadack.com (w budowie!)
-
3. Data: 2011-02-09 14:39:10
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: Michoo <m...@v...pl>
W dniu 09.02.2011 13:54, Robbo pisze:
> W szczególności chciałem zapytać o to, czy poprawnie zastosowałem cli()
> i sei() w procedurach obsługi przerwań.
Nie.
Jeżeli nie deklarujesz przerwań explicite jako nieblokujących to one
dbają o wyłączność za Ciebie. Pisząc sei na końcu przerwania umożliwiasz
odpalenie przerwania po 2 cyklach a prawdopodobnie wyjście z przerwania
trwa chwilę dłużej - przy dużym nagromadzeniu przerwań do obsługi
skończy się to przepełnieniem stosu.
--
Pozdrawiam
Michoo
-
4. Data: 2011-02-09 14:56:27
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Marcin Wasilewski" <j...@a...pl>
Użytkownik "Robbo" <y...@m...com> napisał w wiadomości
news:4d528e6b$0$2436$65785112@news.neostrada.pl...
> W szczególności chciałem zapytać o to, czy poprawnie zastosowałem cli() i
> sei() w procedurach obsługi przerwań.
Widzisz, tak to jest jak się nigdy żadnego kodu w assemblerze na AVR-a nie
napisało.
Otóż procesor AVR wchodząc w obsługę przerwania sam wyłącza przerwania. Więc
stan jest taki, że do czasu zakończenia obsługi aktualnego przerwania,
obsługa kolejnych przerwań jest wyłączona.
Więc cli() po wejściu w obsługę przerwania nie ma sensu (bo przerwania już
są wyłączone), natomiast sei() dajesz wtedy jak chcesz włączyć ręcznie
obsługę przerwań, co oczywiście jest możliwe, tylko na stos trzeba uważać
(jeśli tych przerwań jest dużo w jednostce czasu).
sei() na końcu też nie ma sensu, ponieważ procedury obsługi przerwania nie
opuszcza się poprzez ret, tylko poprzez reti, będące niczym innym jak
połączeniem: ret + sei.
-
5. Data: 2011-02-09 15:10:31
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: Cezar <c...@B...pl>
On 09/02/2011 13:02, RoMan Mandziejewicz wrote:
> Hello Robbo,
>
> Wednesday, February 9, 2011, 1:54:01 PM, you wrote:
>
>> Jakiś czas temu pytałem o sprawy związane z pomiarem częstotliwości
>> sinusoidy o częstotliwości od 2 do 150Hz oraz zmiennej amplitudzie (od kilku
>> V do 400V). Mam już układ elektroniczny przekształcający sinusoidę na
>> prostokąt (brana jest pod uwagę tylko dodatnia połówka, a ujemna jest
>> usuwana). Jest tu kilka rezystorów, mostek, tranzystor, dioda oraz
>> transformatorek. (Może działanie tego układu da się jeszcze ulepszyć, ale to
>> w sumie nie jest teraz tematem). Uzyskany z dodatniej połówki sinusoidy
>> prostokąt jest podawany na nóżkę PE7(INT7) mikrokontrolera ATmega128 (kwarc
>> 16MHz). Dokładność pomiaru, którą chciałbym osiągnąć to 0,2Hz przy
>> częstotliwości 50Hz. Chciałem Was prosić o sprawdzenie mojego kodu, którego
>> zadaniem jest nieustanne mierzenie czasu trwania dodatniej połówki, a
>
> Ja bym liczył czas pomiedzy dwoma narastającymi zboczami. Ale ja
> herbatę cukrem...
truskawki :P
... no chyba ze znamy inne dowcipy
c.
-
6. Data: 2011-02-09 15:46:12
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: RoMan Mandziejewicz <r...@p...pl>
Hello Cezar,
Wednesday, February 9, 2011, 4:10:31 PM, you wrote:
[...]
>>> zadaniem jest nieustanne mierzenie czasu trwania dodatniej połówki, a
>> Ja bym liczył czas pomiedzy dwoma narastającymi zboczami. Ale ja
>> herbatę cukrem...
> truskawki :P
Truskawki to ja ze śmietaną, najlepiej bitą.
> ... no chyba ze znamy inne dowcipy
To nie dowcip.
--
Best regards,
RoMan mailto:r...@p...pl
Nowa strona: http://www.elektronika.squadack.com (w budowie!)
-
7. Data: 2011-02-09 17:50:42
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "4CX250" <t...@p...onet.pl>
Nie bawiłem się jeszcze przerwaniami w atmedze i muszę zaraz sprawdzić
w nocie jak jest ale zapytam wybiegiem a czy aby nie ma przypadkiem
zatrzasku przerwań przychodzących podczas obsługi przerwań i
priorytetów przerwań?
Marek
-
8. Data: 2011-02-09 17:58:35
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "4CX250" <t...@p...onet.pl>
Użytkownik "Robbo" <y...@m...com> napisał w wiadomości
news:4d528e6b$0$2436$65785112@news.neostrada.pl...
A może wykorzystac dwa liczniki.
Jeden zliczający uformowane impulsy a drugi z autoresetem wyzwalający
przerwanie co określony czas. W przerwaniu sprawdzałbym stan licznika
zliczającego, następnie kasował go i opuszczał przerwanie.
Marek
-
9. Data: 2011-02-09 18:00:53
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "4CX250" <t...@p...onet.pl>
Użytkownik "RoMan Mandziejewicz" <r...@p...pl> napisał w
wiadomości news:514110838.20110209164612@pik-net.pl...
> Hello Cezar,
>
> Wednesday, February 9, 2011, 4:10:31 PM, you wrote:
>
> [...]
>
>>>> zadaniem jest nieustanne mierzenie czasu trwania dodatniej
>>>> połówki, a
>>> Ja bym liczył czas pomiedzy dwoma narastającymi zboczami. Ale ja
>>> herbatę cukrem...
>> truskawki :P
>
> Truskawki to ja ze śmietaną, najlepiej bitą.
>
>> ... no chyba ze znamy inne dowcipy
>
> To nie dowcip.
Pan policjant widzę chyba po służbie bo też pozwala sobie na NTG.
Wiem wiem. Jedzie pan na sygnale jako pojazd uprzywilejowany.
Marek
-
10. Data: 2011-02-09 18:40:14
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: Grzegorz Kurczyk <g...@c...slupsk.pl>
W dniu 09.02.2011 13:54, Robbo pisze:
> Witam,
>
> Jakiś czas temu pytałem o sprawy związane z pomiarem częstotliwości
> sinusoidy o częstotliwości od 2 do 150Hz oraz zmiennej amplitudzie (od
> kilku V do 400V). Mam już układ elektroniczny przekształcający sinusoidę
> na prostokąt (brana jest pod uwagę tylko dodatnia połówka, a ujemna jest
> usuwana). Jest tu kilka rezystorów, mostek, tranzystor, dioda oraz
> transformatorek. (Może działanie tego układu da się jeszcze ulepszyć,
> ale to w sumie nie jest teraz tematem). Uzyskany z dodatniej połówki
> sinusoidy prostokąt jest podawany na nóżkę PE7(INT7) mikrokontrolera
> ATmega128 (kwarc 16MHz). Dokładność pomiaru, którą chciałbym osiągnąć to
> 0,2Hz przy częstotliwości 50Hz. Chciałem Was prosić o sprawdzenie mojego
> kodu, którego zadaniem jest nieustanne mierzenie czasu trwania dodatniej
> połówki, a następnie wypisywanie tej wartości na wyświetlacz. Kod, który
> napisałem wygląda na działający, ale może ma jakiś ukryty błąd.
>
Witam
Na wstępie to się zapytam, na czym Koledze tak naprawdę zależy ? Na
pomiarze czasu (okresu) czy częstotliwości ? Bo pisze Kolega o
"dokładności 0,2Hz" i o "wyświetlaniu czasu trwania dodatniej połówki".
Ponieważ zakres częstotliwości jest stosunkowo niewielki, można to
zrobić na dwa sposoby i kilka wariacji ;-).
1. Pomiar ilości impulsów w stałym przedziale czasu. Przy wymaganej
rozdzielczości 0,2Hz pomiar musiałby trwać co najmniej 5 sekund. Metod
realizacji jest wiele. Przy tak małej częstotliwości zbocze sygnału
mierzonego można sobie wykrywać programowo w pętli (pod warunkiem, że w
systemie nie istnieją przerwania, których obsługa zajmuje ponad 6ms).
Jako bramkę czasu najprościej wykorzystać któryś z timerów. Bardziej
elegancko liczyć zbocza w obsłudze zewnętrznego przerwania. Można
zliczać impulsy sprzętowo za pomocą licznika 16-bitowego, a 8-bitowym
realizować bramkę czasu. Można również całkowicie sprzętowo z
wykorzystaniem rejestru ICR licznika 16-bitowego i licznika 8-bitowego
generującego na wyjściu OCx impulsy o czasie bramkowania.
2. Pomiar czasu między impulsami (okresu). Tu aż się prosi wykorzystać
Input Capture Register.
Pozdrawiam
Grzegorz