<?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=4&amp;t=22465&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2019-08-29T10:42:50+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=22465&amp;mode</id>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2019-08-29T10:42:50+01:00</updated>
<published>2019-08-29T10:42:50+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221694#p221694</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221694#p221694"/>
<title type="html"><![CDATA[Re: Chyba problem z Timerem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221694#p221694"><![CDATA[
Jeszcze jedna rzecz mi przyszła do głowy. Ze względu na to, że zmienna <em>wynik_ocr1</em> jest 16-bitowa, aby uniknąć problemów, należałoby dodatkowo zachować atomowość operacji, czyli przed przypisaniem jej wartości należałoby wyłączyć przerwania, przykładowo:[syntax=c]//<br />    uint16_t tmp;<br />    if (enkoder1 != 0) tmp = Dzielnik/enkoder1;<br />    cli();<br />    wynik_ocr1 = tmp;<br />    sei();[/syntax]<br />Tymczasowa zmienna <em>tmp</em> jest po to, żeby nie blokować przerwań na cały czas trwania operacji dzielenia, który może być dość długi.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 29 sie 2019, o 10:42</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2019-08-29T06:50:43+01:00</updated>
<published>2019-08-29T06:50:43+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221693#p221693</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221693#p221693"/>
<title type="html"><![CDATA[Re: Chyba problem z Timerem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221693#p221693"><![CDATA[
Z powodu burzy nie zdążyłem wczoraj dopisać.<br /><br />Obawiam się, że Twoje obliczenia wartości OCR1A nie są prawidłowe. Po pierwsze zakładasz rozdzielczość 1Hz, a po Twoich obliczeniach zmiana wartości zmiennej <em>enkoder1</em> o 1 spowoduje zmianę częstotliwości wyjściowej o ok. 0,5Hz. Po drugie częstotliwość będzie niedokładna (pomijając niedokładności wynikające z zaokrągleń przy dzieleniu). Szczególnie będzie to zauważalne przy wyższych częstotliwościach. Użyj lepiej wzoru na częstotliwość w trybie CTC podaną w dokumentacji przez producenta mikrokontrolera.<br /><br />Dodatkowo zwróć uwagę na to, że zmienna <em>enkoder1</em> jest mianownikiem w dzieleniu, więc jej wartość nie może wynieść <strong>zero</strong> (dzielenie przez zero jest niedopuszczalne), a w Twoim kodzie osiąga. Ewentualnie możesz zabezpieczyć operację dzielenia warunkiem:[syntax=c]if (enkoder1 != 0) wynik_ocr1 = Dzielnik/enkoder1;[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 29 sie 2019, o 06:50</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[SylwekK]]></name></author>
<updated>2019-08-29T06:36:48+01:00</updated>
<published>2019-08-29T06:36:48+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221692#p221692</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221692#p221692"/>
<title type="html"><![CDATA[Re: Chyba problem z Timerem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221692#p221692"><![CDATA[
@andrews dobrze prawi, posłuchaj go i ze zrozumieniem jeszcze raz przeczytaj co napisał. Dodam tylko, że ten &quot;błąd&quot; aktualizacji rejestru jest dobrym przykładem dla, niektórych początkujących programistów dlaczego timerów programowych ze zmiennym opóźnieniem nie robi się liczących w górę tylko w dół, a stosunkowo często się z tym spotykałem. Podczas zmian przy liczeniu w dół program nigdy nie przeskoczy porównania <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=1922">SylwekK</a> — 29 sie 2019, o 06:36</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2019-08-28T19:35:23+01:00</updated>
<published>2019-08-28T19:35:23+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221691#p221691</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221691#p221691"/>
<title type="html"><![CDATA[Re: Chyba problem z Timerem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221691#p221691"><![CDATA[
<div class="quotetitle">Rafal9018 napisał(a):</div><div class="quotecontent"><br />Wprowadziłem zmienna pomocniczą, ale niestety problem pozostał.<br />[syntax=c]void Obliczenia_ocr1a (void){<br />       <br />        wynik_ocr1 = Dzielnik/enkoder1;<br />        OCR1A = wynik_ocr1;<br />       <br />}[/syntax]<br /></div><br />Czy Ty w ogóle przeczytałeś to, co napisałem?<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />wynik obliczeń Dzielnik/enkoder1; wpisywać do jakiejś zmiennej pośredniczącej, <strong>a dopiero <span style="color: #8040FF">w procedurze obsługi przerwania od przepełnienia</span> kopiować go do rejestru OCR1A</strong><br /></div><br /><br /><div class="quotetitle">Rafal9018 napisał(a):</div><div class="quotecontent"><br />A w trybie FAST PWM chyba nie będzie można zmieniąć częstotliwości co 1 Hz.<br /></div><br />A w trybie CTC można? W obydwu trybach zależność częstotliwości od wartości rejestru OCR1A jest nieliniowa, więc nie da się tak łatwo uzyskać dokładnej rozdzielczości 1Hz (dokładność częstoliwości zależy od zakresu częstotliwości, jaki chcesz uzyskać). Poszukaj w dokumentacji mikrokontrolera, jak się oblicza częstotliwości wyjściowe w poszczególnych trybach.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 28 sie 2019, o 19:35</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Rafal9018]]></name></author>
<updated>2019-08-28T18:38:37+01:00</updated>
<published>2019-08-28T18:38:37+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221690#p221690</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221690#p221690"/>
<title type="html"><![CDATA[Re: Chyba problem z Timerem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221690#p221690"><![CDATA[
Wprowadziłem zmienna pomocniczą, ale niestety problem pozostał.<br /><br />[syntax=c]void Obliczenia_ocr1a (void){<br /><br />wynik_ocr1 = Dzielnik/enkoder1;<br />OCR1A = wynik_ocr1;<br /><br />}[/syntax]<br /><br />A w trybie FAST PWM chyba nie będzie można zmieniąć częstotliwości co 1 Hz. A to jest główne moje założenie  <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" /> <br />W takim razie jak powinna wyglądać płynna zmiana rejestru OCRx tak aby nie było zakłóceń pracy Timera ??<br /><br /><strong><span style="color: #808000">------------------------ [ Dodano po: 1 minucie ]</span></strong><br /><br />Jeszcze udostępnię kod:<br /><br />[syntax=c]#include &lt;stdio.h&gt;<br />#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &quot;lcd44780.h&quot;<br />#include &lt;avr/interrupt.h&gt;<br /><br /><br /><br /><br />volatile int8_t enkoder1 = 1;<br />volatile uint8_t timer1 =0;<br />volatile uint8_t licznik = 0;<br /><br />uint8_t czestotliwosc = 0;<br />uint16_t Dzielnik = 15625;<br />uint16_t wynik_ocr1 = 0;<br /><br />//float uint16_t max = 0;<br /><br /><br />void Obliczenia_ocr1a (void);<br /><br />int main(void){<br /><br /><br /><br />// Ustawienie przerwań zewnętrznych PCINT<br /><br />PCICR |= (1&lt;&lt;PCIE0);  // Zezwolenie na przerwanie PCINT na porcie PB<br />PCMSK0 |= (1&lt;&lt;PCINT0) ;  // ustawienie przerwań typu PCINT na porcie PB<br /><br /><br />//////////////////////////////////////////////////////////////////////    Ustawienie Pierwszego Timera 16 bitowego, TC1   <br /><br /><br />  TCCR1B |= (1 &lt;&lt; WGM12); // Tryb CTC<br />  TCCR1B |= (1 &lt;&lt; CS10) | (1&lt;&lt;CS12); // Preskaler 1024<br />  TIMSK1 |= (1 &lt;&lt; OCIE1A); // Enable timer compare interrupt<br />  OCR1A = 15625;   // Bit porównujący<br />  <br />///////////////////////////////////////////////////////////////////<br /><br /><br />///////////////////////////////////////////////////////////////////  Ustawienie wyjść<br />DDRD |= (1&lt;&lt;PD7);<br />DDRC |= (1&lt;&lt;PC4);<br />DDRB |= (1&lt;&lt;PB2);  // LED<br />//DDRC |= (1&lt;&lt;PC0);<br /><br />////////////////////////////////////////////////////////////////////  Podciągnienięcie pod VCC<br /><br />PORTB |= (1&lt;&lt;PB0) | (1&lt;&lt;PB1) | (1&lt;&lt;PB2) | (1&lt;&lt;PB3) | (1&lt;&lt;PB4) | (1&lt;&lt;PB5); <br />PORTD |= (1&lt;&lt;PD7);<br /><br /><br />/////////////////////////////////////////////////////////////////// Ekran startowy<br /><br />lcd_init();<br />lcd_str(&quot;Generator&quot;);<br /><br />sei();  // Głobalne zezwolenie na przerwania<br />    while (1) {<br /><br /><br /><br /><br />Obliczenia_ocr1a();<br /><br />lcd_locate(0,0);<br />lcd_str(&quot;Czestotliwosc&quot;);<br /><br /><br /><br /><br />lcd_locate(1,0);<br />lcd_int(wynik_ocr1);<br /><br />lcd_locate(1,8);<br />lcd_int(enkoder1);<br /><br />lcd_locate(1,13);<br />lcd_int(licznik);<br /><br /><br /><br /><br /><br /><br />}<br />}<br /><br />ISR(TIMER1_COMPA_vect) {   // Wktor przerwania Timer 1<br /><br />PORTB ^= (1&lt;&lt;PB2);<br /> licznik++;<br />}<br /><br />ISR (PCINT0_vect){// Przerwanie PCINT, obsluguje enkoder 1<br /><br />    if ((PINB &amp; (1&lt;&lt;PB0))){<br />        if  ((PINB &amp; (1&lt;&lt;PB1))) enkoder1++;<br /><br />        }<br />    if (!(PINB &amp; (1&lt;&lt;PB0))){<br />        if  (!(PINB &amp; (1&lt;&lt;PB1))) enkoder1++;<br /><br />        }<br />    if (!(PINB &amp; (1&lt;&lt;PB0))){<br />        if  ((PINB &amp; (1&lt;&lt;PB1))) enkoder1--;<br />if (enkoder1 == -1) enkoder1 =0;<br />        }<br />    if ((PINB &amp; (1&lt;&lt;PB0))){<br />        if  (!(PINB &amp; (1&lt;&lt;PB1))) enkoder1--;<br />if (enkoder1 == -1) enkoder1 =0;<br />        }<br /><br />}<br /><br />void Obliczenia_ocr1a (void){<br /><br />wynik_ocr1 = Dzielnik/enkoder1;<br />OCR1A = wynik_ocr1;<br /><br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3441">Rafal9018</a> — 28 sie 2019, o 18:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2019-08-06T07:39:24+01:00</updated>
<published>2019-08-06T07:39:24+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221012#p221012</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221012#p221012"/>
<title type="html"><![CDATA[Re: Chyba problem z Timerem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221012#p221012"><![CDATA[
Przedstawiłeś zbyt mało kodu. Istotne jest, w jakim momencie zmieniasz wartość OCR1A. Zapis do tego rejestru w trybie CTC jest natychmiastowy (nie ma podwójnego buforowania), więc jeśli wpisujesz do niego wartość mniejszą od aktualnej wartości TCNT1, to porównanie w tym cyklu zliczania zostanie pominięte. W efekcie tego licznik nie zostanie wyzerowany, tylko będzie musiał doliczyć do maksymalnej pojemności licznika i dopiero w następnym cyklu nastąpi porównanie (przy preskalerze 1024 to opóźnienie będzie szczególnie widoczne).<br /><br />Widzę, że masz włączone zezwolenie na przerwanie od porównania. Jeśli tak do tej pory nie miałeś, to najlepiej wynik obliczeń <strong><em>Dzielnik/enkoder1;</em></strong> wpisywać do jakiejś zmiennej pośredniczącej, a dopiero w procedurze obsługi przerwania od przepełnienia kopiować go do rejestru OCR1A. Nadal może być problem przy niskich wartościach OCR1A i preskalera, ale przy preskalerze 1024 powinno działać OK. Ewentualnie zamiast trybu CTC użyj innego trybu, gdzie zapis do rejestru jest OCR1A jest synchronizowany sprzętowo (podwójnie buforowany), np. trybu 15 (Fast PWM).<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 6 sie 2019, o 07:39</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Rafal9018]]></name></author>
<updated>2019-08-05T20:23:51+01:00</updated>
<published>2019-08-05T20:23:51+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221009#p221009</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221009#p221009"/>
<title type="html"><![CDATA[Chyba problem z Timerem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22465&amp;p=221009#p221009"><![CDATA[
Cześć,<br /><br />Mam mały problem Timerem sprzętowym. Coś robię źle, ale nie mam pomysłu co  <img src="https://forum.atnel.pl/images/smilies/icon_rolleyes.gif" alt=":roll:" title="Udaje, że to nie on" /> <br /><br />Mianowicie chcę zrobić generatorek, który generuję sygnał prostokątny z określoną częstotliwością. Częstotliwość jest zmieniana poprzez zmianę wartośći rejestru OCR1A. Procek to Atmega 328PB taktowana kwarcem 16 Mhz.<br /><br />[syntax=c]Ustawienia Timera<br /><br />  TCCR1B |= (1 &lt;&lt; WGM12); // Tryb CTC<br />  TCCR1B |= (1 &lt;&lt; CS10) | (1&lt;&lt;CS12); // Preskaler 1024<br />  TIMSK1 |= (1 &lt;&lt; OCIE1A); // Enable timer compare interrupt<br />  OCR1A = 15625;   // Bit porównujący[/syntax]<br /><br />Zmiana wartości rejestru jest realizowana poprzez podział Dzielnika który ma wartość 15 625. Wartość tą dzielę przez wartość zmiennej enkoder1, która wynosi kolejno 1,2,3 itd. w zależności jak kręcę enkoderem.<br /><br />[syntax=c]void Bit_poruwnujacy_obliczenia (void){<br /><br />OCR1A = Dzielnik/enkoder1;<br /><br />}[/syntax]<br /><br />Wszystko jest ok, założenia spełnione. Lecz zaobserwowałem dziwne zachowanie. Mianowicie podczas zmiany wartości zmiennej enkoder1, procek jakby na chwilę przystaje i po chwili realizuję generowanie sygnału. Na wyjściu mam podłączoną diodę więc jak zmieniam częstotliwość to miga szybciej albo wolniej, ale zdarzają się momenty, że na chwilę jakby procek się zatrzymał i dioda nie świeci.<br /><br />A może to przez to, że podczas dzielenia generuje się liczba po przecinku a jak mam typ int ?? Co myślicie ??<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3441">Rafal9018</a> — 5 sie 2019, o 20:23</p><hr />
]]></content>
</entry>
</feed>