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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2014-01-30T12:47:35+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=5738&amp;mode</id>
<entry>
<author><name><![CDATA[Kvite]]></name></author>
<updated>2014-01-30T12:47:35+01:00</updated>
<published>2014-01-30T12:47:35+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=5738&amp;p=67409#p67409</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=5738&amp;p=67409#p67409"/>
<title type="html"><![CDATA[Re: Problem z generowaniem PWM]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=5738&amp;p=67409#p67409"><![CDATA[
Problem okazał się banalny, nie wiem jak to się stało, że tego nie widziałem :/ PORTC&amp;=~PC6; a powinno być PORTC&amp;=~(1&lt;&lt;PC6); itd.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=257">Kvite</a> — 30 sty 2014, o 12:47</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Kvite]]></name></author>
<updated>2014-01-29T23:31:43+01:00</updated>
<published>2014-01-29T23:31:43+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=5738&amp;p=67364#p67364</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=5738&amp;p=67364#p67364"/>
<title type="html"><![CDATA[Problem z generowaniem PWM]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=5738&amp;p=67364#p67364"><![CDATA[
Witam, chciałbym generować pwm dla serwomechanizmów modelarskich na pinach PD3 i PD4. To samo przerwanie (tak sobie pomyślałem) chciałbym wykorzystać do generowania PWM dla silników DC PC6 i PC1. Sterowanie kierunkiem silników PC5 i PC4 dla jednego oraz PC3 i PC2 dla drugiego. <br /><br />Sprzęt: Atmega32, kwarc: 16 Mhz.<br /><br />Teraz po kolei. Utworzyłem sobie &quot;unio-strukturę&quot; wg przepisu Mirka, która będzie mi przetrzymywała dane odpierane z UART. Dane są ładnie aktualizowane wysyłam z terminala i wyświetlam na lcd to działa.<br /><br />[syntax=c]typedef struct {<br />volatile uint8_t pwm_l;<br />volatile uint8_t pwm_p;<br />uint8_t mot_l;<br />uint8_t mot_p;<br />uint8_t buzz;<br />volatile uint8_t cam_pion;<br />volatile uint8_t cam_poz;<br />} T_STRUCT_RECIVE;<br /><br />typedef union {<br />uint8_t idx_recive&#91;10&#93;;<br />T_STRUCT_RECIVE frame_recive;<br />} T_UNION_RECIVE;[/syntax]<br /><br />W pętli głównej poczyniłem dwa switche do aktualizacji kierunku [syntax=c]// ###########dekodowanie i sterowanie kierunkami silników #############<br /><br />enum E_direction {stop = 0x00, straight = 0x0F, back = 0xF0}; // oczywiście to nie jest w pętli głównej tylko zamieściłem, żeby było wiadomo skąd przełączniki<br /><br />switch (union_recive.frame_recive.mot_p) {<br /><br />case (stop):  // stop<br />PORTC&amp;=~(1&lt;&lt;PC4);<br />PORTC&amp;=~(1&lt;&lt;PC5);<br />break;<br /><br />case (straight): // do przodu<br />PORTC|=(1&lt;&lt;PC4);<br />PORTC&amp;=~(1&lt;&lt;PC5);<br />break;<br /><br />case (back): // do tyłu<br />PORTC&amp;=~(1&lt;&lt;PC4);<br />PORTC|=(1&lt;&lt;PC5);<br />break;<br />}<br /><br />switch (union_recive.frame_recive.mot_l) {<br /><br />case (stop): // stop<br />PORTC&amp;=~(1&lt;&lt;PC3);<br />PORTC&amp;=~(1&lt;&lt;PC2);<br />break;<br /><br />case (straight): // do przodu<br />PORTC|=(1&lt;&lt;PC3);<br />PORTC&amp;=~(1&lt;&lt;PC2);<br />break;<br /><br />case (back): // do tyłu<br /><br />PORTC&amp;=~(1&lt;&lt;PC3);<br />PORTC|=(1&lt;&lt;PC2);<br />break;<br />}<br /><br />//###################################################################################[/syntax]<br /><br />po czym policzyłem sobie jak zrobić PROGRAMOWY PWM dla serw i ten sam dla silników<br />Dla serw wartość będzie miała możliwość zmieniać się w zakresie 12-26 (union_recive.frame_recive.cam_pion)<br />Natomiast dla silników 0-256 (union_recive.frame_recive.pwm_p)<br /><br />Serwa czyli 50 Hz -&gt; 20 ms<br /><br />50Hz * 256 = 12800 Hz<br /><br />obliczanie OCR0: 16000000/8/12800 = 156,2 <br />czyli OCR0 = 155.<br /><br />inicjalizacja Timera 0 wygląda tak:<br />[syntax=c]void init_Timer0 (void)<br />{<br />/* Timer0 – konfiguracja silnika timerów programowych */<br />TCCR0  |= (1&lt;&lt;WGM01);   // tryb pracy CTC<br />TCCR0  |= (1&lt;&lt;CS01); // preskaler = 8<br />OCR0  = 155;   // przerwanie porównania co 0.000,078,125s (12800Hz)<br />TIMSK  = (1&lt;&lt;OCIE0); // Odblokowanie przerwania CompareMatch<br />}[/syntax]<br /><br />no i teraz treść przerwania : <br />[syntax=c]ISR (TIMER0_COMP_vect){  // przerwanie uruchamiające programowy PWM dla serw i dla silników DC<br /><br />static uint8_t cnt; // licznik programowy 0-255  12800Hz / 256 = 50 Hz =&gt; 20ms<br />uint16_t n;<br /><br />if(cnt&gt;=union_recive.frame_recive.pwm_p){ // pwm silnika prawego (wartości 0-256)<br />PORTC&amp;=~PC6;<br />}else PORTC|=PC6;<br /><br />if(cnt&gt;=union_recive.frame_recive.pwm_l){ // pwm silnika prawego (wartości 0-256)<br />PORTC&amp;=~PC1;<br />}else PORTC|=PC1;<br /><br />if(cnt&gt;=union_recive.frame_recive.cam_pion){ // pwm serwa pionowego (wartości 12-26)<br />PORTD|=PD3;<br />}else PORTD&amp;=~PD3;<br /><br />if(cnt&gt;=union_recive.frame_recive.cam_poz){ // pwm serwa poziomego (wartości 12-26)<br />PORTD|=PD4;<br />}else PORTD&amp;=~PD4;<br /><br />union_send.frame_send.fault++; // tylko do testu<br /><br />// TIMERY PROGRAMOWE NA POTRZEBY FUNKCJI GŁÓWNEJ<br /> n = Timer0_1;  /* 12800Hz Timer1 */<br /> if (n) Timer0_1 = --n;<br /><br /> n = Timer0_2;  /* 12800Hz Timer2 */<br /> if (n) Timer0_2 = --n;<br /><br />cnt++;<br />}[/syntax]<br /><br />przerwanie działa bo union_send.frame_send.fault (jest w innej strukturze też ze specyfikatorem volatile) wyświetlam na lcd i widać że sobie przelatuje bardzo szybko <br /><br />natomiast na PC6 PC1 PD3 PD4 nie mam pwm   <img src="https://forum.atnel.pl/images/smilies/icon_cry.gif" alt=":cry:" title="Płacze" /> <br /><br />Dodam że JTAG jest wyłączony oraz wejście TOSC1 (PC6)  (na pewno nie działa jako wejscie bo dla pewności na poczatku dorzuciłem ASSR&amp;=~(1&lt;&lt;AS2) )<br /><br /><br />na dodatek gdy już w pętli głównej użyje<br /><br />[syntax=c]if (!Timer0_1) {<br />Timer0_1=5000; // około 390 ms<br />PORTD^=(1&lt;&lt;PD2);<br />}[/syntax]<br /><br />to dioda podłączona anodą dla testów do PD2 świeci ciągle.<br /><br />Ukłony komuś kto spróbuje pomóc.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=257">Kvite</a> — 29 sty 2014, o 23:31</p><hr />
]]></content>
</entry>
</feed>