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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-10-12T19:31:25+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=13204&amp;mode</id>
<entry>
<author><name><![CDATA[drewpol]]></name></author>
<updated>2015-10-12T19:31:25+01:00</updated>
<published>2015-10-12T19:31:25+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13204&amp;p=142227#p142227</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13204&amp;p=142227#p142227"/>
<title type="html"><![CDATA[Timery programowe]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13204&amp;p=142227#p142227"><![CDATA[
Witam. Proszę o pomoc w rozwiązaniu problemu. Próbuję napisać program, który po krótkim naciśnięciu przycisku KEY będzie powodował ROL'owanie trzech kolejnych diod LED1, LED2 oraz LED3. Funkcja powodująca przewijanie wygląda tak:<br />[syntax=c]//funkcja przesuwająca bit - kolejne zapalanie następnej diody LED<br />void przesuwanie_lewo(volatile uint8_t *KPORT){<br /><br />uint8_t bajt = 1;<br /><br />//po krotkim nacisnieciu klawisza zmienna akcja1 przyjmuje wartosc 1 oraz sprawdzenie czy Timer2 ==0;<br />if(klawisz1.akcja1 &amp;&amp; !Timer2){<br />Timer2 = 50;<br />*KPORT = ~bajt;<br />bajt = (bajt&lt;&lt;1) | (bajt&gt;&gt;7);<br />if(bajt &gt; 8) bajt = 1;<br />}<br />}[/syntax]<br />gdzie zmienna akcja1 z obiektu struktury klawisz1 zmienia się cyklicznie z 0 na 1 po każdym naciśnięciu klawisza KEY:<br />[syntax=c]//funkcja zmieniająca stan zmiennej &quot;akcja&quot; na przeciwny<br />void wlacz_wylacz(uint8_t *akc){<br />*akc ^= 1;<br />}[/syntax]<br />I teraz pojawia się problem ponieważ po wciśnięciu klawisza KEY zapala się tylko pierwsza dioda LED1. Jeśli w pierwszym listingu usunąć Timer2 i zastosować delay_ms to uzyskuje zamierzony efekt lecz nie mogę już wyłączyć diod po kolejnym wciśnięciu.<br />Proszę o pomoc w rozwiązaniu tych dwóch problemów. Niżej wstawiam kod całego programu. <br />Z GÓRY DZIĘKUJĘ ZA POMOC!<br />[syntax=c]/*<br /> * main.c<br /><br /> *<br /> *  Created on: 11 paź 2015<br /> *      Author: damia<br /> */<br /><br />//F_CPU 8000000 MHz<br /><br />//dołączenie plików nagłówkowych<br />#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br /><br />#define LED1 (1&lt;&lt;PD0)<br />#define LED2 (1&lt;&lt;PD1)<br />#define LED3 (1&lt;&lt;PD2)<br />#define KEY (1&lt;&lt;PC0)<br /><br />//definicja struktury SKLAWISZ<br />typedef struct{<br />volatile uint8_t *KPIN;//zmienna do przechowywania PINx<br />uint8_t key_mask;//zmienna przechowująca maskę klawisza<br />uint8_t wait_time_s;//zmienna przechowująca czas oczekiwania<br />void (*kfun1)(uint8_t *akc);//wskaznik do funkcji<br />uint8_t klock;<br />uint8_t flag;<br />uint8_t akcja1;//zmienna pomocnicza do włączania i wyłączania diod - krotkie wcisnięcie<br />uint8_t akcja2;//zmienna pomocnicza do wlaczania i wylączania diod - dlugie przytrzymanie<br />}SKLAWISZ;<br /><br />//timery programowe<br />volatile uint8_t Timer1, Timer2, Timer3;<br /><br />//deklaracje funkcji<br />void przesuwanie_lewo(volatile uint8_t *KPORT);<br />void wlacz_wylacz(uint8_t *akc);<br />void wcisniecie(SKLAWISZ *kla);<br /><br />//utworzenie nowego klawisza<br />SKLAWISZ klawisz1;<br /><br /><br />int main(void){<br />//kierunek wyjsciowy pinów portu D oraz podciagniecie do VCC bo dioda podlaczona katoda do VCC<br />DDRD |= (LED1 | LED2 | LED3);<br />PORTD |= (LED1 | LED2 | LED3);<br />//kierunek wejściowy pinu PC0 portu C oraz podciagniecie do VCC<br />DDRC &amp;= KEY;<br />PORTC |= KEY;<br /><br />//******Inicjalizacja timera Timer0*********<br />TCCR0 |= (1&lt;&lt;WGM01) | (1&lt;&lt;WGM00);//tryb pracy CTC<br />TCCR0 |= (1&lt;&lt;CS01) | (1&lt;&lt;CS00);//preskaler 1024<br />OCR0 = 77;//podział przez 78 - podstawa 100 Hz<br />TIMSK |= (1&lt;&lt;OCIE0);//CompareMatch<br /><br />//przypisanie do zmiennych struktury poszczególnych danych<br />klawisz1.KPIN = &amp;PINC;<br />klawisz1.key_mask = KEY;<br />klawisz1.kfun1 = wlacz_wylacz;<br />klawisz1.wait_time_s = 3;<br /><br />sei();<br /><br />while(1){<br />wcisniecie(&amp;klawisz1);//sprawdzenie jak zostal wcisniety klawisz<br />przesuwanie_lewo(&amp;PORTD);//zapalanie kolejnych diod<br /><br /><br />}<br />}<br /><br />//funkcja zmieniająca stan zmiennej &quot;akcja&quot; na przeciwny<br />void wlacz_wylacz(uint8_t *akc){<br />*akc ^= 1;<br />}<br /><br />//funkcja przesuwająca bit - kolejne zapalanie następnej diody LED<br />void przesuwanie_lewo(volatile uint8_t *KPORT){<br /><br />uint8_t bajt = 1;<br /><br />//po krotkim nacisnieciu klawisza zmienna akcja1 przyjmuje wartosc 1 oraz sprawdzenie czy Timer2 ==0;<br />if(klawisz1.akcja1 &amp;&amp; !Timer2){<br />Timer2 = 50;<br />*KPORT = ~bajt;<br />bajt = (bajt&lt;&lt;1) | (bajt&gt;&gt;7);<br />if(bajt &gt; 8) bajt = 1;<br />}<br />}<br /><br />//funkcja sprawdzająca rodzaj wcisniecia klawisza<br />void wcisniecie(SKLAWISZ *kla){<br /><br />register uint8_t wcisniety = (*kla-&gt;KPIN &amp; kla-&gt;key_mask);<br /><br />if(!kla-&gt;klock &amp;&amp; !(wcisniety)){<br />kla-&gt;klock = 1;<br />if(kla-&gt;kfun1) kla-&gt;kfun1(&amp;kla-&gt;akcja1);//tutaj przekazana jest zmienna akcja1 po nacisnieciu klawisza w celu jej zmiany na przeciwny<br />//powoduje to kolejne zapalanie diod w funkcji &quot;przesuwanie_lewo&quot;<br />kla-&gt;flag = 1;<br />Timer1 = kla-&gt;wait_time_s * 100;<br /><br />}else if(kla-&gt;klock &amp;&amp; wcisniety){<br />(kla-&gt;klock)++;<br />if(!kla-&gt;klock){<br />kla-&gt;flag = 0;<br />Timer1 = 0;<br />}<br /><br />//tutaj przekazanie zmiennaj akcja do innego działania<br />}else if(kla-&gt;flag &amp;&amp; !(Timer1)){<br />if(kla-&gt;kfun1) kla-&gt;kfun1(&amp;kla-&gt;akcja2);<br />kla-&gt;flag = 0;<br />}<br /><br />}<br /><br />//Timery<br />ISR(TIMER0_COMP_vect){<br />uint8_t n;<br />n=Timer1;<br />if(n) Timer1 = --n;// 100Hz<br />n=Timer2;<br />if(n) Timer2 = --n;// 100Hz<br />}[/syntax]<br /><br /><strong><span style="color: #808000">------------------------ [ Dodano po: 57 minutach ]</span></strong><br /><br />Znalazłem już błąd. <br />1. Po pierwsze w funkcji :<br />[syntax=c]void przesuwanie_lewo(volatile uint8_t *KPORT);[/syntax]<br />trzeba utworzyć zmienną statyczną. Po każdym wejściu w funkcję kompilator na nowo definiował zmienną bajt wartością 1 zamiast zapamiętać ostatnią wartość. Rozwiązuje to dodanie słowa static:<br />[syntax=c]static uint8_t bajt = 1;[/syntax]<br />2. Timer był źle zainicjalizowany, ale nie miało to większego znaczenia w tym przypadku.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8379">drewpol</a> — 12 paź 2015, o 19:31</p><hr />
]]></content>
</entry>
</feed>