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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-08-24T20:07:38+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=8&amp;t=12736&amp;mode</id>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2015-08-24T20:07:38+01:00</updated>
<published>2015-08-24T20:07:38+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138238#p138238</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138238#p138238"/>
<title type="html"><![CDATA[Re: Przerwania wewnętrzne - problem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138238#p138238"><![CDATA[
Pod koniec rozdziału o ADC jest opisany rejestr SFIOR. Są tam bity ADTSx. Należy je ustawić tak, aby przepełnienie timera 1 wyzwalało pomiar. Będzie się to działo automatycznie. Przerwanie TIMER1_OVF_vect i (1&lt;&lt;TOIE1) nie są potrzebne. Należy dodatkowo ustawić bit ADATE w rejestrze ADCSRA oraz przerwanie ADC_vect i w nim pobierać pomiar i wysyłać na port szeregowy tak jak to robisz teraz w funkcji obsługi przerwania od przepełnienia timera 1.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 24 sie 2015, o 20:07</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[lorddran]]></name></author>
<updated>2015-08-23T19:20:18+01:00</updated>
<published>2015-08-23T19:20:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138177#p138177</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138177#p138177"/>
<title type="html"><![CDATA[Re: Przerwania wewnętrzne - problem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138177#p138177"><![CDATA[
Poprawiłem błędy, bardzo za nie przepraszam <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><br />Ok, bezsensowna linijka to mój błąd podczas pisania - nie pytajcie jak ta pomyłka powstała. Naturalnie chciałem napisać<br />[syntax=c]TIMSK |= (1&lt;&lt;TOIE1) | (1&lt;&lt; OCIE1A);[/syntax]<br />Niestety to właśnie ustawienie zakłóca mi działanie programu.<br /><br /><br />Wydaje mi się, że przyczyną jest umieszczenie w przerwaniu ISR(TIMER1_OVF_vect) pętli while. Dobrze myślę?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8931">lorddran</a> — 23 sie 2015, o 19:20</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[anshar]]></name></author>
<updated>2015-08-23T18:49:57+01:00</updated>
<published>2015-08-23T18:49:57+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138169#p138169</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138169#p138169"/>
<title type="html"><![CDATA[Re: Przerwania wewnętrzne - problem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138169#p138169"><![CDATA[
Po pierwsze piszesz w języku C, a nie w &quot;język actionscript&quot;, popraw to proszę (wybieraz listing kodu: C, zamiast actionscript).<br /><br />Następnie nigdy w kodzie nie umieszczamy <br />[syntax=c]#define F_CPU 16000000UL[/syntax]<br />robimy to w ustawieniach projektu. Zobacz <a href="https://www.youtube.com/watch?v=UhcyBpM57vo&amp;feature=youtu.be&amp;t=3026"  class="postlink">tutaj.</a><br /><br />Ta linijka [syntax=c]TIMSK |= (0&lt;&lt;TOIE1) | (0&lt;&lt; OCIE1A);[/syntax]<br />nie ma sensu, zobacz w data sheet str.112 bity TOIE1 I OCIE1A domyślnie są ustawione na 0, poza tym tak się nie zeruje przecież bitów, prawda?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=7157">anshar</a> — 23 sie 2015, o 18:49</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[lorddran]]></name></author>
<updated>2015-08-23T21:19:29+01:00</updated>
<published>2015-08-23T17:44:40+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138160#p138160</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138160#p138160"/>
<title type="html"><![CDATA[Przerwania wewnętrzne - problem]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12736&amp;p=138160#p138160"><![CDATA[
Witam.<br />W swoim kodzie staram się wykorzystać wewnętrzne przerwania generowane przez TIMER1 atmegi32. Timer działa w trybie 3 (PWM z korekcją fazy). Chcę wykorzystać przerwania po ustawieniu flag TOV1 (do dokonywania pomiaru adc) i OCR1A (do obliczeń nowej wartości PWM'a). Najpierw zapomniałem ustawić flag TOIE1 i OCIE1A w rejestrze TIMSK - program działał, poza pomiarem i obliczeniami nowej wartości PWM (czyli działała komunikacja z PC i ręczne ustawianie PWM). Po dodaniu w main() linijki: TIMSK |= (0&lt;&lt;TOIE1) | (0&lt;&lt; OCIE1A); przestała działać komunikacja. Co robię źle?<br /><br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;string.h&gt;<br />#include &quot;mkuart.h&quot;<br /><br />#define LED (1&lt;&lt;PC7)<br />#define KIERUNEK1 (1&lt;&lt;PD7) <br />#define KIERUNEK2 (1&lt;&lt;PD2)<br />#define KIERUNEK_TOG1 PORTD ^= KIERUNEK1<br />#define KIERUNEK_TOG2 PORTD ^= KIERUNEK2<br />#define LED_ON PORTC |= LED<br />#define LED_OFF PORTC &amp;= ~LED<br /><br />//----------------- ZMIENNE<br />char uart_buf&#91;100&#93;;<br />volatile uint32_t procent = 0;<br />volatile float pomiar1 = 0;<br />volatile int32_t wyjscie = 0;<br />volatile float tmp = 0;<br />volatile int16_t tmp1 = 0;<br />volatile float zadany = 0;<br />volatile float zmierzony = 0;<br />volatile uint8_t regulacja = 0;<br />volatile float do_wyslania = 0;<br />volatile uint16_t odebrane = 0;<br /><br />//---------------- Struktura zmiennych PID<br />struct Struktura {<br />float R;<br />float L;<br />float Kpp;<br />float Kpi; <br />float Tii; <br />float Tp;<br />float int_I;<br />float int_old;<br />float ii; <br />float ei; <br />float iref;<br />uint16_t anti;<br />};<br />struct Struktura STR_PID;<br /><br />//-------------------------------- FLAGI<br />volatile unsigned char timer0_flag = 0;<br />volatile unsigned char regulator_status = 0;<br /><br />//-------------------------------- FUNKCJE<br />void analizuj_dane( char * buf );<br />float regulator(float zadany , float zmierzony);<br />uint32_t PWM_reczny(uint32_t procent);<br /><br />int main(void){<br />//---------------------------- USTAWIENIA POCZATKOWE<br />DDRA=0xFF; //porty jako wyjscia<br />DDRB=0xFF;<br />DDRC=0xFF;<br />DDRD=0xFF;<br /><br />DDRB |=LED; // dioda do testow<br />DDRA &amp;= ~(1&lt;&lt;PA0); // PA0 jako wejście adc<br />DDRD |= (1&lt;&lt;PD2) | (1&lt;&lt;PD3) | (1&lt;&lt;PD5) | (1&lt;&lt;PD6) | (1&lt;&lt;PD7);// kierunek1, blokada1 (stan niski blokuje), PWM(PD5), blokada2, kierunek2.<br />PORTD &amp;= ~(1&lt;&lt;PD2);// ustawienie zer na portach sterujacych po starcie<br />PORTD &amp;= ~(1&lt;&lt;PD3);<br />PORTD &amp;= ~(1&lt;&lt;PD6);<br />PORTD &amp;= ~(1&lt;&lt;PD7);<br />PORTD |= (1&lt;&lt;PD7);// ustawienie obrotów w lewo<br />PORTD &amp;= ~(1&lt;&lt;PD2);<br />PORTD|=(1&lt;&lt;PD5);<br /><br /><br />//------------------------------------------------- PWM Timer1 (PWM with phase correct)<br />TCCR1A |= (1&lt;&lt;WGM10) | (1&lt;&lt;WGM11);// pwm with phase correct (mode 3)<br />TCCR1A |= (1&lt;&lt;COM1A1); // nieodwracajacy<br />TCCR1B |= (1&lt;&lt;CS10);   //preskaler 1<br />TIMSK |= (0&lt;&lt;TOIE1) | (0&lt;&lt; OCIE1A);<br />//------------------------------------------------- ADC<br />ADCSRA |= (1&lt;&lt;ADEN); //uruchomienie ADC<br />ADCSRA |= (1&lt;&lt;ADPS2) | (1&lt;&lt;ADPS1) | (1&lt;&lt;ADPS0); // preskaler 128<br />ADMUX |= (1&lt;&lt;REFS1) | (1&lt;&lt;REFS0); //napiecie odniesienia 2,56<br />ADMUX = (ADMUX &amp; 0b11111000) | 0;<br /><br />STR_PID.Tp = 0.0001; // 1/f<br />STR_PID.Tii = 0.001; // L/R<br />STR_PID.Kpi = 3.125; // (Tii * R)/(2*Kpp+Tp)<br />STR_PID.Kpp = 24;<br />//STR_PID.anti = 1;<br /><br />// inicjacja usartu<br />register_uart_str_rx_event_callback ( analizuj_dane );<br />USART_Init( __UBRR );<br />_delay_ms(10);<br />sei();<br /><br />while (1)<br />{<br />UART_RX_STR_EVENT( uart_buf );<br /><br />//===================== STOP ===========================<br />if (regulator_status == 0)<br />{<br />PORTD &amp;= ~(1&lt;&lt;PD3);<br />PORTD &amp;= ~(1&lt;&lt;PD6);<br />STR_PID.int_I = 0;<br />}<br />//================= RĘCZNE WPISYWANIE PWM ==============<br />if(regulator_status == 2)<br />{<br />PWM_reczny(procent);<br />}<br />//================= Regulacja PI ==================<br />if(regulator_status == 1) <br />{<br />TIMSK |= (1&lt;&lt;TOIE1);<br />PORTD |= (1&lt;&lt;PD3) | (1&lt;&lt;PD6);// odblokowanie mostka<br /><br />OCR1A = wyjscie; <br /><br />} <br />}<br />}<br /><br />void analizuj_dane( char * buf ){<br /><br />char * wsk;<br />wsk = strtok( buf, &quot;,&quot; );<br /><br />if ( !strcmp(wsk, &quot;led&quot;)){<br />wsk = strtok( NULL, &quot;,&quot; );<br />if( *wsk == '1' ){<br />LED_ON;<br />}<br />if ( *wsk == '0' ){<br />LED_OFF;<br />}<br />}<br />if ( !strcmp(wsk, &quot;K&quot;)){<br />wsk = strtok( NULL, &quot;,&quot; );<br />if( *wsk == 'L' ){<br />PORTD |= (1&lt;&lt;PD7);<br />PORTD &amp;= ~(1&lt;&lt;PD2);<br />}<br />if ( *wsk == 'P' ){<br />PORTD |= (1&lt;&lt;PD2);<br />PORTD &amp;= ~(1&lt;&lt;PD7);<br />}<br />if ( *wsk == 'T' ){<br />KIERUNEK_TOG1;<br />KIERUNEK_TOG2;<br />}<br />}<br />if ( !strcmp(wsk, &quot;PWM&quot;))<br />{<br />wsk = strtok( NULL, &quot;,&quot; );<br />procent = atoi(wsk);<br />}<br />if ( !strcmp(wsk, &quot;REG&quot;))<br />{<br />wsk = strtok( NULL, &quot;,&quot; );<br />regulator_status = atoi(wsk);<br />}<br />if ( !strcmp(wsk, &quot;ZAD&quot;))<br />{<br />wsk = strtok( NULL, &quot;,&quot; );<br />odebrane = atoi(wsk);<br />}<br />}<br /><br />uint32_t PWM_reczny(uint32_t procent){<br /><br />uint8_t wartosc_pwm = 0;<br />float wypelnienie = 0;<br />float mnoznik = 10.24;<br /><br />if (procent == 0)<br />{<br />PORTD &amp;= ~(1&lt;&lt;PD3);<br />PORTD &amp;= ~(1&lt;&lt;PD6);<br />wyjscie = 0;<br />wypelnienie = 0;<br />}<br />else{<br />wartosc_pwm=procent;// Obliczanie wartości wypełnienia z procentów (PWM,%)<br />wypelnienie = ((mnoznik * wartosc_pwm) + 0.5);<br />PORTD |= (1&lt;&lt;PD3) | (1&lt;&lt;PD6); // Odblokowanie mostka<br /><br />OCR1A = wypelnienie;<br />}<br /><br />uart_putint( OCR1A, 10);<br />uart_puts(&quot;\r\n&quot;);<br />}<br /><br />float regulator(float zadany, float zmierzony)<br />{<br />float ret;<br />STR_PID.ei = zadany - zmierzony; <br />STR_PID.int_I = 0;<br /><br />ret =((float)STR_PID.Kpi * (float)STR_PID.ei);<br /><br />return((float)ret);<br />}<br /><br />// przerwanie w chwili porównania (TOP) - do obliczeń PI<br />ISR(TIMER1_COMPA_vect)<br />{<br />zadany = (float)0.3;<br />zmierzony = (float) 0.015 * pomiar1 - 7.992;<br /><br /><br />do_wyslania = pomiar1;<br />uart_putint( do_wyslania, 10);<br />uart_puts(&quot;\r\n&quot;);<br /><br /><br />tmp = regulator(zadany, zmierzony);<br /><br />if (tmp &gt;= 0)<br />{<br />PORTD |= KIERUNEK2;// kierunek 1<br />PORTD &amp;= ~KIERUNEK1;// kierunek 2<br />}<br />else<br />{<br />PORTD |= KIERUNEK1;// kierunek 1<br />PORTD &amp;= ~KIERUNEK2;// kierunek 2<br />tmp = tmp*(-1);<br />}<br />if (tmp &gt;= 1)<br />{<br />tmp = 1;<br />}<br />tmp1 = (int16_t)(tmp * 255);<br />wyjscie = tmp1;<br />}<br /><br />// przerwanie w chwili przepełnienia (BOTTOM) - pomiar ADC<br />ISR(TIMER1_OVF_vect)<br />{<br />ADCSRA |= (1&lt;&lt;ADSC);<br />while(ADCSRA &amp; (1&lt;&lt;ADSC));<br />pomiar1 = ADCW;<br /><br />do_wyslania = pomiar1;<br />uart_putint( do_wyslania, 10);<br />uart_puts(&quot;\r\n&quot;);<br /><br />}[/syntax]<br /><br />Kod troszkę długi i może niefachowo poukładany, więc jeśli przy okazji macie pomysł jak go ulepszyć to nie krępujcie się wytykać mi błędów - oczywiście konstruktywnie.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8931">lorddran</a> — 23 sie 2015, o 17:44</p><hr />
]]></content>
</entry>
</feed>