<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=8&amp;t=7616&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2014-06-30T23:58:50+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=8&amp;t=7616&amp;mode</id>
<entry>
<author><name><![CDATA[sq8dsr]]></name></author>
<updated>2014-06-30T23:58:50+01:00</updated>
<published>2014-06-30T23:58:50+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86291#p86291</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86291#p86291"/>
<title type="html"><![CDATA[Re: częstościomierz na AVR]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86291#p86291"><![CDATA[
<div class="quotetitle">Zaba napisał(a):</div><div class="quotecontent"><br />A ja mam pytanie czy nie można by <br />zliczać impulsów w krótszym czasie<br />niż 1s np. 0,5s.<br /></div><br />A no pewnie, że można. Przy częstotliwościach dużych stosuje się jeszcze krótsze czasy próbkowania. np. 0,1s albo nawet 0,01s A następnie przesuwa się przecinek. Powoduje to oczywiście ucięcie najmłodszych pozycji.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1589">sq8dsr</a> — 30 cze 2014, o 23:58</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Zaba]]></name></author>
<updated>2014-06-30T20:01:01+01:00</updated>
<published>2014-06-30T20:01:01+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86226#p86226</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86226#p86226"/>
<title type="html"><![CDATA[Re: częstościomierz na AVR]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86226#p86226"><![CDATA[
A ja mam pytanie czy nie można by <br />zliczać impulsów w krótszym czasie<br />niż 1s np. 0,5s.<br /><br />Nie wiem czy dobrze myślę ale mniejszy błąd<br />podstawy czasu byłby przy krótszych odcinkach odmierzanego czasu<br />ale dochodzi błąd ilości zliczanych impulsów (+/- 2 impulsy)<br /><br />Można by to uzależnić od mierzonej częstotliwości <br />im większa tym krótsze odcinki np. 1/4 s przy 50MHz<br /><br />Tylko nie wiem czy czasami nie przekombinowałem <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1044">Zaba</a> — 30 cze 2014, o 20:01</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[sq8dsr]]></name></author>
<updated>2014-06-30T15:11:54+01:00</updated>
<published>2014-06-30T15:11:54+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86160#p86160</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86160#p86160"/>
<title type="html"><![CDATA[Re: częstościomierz na AVR]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86160#p86160"><![CDATA[
No, jest dużo lepiej:<br />Oto kod:<br /><br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 24-06-2014<br /> */<br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &quot;SPI/spi.h&quot;<br />#include &quot;common.h&quot;<br /><br />        volatile uint16_t licznik ;    //ilosc przepełnien T1<br />        uint8_t reszta ;               //to co zostalo w T1 przed przepelnieniem<br />        uint32_t czestotliwosc;<br />        volatile uint8_t sekunda_flaga;<br />        volatile uint8_t sreg;<br /><br />int main(void) {<br />    PORTB |= (1&lt;&lt;PB0);       //PB1  wejście podciagnięte do plusa<br />    _delay_ms(50);<br /><br />timer_init(); //właczenie timerów<br />InitSpi();//włączenie SPI do wyswietlacza LED<br />OCR1A = 18984;<br />sei();<br /><br />while(1) {<br /><br />if (TIFR &amp; (1&lt;&lt;OCF1A)){ //wykonuje się przy każdej sekundzie<br />TCCR0 &amp;= ~((1&lt;&lt; CS02) |(1&lt;&lt; CS01));   //wyłaczenie licznika T0<br />TCCR1B &amp;= ~(1 &lt;&lt; WGM12)|(1&lt;&lt;CS12);//wyłaczenie podstawy czasu<br /><br />reszta = TCNT0;// zapisanie tego co zostało w liczniku T0<br />czestotliwosc = licznik * 256UL; //mnozenie ilosci przepelnien T0 i jego maks zawartosci<br />czestotliwosc = (czestotliwosc + reszta); //obliczenie calkowitej ilosci zliczen<br />czestotliwosc &lt;&lt;= 4;<br />convert_new(czestotliwosc);  //zapis liczby do bufora wyswietlacza LED<br /><br />licznik=0;//zerowanie licznika przepełnień<br />TCNT0 = 0;//zerowanie licznika timera0<br />TCNT1 = 0;//zerowanie licznika timera1<br />TCCR0 |= (1&lt;&lt; CS02)|(1&lt;&lt; CS01); //ponowne właczenie licznika T1<br />TCCR1B |= (1 &lt;&lt; WGM12)|(1&lt;&lt;CS12); //ponowne włączenie podstawy czasu<br />TIFR |= (1&lt;&lt;OCF1A);  // kasujemy flagę<br />}<br /><br />if (TIFR &amp; (1&lt;&lt;OCF2)) {<br />disp();<br />TIFR |= (1&lt;&lt;OCF2);<br />}<br /><br />} // koniec WHILE<br />} // koniec MAIN<br /><br /><br />ISR(TIMER0_OVF_vect){<br />licznik++;<br />}[/syntax]<br /><br />Jak widać pozostało tylko jedno przerwanie.<br />Przy testowej częstotliwości 3,6864 MHz stabilność jest do pojedynczych herców. Czasem coś tam skoczy o kilka herców, ale układ z testowym generatorem i dzielnikiem jest na stykówie ma długie kable więc może jakieś sysfy się czasem naniosą.<br />W zasadzie podobna dokładność jest przy przebiegu 50 MHz (mimo, ze dzielnik jest LS).<br /><br />Występuje tylko drobny problem przy multipleksowaniu wyświetlacza, prawie niezauważalny, ale czasem tak jakby mignie jedna pozycja. Oczywiście wynika to, jak sądzę, z tego że jego obsługa nie jest w przerwaniu tylko przez flagę. I czasem się opóźni.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1589">sq8dsr</a> — 30 cze 2014, o 15:11</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[sq8dsr]]></name></author>
<updated>2014-06-30T12:05:56+01:00</updated>
<published>2014-06-30T12:05:56+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86155#p86155</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86155#p86155"/>
<title type="html"><![CDATA[Re: częstościomierz na AVR]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86155#p86155"><![CDATA[
No faktycznie nie przyszło mi do głowy, że prolog procedury INT może mi tu psuć sprawę. Chyba bardziej prolog niż epilog, bo w toku prób wsadzałem nawet resztę operacji do procedury przerwania, epilog wykonywał się już po zatrzymaniu licznika T1.<br />Zaraz spróbuję tak zrobić jak mówisz. Bez przerwania, tylko z samą flagą.<br /><br />Do liczenia impulsów używałem wejścia licznikowego T1, czyli timera1 16-bit. Ale może faktycznie lepiej zrobić liczenie impulsów na timerze0 (T0) a podstawę czasu na timerze1. Jako że timer1 jest 16 bitowy więc te przysłowiową sekundę można będzie dokładniej ustawić plus dobór odpowiedniej częstotliwości taktowania ze stabilnego źródła.<br />Zaraz spróbuję tak zrobić...<br /><br />Dzięki Mirku <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1589">sq8dsr</a> — 30 cze 2014, o 12:05</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2014-06-30T06:46:57+01:00</updated>
<published>2014-06-30T06:46:57+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86144#p86144</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86144#p86144"/>
<title type="html"><![CDATA[Re: częstościomierz na AVR]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86144#p86144"><![CDATA[
Twój podstawowy błąd to po prostu całkowicie złe podejście do tego wzorca sekundy <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" /> i w ogóle tego że próbujesz to robić na takich flagach .... przez co tracisz kupę czasu na PROLOG i EPILOG przerwań przecież<br /><br />gdzieś w którymś wątku na forum ale też na 100% w którymś z poradników wideo tłumaczę i pokazuję, że w książce ten mechanizm flagi, gdzie w przerwaniu INTx ustawiam zmienną<br /><br />flaga=1;<br /><br />opisałem po to aby każdy zrozumiał na tak prostym przykładzie o co chodzi z tymi flagami. Tam gdzie nie zależy na czasie można tak robić chociaż po co ? skoro mamy przecież FLAGI SPRZĘTOWE przerwań - więc nawet w takich przypadkach nie musimy tracić  pamięci RAM. Zajrzyj proszę do noty do rejestru FLAG dla INT1 <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> dla m32 jest to rejestr GIFR w którym masz 3 flagi dla 3 przerwań INT <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> i już bez żadnej procedury przerwania w pętli głównej mógłbyś się posługiwać tą flagą sprzętową zamiast zmienną flaga1<br /><br />[syntax=c]if( GIFR &amp; (1&lt;&lt;INTF1) ) {<br /><br />   // .... tu robisz sobie coś<br /><br />   GIFR |= (1&lt;&lt;INTF1);  // kasujemy flagę<br />}[/syntax]<br /><br />To już jest o wiele szybsze niż mechanizm z tym flaga=1; bo odpada ci obsługa przerwania, jego prolog i epiliog a to przecież ZJADA (powiedziałbym nawet, że) wpiernicza w takim wypadku MNÓSTWO cykli zegara - do tego jeszcze próba zliczania tego w pętli głównej ... a nie za pomocą sprzętową - to jak sam widzisz powody, nie malutkich, a ogromnych niedokładności.<br /><br />No ale też dziwię się że do celów zbudowania częstościomierza nie wykorzystasz np wejść licznikowych np T0 ? Przecież można wtedy zrobić podstawę czasu na jednym timerze a na timerze zerowym zliczać impulsy przez wejście T0 ... w necie można spotkać setki takich częstościomierzy opisanych - zobacz np:<br /><br /><!-- m --><a class="postlink" href="http://www.svet-el.si/english/index.php/projects/5-practical/44-avr185" >http://www.svet-el.si/english/index.php ... /44-avr185</a><!-- m --><br /><br />albo:<br /><br /><!-- m --><a class="postlink" href="http://eesite.bitbucket.org/html/electronics/fmtr/fmtr.html" >http://eesite.bitbucket.org/html/electr ... /fmtr.html</a><!-- m --><br /><br />ale jak się wpisze hasło &quot;avr frequency meter&quot; to wyskoczy ci mnóstwo linków do podobnych rozwiązań i można sobie podpatrzeć jakieś podejście<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 30 cze 2014, o 06:46</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[sq8dsr]]></name></author>
<updated>2014-06-30T02:32:44+01:00</updated>
<published>2014-06-30T02:32:44+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86138#p86138</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86138#p86138"/>
<title type="html"><![CDATA[częstościomierz na AVR]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7616&amp;p=86138#p86138"><![CDATA[
Witam<br /><br />Temat stary jak świat. Wiele rozwiązań... Wszystkie sprowadzają się do liczenia impulsów (zboczy) w jednostce czasu (dla niskich częstotliwości metoda jest odwrotna i polega na pomiarze czasu między zboczami, ale to inny temat). <br />Postanowiłem sobie zbudować częstościomierz, więc coś na szybko sobie &quot;skleiłem&quot;.<br />Zresztą posiłkowałem się dawnym projektem autorstwa kolegi Janeczqu. <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><br /><br /><a href="http://forum.atnel.pl/_obrazki/o/1589/6d2760c815449d60e394b0883c105e08.png"  class="postlink"><img src="http://forum.atnel.pl/_obrazki/o/thumb/1589/6d2760c815449d60e394b0883c105e08.png" alt="Obrazek" /></a><br /><br />Schemat oczywiście orientacyjny aby pokazać o co chodzi. Nie robię jeszcze docelowego projektu bo zatrzymałem się na głupim (dziwnym) problemie.<br /><br />oto kod:<br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 24-06-2014<br /> */<br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &quot;SPI/spi.h&quot;<br />#include &quot;common.h&quot;<br /><br /><br />        volatile uint16_t licznik ;                     //ilosc przepełnien T1<br />        uint16_t reszta ;                      //to co zostalo w T1 przed przepelnieniem<br />        uint32_t czestotliwosc;<br /> //     volatile uint16_t przepelnienie = 1214;<br />        volatile uint8_t sekunda_flaga;<br />        uint8_t sreg;<br /><br />int main(void) {<br /><br /><br />    PORTB |= (1&lt;&lt;PB1);                          //PB1  wejście podciagnięte do plusa<br />    _delay_ms(50);<br /><br />timer_init(); //właczenie timerów<br />InitSpi();//włączenie SPI do wyswietlacza LED<br />MCUCR |= (1&lt;&lt;ISC11)|(1&lt;&lt;ISC10);//właczenie przerwania INT1 od RTC (co 1 sek)<br />GICR |= (1&lt;&lt;INT1); //zezwolenie na INT1<br /><br /><br /><br /><br />sei();<br /><br /><br />while(1) {<br />if (sekunda_flaga){ //wykonuje się przy każdej sekundzie<br />reszta = TCNT1;// zapisanie tego co zostało w liczniku T1<br />czestotliwosc = licznik * 65536; //mnozenie ilosci przepelnien T1 i jego maks zawartosci<br />czestotliwosc = (czestotliwosc + reszta)*16; //obliczenie calkowitej ilosci zliczen<br />convert_new(czestotliwosc);  //zapis liczby do bufora wyswietlacza LED<br />sekunda_flaga = 0;<br />licznik=0;//zerowanie<br />TCNT1 = 0;//zerowanie<br /><br />TCCR1B |= (1&lt;&lt; CS12) |(1&lt;&lt; CS11); //ponowne właczenie licznika T1<br /><br />//SREG = sreg;<br />//sei();<br />}<br />if (disp_flag) disp();//wywołanie fukcji multipleksujacej LED<br /><br /><br />} // koniec WHILE<br />} // koniec MAIN<br /><br /><br />ISR(INT1_vect){<br />TCCR1B &amp;= ~((1&lt;&lt; CS12) |(1&lt;&lt; CS11));   //wyłaczenie licznika T1<br />//sreg = SREG;<br />//cli();<br /><br />sekunda_flaga=1;//ustawienie flagi<br />}<br /><br /><br /><br /><br />ISR(TIMER2_COMP_vect){<br /><br />disp_flag=1;//ustawienie flagi do multipleks.<br /><br />}<br /><br /><br />ISR(TIMER1_OVF_vect){<br /><br />        licznik++;//inkrementacja zmiennej licznik po przepełnieniu T1<br />}[/syntax]<br /><br />inicjalizacja timerów:<br />[syntax=c]void timer_init(void){<br /><br />TCCR2 |= (1&lt;&lt;WGM21);<br />TCCR2 |= (1&lt;&lt;CS22)|(1&lt;&lt;CS20);<br />OCR2 = 255;<br />TIMSK |= (1&lt;&lt;OCIE2);<br /><br />    //Timer1 jako licznik<br />    TCCR1B |= (1&lt;&lt; CS12) |(1&lt;&lt; CS11);  //zrodło zewnętrzne - zbocze opadające<br />    TIMSK |= (1&lt;&lt;TOIE1);                     // zezwolenie na przerwanie od przepełnienia<br /><br />}[/syntax]<br /><br />Jak widać nie ma tu nic dziwnego. Są ślady po moich próbach mieszania operacjami wyłączania przerwań (obecnie zarzucone bo nic nie zmieniało).<br />Problem polega na tym, że częstotliwość (czyli ilość impulsów zliczonych w ciągu sekundy) jest zaniżona.<br />Wzorzec sekundy aktualnie pobieram z przerwania generowanego przez RTC. <br />Próbowałem również wytworzyć wzorzec sekundy przy użyciu Timera0. Jednak błąd był jeszcze większy.<br /><br />Co prawda nie posiadam pewnego częstościomierza do porównania, jednak źródła testowych przebiegów na których pracuję  to scalone generatory TTL o różnych częstotliwościach. <br />Jako że stosuję licznik 74LS393 dokonujący podziału przez 16 ilość impulsów mnożę razy 16 w kodzie. Myślałem, że to jest źródłem błędu. Jednak nie. Podałem np. 3,6864MHz bez podziału na wejście T1 i błąd był taki sam. Przy tej częstotliwości jest to odchylenie o około 1 kHz w dół. Jak na mój rozum zdecydowanie za dużo jak na takie źródło, którego ideą jest dokładność.<br />Przy większych częstotliwościach błąd rośnie proporcjonalnie. Przy 50MHz jest już około 12-13 kHz. <br /><br />Jednocześnie wskazanie częstotliwości jest dość stabilne, czasem zmieni się o kilka - kilkanaście Hz, ale to już jest w granicy dokładności generatora, poza tym kwarc w RTC też może nieco się wahać. Gdyby źródłem błędy był RTC (wzorzec sekundy) to oznaczałoby to, że spieszy się około 1 sekundy na godzinę. A jego dokładność (doświadczalnie sprawdzone) to koło 1 s. na dobę.<br /><br />Zastanawiam się nad tym co może być przyczyną. Oczywiście może jutro uruchomię duży radziecki częstościomierz i porównam. Jednak powtarzalna odchyłka, proporcjonalna do częstotliwości sugeruje błąd w zliczaniu impulsów w moim układzie. Jednak nie przychodzi mi do głowy co można, w tak prostym przykładzie, zrobić inaczej...<br /><br />Przyszło mi już do głowy, że zbocza przebiegu TTL z generatora są za mało strome i jakiś ich ułamek się gubi na EDGE DETECTOR, który jest na wejsciu T1 w MCU. Zrobiłem więc test z układem 74HC14 (negator z wejściem Schmitta) przed a później po dzielniku. Zresztą tak jak sądziłem nic to nie zmieniło.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1589">sq8dsr</a> — 30 cze 2014, o 02:32</p><hr />
]]></content>
</entry>
</feed>