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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2014-01-07T22:04:07+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=5471&amp;mode</id>
<entry>
<author><name><![CDATA[adamstepniak41]]></name></author>
<updated>2014-01-07T22:04:07+01:00</updated>
<published>2014-01-07T22:04:07+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=5471&amp;p=64222#p64222</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=5471&amp;p=64222#p64222"/>
<title type="html"><![CDATA[Pogramowy PWM, sterowanie serwami.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=5471&amp;p=64222#p64222"><![CDATA[
Witam. <br />Mam problem z programem do sterowania serwami za pomocą potencjometru. Serwa drżą i nie reagują na obrót potencjometru. Pracuje na atmega16 16MHz. Fusbity mam ustawione poprawnie. Próbowałem drogą eliminacji dojść w którym fragmencie kodu może być błąd i doszedłem do tego, że program działa poprawnie bez fragmentów kodu związanych z ADC. W pętli głównej napisałem pętle która zwiększała i zmniejszała wypełnienie PWM i do tego momentu działało poprawnie. W momencie dołączenia linijek od ADC serwa zaczynają drżeć i nie reagują na polecenia. Niestety nie mam możliwości sprawdzenia układu pod oscyloskopem dlatego proszę o rzucenie okien na mój kod. <br />Pozdrawiam.<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br /><br /><br />volatile uint16_t ADC0;<br />volatile uint16_t ADC1;<br />volatile uint16_t ADC2;<br />volatile uint16_t ADC3;<br /><br />static uint8_t TheLow;<br />static uint16_t Result;<br />static volatile float a;<br /><br />ISR(TIMER1_COMPA_vect);  // deklaracja funkcji obslugi przewan od timera1<br />ISR (ADC_vect);          // deklaracja funkcji obslugi przerwan od ADC<br /><br />int main(void)<br />{<br />DDRC |= 1&lt;&lt;PC3;<br />PORTC |= 1&lt;&lt;PC3;<br />DDRD |= (1&lt;&lt;PD7)|(1&lt;&lt;PD5)|(1&lt;&lt;PD4); // piny serw jako wyjscia<br />DDRB |= (1&lt;&lt;PB3);                   // piny serw jako wyjscia<br />PORTD |= (1&lt;&lt;PD7)|(1&lt;&lt;PD5)|(1&lt;&lt;PD4); // piny serw jako wyjscia w stanie wysokim<br />PORTB |= (1&lt;&lt;PB3);                   // piny serw jako wyjscia w stanie wysokim<br />DDRA &amp;= ~((1&lt;&lt;PA0)|(1&lt;&lt;PA1)|(1&lt;&lt;PA2)|(1&lt;&lt;PA3)); // piny ADC jako wejscia<br /><br />sei();<br />//---------konfiguracja timera -----------------------//<br />TCCR1A |= 1&lt;&lt;WGM11; // tryb fast PWM<br />TCCR1B |= 1&lt;&lt;WGM12 | 1&lt;&lt;WGM13 | 1&lt;&lt;CS11; // tryb fast PWM; prescaler 8<br />TIMSK |= 1&lt;&lt;OCIE1A; // zezwolenie na przerwanie od compare match<br />ICR1 = 39999; // wartosc TOP dla 20ms<br /><br />//-------------------------------------------<br /><br />//----------koniguracja ADC-----------------------//<br />ADCSRA |= (1&lt;&lt;ADPS2)|(1&lt;&lt;ADPS1)|(1&lt;&lt;ADPS0)/*|(1&lt;&lt;ADATE)*/; // prescaler 16; zrodlo zdarzenia<br />ADMUX  |= (1&lt;&lt;REFS0)|(1&lt;&lt;REFS1); // wew zrodlo napiecia odniesienia<br />ADCSRA |= (1&lt;&lt;ADIE); // interrups enable<br />ADCSRA |= (1&lt;&lt;ADEN); // ADC enable<br />ADCSRA |= (1&lt;&lt;ADSC);<br /><br /><br />a = ((4000-2000)/1023);<br /><br />while(1)<br />{<br /><br />//----------Przerzutowanie-----------------------//<br /><br />switch (ADMUX)<br />{<br />   case 0xC1:<br />   ADC0 = ((a*ADC0)+ 2000);<br />   break;<br /><br />   case 0xC2:<br />   ADC1 = ((a*ADC1)+ 2000);<br />   break;<br /><br />   case 0xC3:<br />   ADC2 = ((a*ADC2)+ 2000);<br />   break;<br /><br />   case 0xC0:<br />   ADC3 = ((a*ADC3)+ 2000);<br />   break;<br /><br />}<br />//--------------------------------------------------//<br /><br /><br />//----------Sterowanie serwami-----------------------//<br /><br />if (TCNT1 &gt;=2000 &amp;&amp; TCNT1 &lt;= 4000)<br />{<br />if (TCNT1 &gt;= ADC0 &amp;&amp; bit_is_set(PORTD,PIND4)) PORTD &amp;= ~(1&lt;&lt;PIND4);<br />if (TCNT1 &gt;= ADC1 &amp;&amp; bit_is_set(PORTD,PIND5)) PORTD &amp;= ~(1&lt;&lt;PIND5);<br />if (TCNT1 &gt;= ADC2 &amp;&amp; bit_is_set(PORTD,PIND7)) PORTD &amp;= ~(1&lt;&lt;PIND7);<br />if (TCNT1 &gt;= ADC3 &amp;&amp; bit_is_set(PORTB,PINB3)) PORTB &amp;= ~(1&lt;&lt;PINB3);<br />}<br /><br />}<br /><br />}<br />//--------------------------------------------------------//<br /><br /><br />//------------ przerwanie od timera------------------------<br />ISR(TIMER1_COMPA_vect)<br />{<br />PORTD |= (1&lt;&lt;PD7)|(1&lt;&lt;PD5)|(1&lt;&lt;PD4); // piny serw jako wyjscia w stanie wysokim<br />PORTB |= (1&lt;&lt;PB3);                   // piny serw jako wyjscia w stanie wysokim<br /><br />ADCSRA |= 1&lt;&lt;ADSC;<br />// PORTD ^= (1&lt;&lt;PD7);<br /><br />}<br />//---------------------------------------------------------<br /><br /><br />//----------------- przerwanie od ADC-----------------------<br />ISR (ADC_vect)<br />{<br />PORTC ^= 1&lt;&lt;PC3;<br />TheLow = ADCL;<br />    Result = (ADCH&lt;&lt;8) | TheLow;<br /><br />switch (ADMUX)<br />{<br />   case 0xC0:<br />   ADC0=Result;<br />   ADMUX = 0xC1;<br />   break;<br /><br />   case 0xC1:<br />   ADC1=Result;<br />   ADMUX = 0xC2;<br />   break;<br /><br />   case 0xC2:<br />   ADC2=Result;<br />   ADMUX = 0xC3;<br />   break;<br /><br />   case 0xC3:<br />   ADC0=Result;<br />   ADMUX = 0xC0;<br />   break;<br /><br />   default:<br />   //Default code<br />   break;<br /><br />}<br /><br /><br />}<br />//-----------------------------------------------------[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1473">adamstepniak41</a> — 7 sty 2014, o 22:04</p><hr />
]]></content>
</entry>
</feed>