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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2016-12-13T10:01:06+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=17037&amp;mode</id>
<entry>
<author><name><![CDATA[amilo_pa]]></name></author>
<updated>2016-12-13T10:01:06+01:00</updated>
<published>2016-12-13T10:01:06+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177344#p177344</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177344#p177344"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177344#p177344"><![CDATA[
Nie nie nie <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> właśnie bardzo dobrze, że pokazałeś mi inny sposób i dałeś mi zagwozdkę <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> to jest jedyny sposób żeby nauczyć się dobrze programować <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> muszę przed świętami zakończyć ten projekt, ale zaraz po świętach ogarnę podesłany przez Ciebie kod i przerobię swój program na wzór tego kodu <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br />Dziękuje za podpowiedzi <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=3824">amilo_pa</a> — 13 gru 2016, o 10:01</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2016-12-13T08:38:47+01:00</updated>
<published>2016-12-13T08:38:47+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177327#p177327</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177327#p177327"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177327#p177327"><![CDATA[
Chyba niepotrzebnie Ci namieszałem z tymi wskaźnikami na funkcje <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" />, ale to bardzo typowa sytuacja, gdzie aż się prosi, żeby ich użyć, ponieważ to znacznie upraszcza kod.<br /><br />Zasadniczo sprawa jest stosunkowo prosta. Zakładam, że ogólnie wiesz co to są wskaźniki. Tak samo, jak zmienną można odczytać (lub zmodyfikować) bezpośrednio za pomocą jej nazwy albo pośrednio, za pomocą wskaźnika (adresu w pamięci), tak samo funkcję można wywołać bezpośrednio, za pomocą jej nazwy albo pośrednio, za pomocą wskaźnika na tę funkcję. Funkcja przecież również znajduje się gdzieś w pamięci i musi posiadać swój adres.<br /><br />Początkowo deklaracja takiego wskaźnika na funkcję może wydawać się nieco skomplikowana i niezrozumiała, ale jak już się zrozumie o co chodzi, staje się to proste. Zapewne w tym przypadku wygląda to jeszcze bardziej skomplikowanie, dlatego że wskaźnik nie jest osobną zmienną, tylko elementem struktury.<br /><br />W tej chwili nie mam czasu tego opisywać, a poza tym to trochę za dużo pisania, żeby to szczegółowo wyjaśniać na forum. Jest na pewno sporo materiałów na ten temat w internecie, więc poczytaj  i jak czegoś nie zrozumiesz to pytaj.<br /><br />Słowa kluczowe to coś w stylu:<br />c wskaźnik na funkcję<br />lub<br />c function pointers<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 13 gru 2016, o 08:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[amilo_pa]]></name></author>
<updated>2016-12-12T21:44:03+01:00</updated>
<published>2016-12-12T21:44:03+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177291#p177291</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177291#p177291"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177291#p177291"><![CDATA[
@andrews siedzę już 2 godzinę i próbuje zrozumieć to co napisałeś i normalnie nie ogarniam <img src="https://forum.atnel.pl/images/smilies/icon_e_biggrin.gif" alt=":D" title="Bardzo szczęśliwy" /> totalny mindfuck <img src="https://forum.atnel.pl/images/smilies/icon_e_biggrin.gif" alt=":D" title="Bardzo szczęśliwy" /> Masz może jakiś zestaw ćwiczeń, który umożliwi mi zrozumienie tego kodu ? <img src="https://forum.atnel.pl/images/smilies/icon_razz.gif" alt=":P" title="Pokazuje język" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3824">amilo_pa</a> — 12 gru 2016, o 21:44</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2016-12-11T19:36:28+01:00</updated>
<published>2016-12-11T19:36:28+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177156#p177156</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177156#p177156"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177156#p177156"><![CDATA[
<div class="quotetitle">amilo_pa napisał(a):</div><div class="quotecontent"><br />dodanie ATOMIC_BLOCK(ATOMIC_RESTORESTATE) nie przyniosło pożądanego efektu<br /></div><br />Nawet jeśli, to uwierz mi, że to nie jest jakieś moje &quot;widzimisię&quot;, tak po prostu musi być, aby program działał prawidłowo.<br /><br />Rozpatrzmy sobie sytuację:<br /><ul><li>Zmienna chimney.LED_timer jest równa 0x0100.</li><li>W celu sprawdzenia warunku <em>if(!chimney.LED_timer)</em> zmienna musi zostać załadowana do rejestrów.</li><li>Zostaje wczytany do rejestru najpierw młodszy bajt zmiennej, czyli 0x00.</li><li>W tym momencie następuje skok do procedury obsługi przerwania i zmienna jest dekrementowana, osiągając wartość 0x00FF.</li><li>Teraz program wraca do głównego programu i do następnego rejestru jest ładowany starszy bajt zmiennej, czyli w chwili obecnej 0x00.</li></ul>W efekcie do kolejnych rejestrów została wpisana dwa razy wartość 0x00, czyli kopia całej zmiennej w rejestrach jest równa 0x0000 (warunek <em>if(!chimney.LED_timer)</em> jest spełniony), pomimo tego że w rzeczywistości wartość zmiennej wynosi 0x00FF, czyli program nie działa zgodnie z założeniem.<br /><br />Oczywiście takie sytuacje nie muszą się zdarzać często, co powoduje, że błąd nie jest od razu widoczny, ale prędzej czy później takie sytuacje się zdarzą.<br /><br /><div class="quotetitle">amilo_pa napisał(a):</div><div class="quotecontent"><br />Nie za bardzo rozumiem zapis tego kodu window_left.chosen_function(&amp;window_left); i jak ma to wywoływać odpowiednią funkcję<br /></div><br />[syntax=c]// niezbędne, aby definicja wskaźnika do funkcji<br />// znała strukturę TLED_RGB<br />typedef struct TLED_RGB TLED_RGB;<br /><br />// definicja typu wskaźnik do funkcji posiadającej jeden parametr<br />// w postaci wskaźnika do struktury TLED_RGB<br />typedef void (*led_drv_fn)(TLED_RGB*);<br /><br />//deklaracja struktury typu TLED_RGB<br />struct TLED_RGB {<br />    uint8_t color&#91;6&#93;;                   //wartość PWM diod RGB: R=0, G=1, B=2, H=3, S=4, V=5<br />    volatile uint16_t timer_set;        //zapamiętany czas rozświetlania i ściemniania diody RGB, ładowany do licznika LED_timer<br />    volatile uint16_t LED_timer;        //czas odliczany w przerwaniu<br />    volatile uint32_t period_time;      //zmienna za pomocą której ustawiamy nowy czas szybkości rozświetlania i ściemniania diody<br />    led_drv_fn chosen_function;         // wskaźnik do funkcji sterującej ledem<br />    volatile uint8_t value_max;         //zmienna odpowiedzialna za maksymalny strumień świetlny<br />    volatile uint8_t saturation_max;    //zmienna odpowiadająca za maksymalne nasycenie kolorów<br />};<br /><br />// funkcje sterujące<br />void select_set_colors_rgb(TLED_RGB *sel_rgb);<br />void flow_colors_rgb(TLED_RGB *sel_rgb);<br /><br />// deklaracja zmiennej 'test' typu TLED_RGB<br />// w miejscu elementu struktury 'chosen_function' wpisujemy<br />// nazwę funkcji, którą chcemy zainicjować wstępnie<br />TLED_RGB test = {<br />    { 255, 255, 255, 255, 255, 255 },<br />    0, 0, 0, select_set_colors_rgb, 0, 0<br />};<br /><br />// teraz w programie możemy wywołać funkcję<br />// tym razem będzie to funkcja 'select_set_colors_rgb'<br />    test.chosen_function(&amp;test);<br /><br />// można do zmiennej przypisać inną funkcję<br />    test.chosen_function = flow_colors_rgb;<br /><br />// teraz zostanie wywołana funkcja 'flow_colors_rgb'<br />    test.chosen_function(&amp;test);<br /><br />// czyli w Twoim kodzie zamiast pisać<br />    diode_rgb-&gt;chosen_function = 2;<br />// przypisujesz zamiast wartości 2 nazwę fukcji, którą planujesz wywołać<br />    diode_rgb-&gt;chosen_function = flow_colors_rgb;[/syntax]<br /><br /><br />Jeśli w tej chwili masz odrębne funkcje dla poszczególnych struktur, to być może przekazywanie argumentu w postaci wskaźnika do struktury będzie zbędne. Trzeba by było w takim przypadku odpowiednio zmodyfikować mój przykład.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 11 gru 2016, o 19:36</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[amilo_pa]]></name></author>
<updated>2016-12-11T17:33:31+01:00</updated>
<published>2016-12-11T17:33:31+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177144#p177144</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177144#p177144"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177144#p177144"><![CDATA[
ok, teraz rozumiem i dziękuję za informacje:)<br /><br />Program działa poprawnie, ale ze zdublowanymi funkcjami (do każdej struktury TLED_RGB utworzyłem osobną funkcje która wykonuje to samo więc nie jest to optymalny sposób) :/ a dodanie <em>ATOMIC_BLOCK(ATOMIC_RESTORESTATE)</em> nie przyniosło pożądanego efektu :/<br /><br />Nie za bardzo rozumiem zapis tego kodu  <em>window_left.chosen_function(&amp;window_left);</em>  i jak ma to wywoływać odpowiednią funkcję :/ możesz coś rozjaśnić? Z góry dziękuję <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=3824">amilo_pa</a> — 11 gru 2016, o 17:33</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2016-12-11T16:15:46+01:00</updated>
<published>2016-12-11T16:15:46+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177129#p177129</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177129#p177129"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177129#p177129"><![CDATA[
<div class="quotetitle">amilo_pa napisał(a):</div><div class="quotecontent"><br />Czyli polega to na tym, że w momencie porównania if(!chimney.LED_timer) nie może wystąpić przerwanie od Timera2<br /></div><br />Dokładnie o to chodzi, jednak nie tylko w momencie porównania, ale także w trakcie przypisania wartości <em>chimney.LED_timer=chimney.timer_set;</em>.<br /><br />Oczywiście ta zasada nie dotyczy tylko tego konkretnego przypadku. Zawsze kiedy zmienna składająca się z więcej niż jednego bajtu (w mikrokontrolerach 8-bitowych) jest używana zarówno w przerwaniu, jak i w głównej pętli programu należy zapewnić do niej atomowy dostęp. Nie trzeba tego robić wewnątrz procedury obsługi przerwania, ponieważ wtedy globalna flaga zezwalająca na przerwania jest wyłączona, chyba że programista ją sam świadomie włączy, ale to już inna historia <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br />Niestety nie mam czasu na szczegółową analizę całego kodu. Zakładam, że skoro działa poprawnie to znaczy, że jest OK. Wydaje mi się, że czasami może niepotrzebnie komplikujesz pewne sprawy, ale to się na pewno zmieni, jak zdobędziesz praktykę <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br />Podam jeden przykład. Nie chodzi o to, że to błąd, chodzi tylko o poprawę czytelności (i być może szybkości wykonania).<br />Mógłbyś w strukturze TLED_RGB zamiast indeksu funkcji użyć wskaźnika do niej. Wprawdzie spowodowałoby to zwiększenie rozmiaru struktury o 1 bajt (nie masz przecież tych zmiennych dużo), jednak wywołanie odpowiedniej funkcji:<br />[syntax=c]// zamiast wyglądać tak<br />    if(window_left.chosen_function == 1){//wybór funkcji wyświetlania led<br />        select_set_colors_rgb(&amp;window_left);//rozświetlanie i ściemnianie wybranych kolorów<br />    }<br />    else if(window_left.chosen_function == 2){<br />        flow_colors_rgb (&amp;window_left);//cykliczna zmiana pomiędzy kolorami<br />    }<br /><br />// mogłoby wyglądać tak (niezależnie od ilości funkcji do wyboru)<br />    window_left.chosen_function(&amp;window_left);[/syntax]<br />W tej chwili masz tylko dwie funkcje do wyboru, ale jak wyglądałoby Twoje wywołanie, gdyby ich było np. 10?<br /><br />No ale tak jak napisałem, z czasem na pewno do tego dojdziesz <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=14165">andrews</a> — 11 gru 2016, o 16:15</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[amilo_pa]]></name></author>
<updated>2016-12-11T12:38:09+01:00</updated>
<published>2016-12-11T12:38:09+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177103#p177103</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177103#p177103"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177103#p177103"><![CDATA[
@andrews Czyli polega to na tym, że w momencie porównania <em>if(!chimney.LED_timer)</em> nie może wystąpić przerwanie od Timera2, dobrze rozumiem zastosowanie flagi atomowej?<br /><br />Nie wiem czy dobrze to zrobiłem, mógłbyś rzucić okiem?<br /><br />main.c<br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 9 lis 2016<br /> *       Autor: Piotr Łączny<br /> */<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;util/atomic.h&gt;<br /><br /><br />#include &quot;LCD/lcd44780.h&quot;<br />#include &quot;IR_DECODE/ir_decode.h&quot;<br />#include &quot;GAMMA_CORRECTION/gamma.h&quot;<br />#include &quot;D_LED/d_led.h&quot;<br /><br /><br />#define PERIOD_Tim3 117<br /><br />#define SATURATION 2<br /><br /><br /><br /><br /><br /><br />uint8_t chose_led &#91;3&#93;;//zmienna umożliwiająca wybór diody oraz przypisanie do niej funkcji sterującej diodą<br /><br /><br />//uint8_t select_color_chimney = 0, flaga_rgb_chimney = 0, i_chimney = 0;<br />//uint8_t select_color_window_left = 0, flaga_rgb_window_left = 0, i_window_left = 0;<br /><br />uint16_t temp; //zmienna wykorzystywana do flagi atomowej<br /><br />int main(void) {<br /><br /><br />//ustawienia startowe diody komina<br />chimney.color&#91;H&#93;=RED;<br />chimney.color&#91;S&#93;=255;<br />chimney.color&#91;V&#93;=255;<br />chimney.value_max=255;<br />chimney.saturation_max = 255;<br />chimney.chosen_function = 1;<br />chimney.timer_set=80;//PERIOD_Tim3; //co 20 ms przerwanie<br />chimney.LED_timer=PERIOD_Tim3; //co 20 ms przerwanie<br />chimney.period_time = PERIOD_TIME_LED;<br /><br />//ustawienia startowe diody w lewym oknie<br />window_left.color&#91;H&#93;=BLUE;<br />window_left.color&#91;S&#93;=255;<br />window_left.color&#91;V&#93;=255;<br />window_left.value_max=255;<br />window_left.saturation_max = 255;<br />window_left.chosen_function = 2;<br />window_left.timer_set=10;//PERIOD_Tim3;<br />window_left.LED_timer=50;//PERIOD_Tim3;<br />window_left.period_time = PERIOD_TIME_LED;<br /><br />//ustawienia startowe diody w prawym oknie<br />window_right.color&#91;H&#93;=RED;<br />window_right.color&#91;S&#93;=255;<br />window_right.color&#91;V&#93;=255;<br />window_right.value_max=255;<br />window_right.saturation_max = 255;<br />window_right.chosen_function = 2;<br />window_right.timer_set=PERIOD_Tim3;<br />window_right.LED_timer=PERIOD_Tim3;<br />window_right.period_time = PERIOD_TIME_LED;<br /><br />ground1.pwm_max = 200;<br />ground1.timer_set = 750;<br />ground1.flag = TRUE;<br /><br />ground2.pwm_max = 255;<br />ground2.timer_set = 117;<br />ground2.flag = TRUE;<br /><br /><br /><br />DDRA |= (1&lt;&lt;PA7);// ustawiamy kierunek linii podświetlenia LCD jako WYJŚCIE<br />PORTA |= (1&lt;&lt;PA7);// załączamy podświetlenie LCD - stan wysoki<br /><br />d_led_init();//ustawienie portów z podłączonymi LEDami<br />timer2_init();//ustawienie Timera2<br />lcd_init();/* inicjalizacja LCD */<br />ir_init();/* inicjalizacja dekodowania IR */<br /><br />sei();/* włączamy globalne przerwania */<br /><br /><br />lcd_locate(0,0);<br />lcd_str(&quot;    &quot;);<br />lcd_locate(0,0);<br />lcd_int(window_left.timer_set);<br /><br />lcd_locate(0,4);<br />lcd_str(&quot;       &quot;);<br />lcd_locate(0,4);<br />lcd_long(window_left.period_time);<br /><br /><br />selected_led = ground1;<br /><br /><br /><br />/* pętla nieskończona */<br />while(1)<br />{<br /><br />control_leds(&amp;ground1,gamma_correctionR);<br />control_leds(&amp;ground2, gamma_correctionR);<br /><br />//**************************************************************//<br />////<br />//****Fragment kodu wywołujący funkcję sterujące diodami RGB****//<br />////<br />//**************************************************************//<br />//**Dioda w kominie**//<br />ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { temp = chimney.LED_timer; }<br />if(!temp){<br />if(chimney.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb(&amp;chimney);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(chimney.chosen_function == 2){<br />flow_colors_rgb (&amp;chimney);//cykliczna zmiana pomiędzy kolorami<br />}<br /> ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br /> chimney.LED_timer=chimney.timer_set;<br /> }<br />}<br />//**Dioda w lewym oknie**//<br />ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { temp = window_left.LED_timer; }<br />if(!temp){<br />if(window_left.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb(&amp;window_left);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(window_left.chosen_function == 2){<br /> flow_colors_rgb (&amp;window_left);//cykliczna zmiana pomiędzy kolorami<br />}<br /> ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br /> window_left.LED_timer=window_left.timer_set;<br /> }<br />}<br />//**Dioda w prawym oknie**//<br />ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { temp = window_right.LED_timer; }<br />if(!temp){<br />if(window_right.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb(&amp;window_right);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(window_right.chosen_function == 2){<br />flow_colors_rgb (&amp;window_right);//cykliczna zmiana pomiędzy kolorami<br />}<br />ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br />window_right.LED_timer=window_right.timer_set;<br />}<br />}<br /><br />//<br />//if(!Timer4){<br />//PORT(LED4_3PORT) ^= (1&lt;&lt;LED4_3);<br />//selected_rgb.pwm_max += 10;<br />//lcd_locate(1,5);<br />//lcd_str(&quot;   &quot;);<br />//lcd_locate(1,5);<br />//lcd_int(selected_rgb.pwm_max);<br />//Timer4 = 10000;<br />//}<br /><br /><br /><br />/* ****** ZDARZENIE Z ODBIORNIKA PODCZERWIENI ********** */<br />if(Ir_key_press_flag) {/* jeśli odebrano prawidłowe kody z pilota */<br /><br /><br />lcd_locate(0,12);<br />lcd_str(&quot;   &quot;);<br />lcd_locate(0,12);<br />lcd_int(command);<br /><br />lcd_locate(0,0);<br />lcd_str(&quot;    &quot;);<br />lcd_locate(0,0);<br />lcd_int(chimney.timer_set);<br /><br />lcd_locate(0,4);<br />lcd_str(&quot;       &quot;);<br />lcd_locate(0,4);<br />lcd_long(chimney.period_time);<br /><br />lcd_locate(1,0);<br />lcd_str(&quot;    &quot;);<br />lcd_locate(1,0);<br />lcd_int(window_left.timer_set);<br /><br />lcd_locate(1,4);<br />lcd_str(&quot;       &quot;);<br />lcd_locate(1,4);<br />lcd_long(window_left.period_time);<br /><br /><br />if(chose_led&#91;set_chosen_led&#93; != 1)//wybranie diody do obróbki<br />{<br />switch (command)//na podstawie kodu klawisza wybierana jest dioda do obróbki<br />{<br />case 0:<br />;<br />break;<br />case 1://wybór diody RGB umieszczonej w kominie<br />chose_led&#91;chosen_led&#93; = 1;//do obróbki została wybrana dioda w kominie<br />blink_selected_led (&amp;chimney);<br />break;<br />case 2:<br />chose_led&#91;chosen_led&#93; = 2;//do obróbki została wybrana dioda w lewym oknie<br />blink_selected_led (&amp;window_left);<br />break;<br />case 3:<br />chose_led&#91;chosen_led&#93; = 3;//do obróbki została wybrana dioda w prawym oknie<br />blink_selected_led (&amp;window_right);<br />break;<br />case 4:<br />;<br />break;<br />case 5:<br />;<br />break;<br />case 6:<br />;<br />break;<br />case 7:<br />;<br />break;<br />case 8:<br />;<br />break;<br />case 9:<br />;<br />break;<br /><br />case SUBMIT://wciśnięty został klawisz OK zatwierdzający wybór<br />chose_led&#91;set_chosen_led&#93; = 1;//zapobiegnięcie ponownemu wejściu instrujcję wyboru diody do obróbki<br /><br />//Zatwierdzenie wyboru diody sygnalizowane jest jej mrógnięciem//<br />switch(chose_led&#91;chosen_led&#93;){<br />case 1:<br />blink_selected_led (&amp;chimney);<br />break;<br /><br />case 2:<br />blink_selected_led (&amp;window_left);<br />break;<br /><br />case 3:<br />blink_selected_led (&amp;window_right);<br />break;<br /><br />}<br />break;<br />default: /* instrukcje, jeśli żaden z wcześniejszych warunków nie został spełniony */<br />;<br />break;<br />}//switch (command)<br />}//chose_led&#91;1&#93; != 1)<br /><br />/*kasowanie zatwierdzenia wybrania diody*/<br />if(chose_led &#91;set_chosen_led&#93; == 1 &amp;&amp; command == RESET){ //RESET - klawisz &quot;help&quot;<br /><br />switch(chose_led&#91;chosen_led&#93;){//Zatwierdzenie skasowania wyboru diody sygnalizowane jest jej mrugnięciem<br />case 1:<br />blink_selected_led (&amp;chimney);<br />break;<br /><br />case 2:<br />blink_selected_led (&amp;window_left);<br />break;<br /><br />case 3:<br />blink_selected_led (&amp;window_right);<br />break;<br /><br />}<br />chose_led&#91;set_chosen_led&#93; = 0; // skosowanie zatwierdzenia wybrania diody do obróbki<br />}<br /><br />/*Dla wybranej diody;<br /> * -  przypisujemy funkcję, która nią steruje<br /> * - sterujemy jej: jasnością, nasycenem barw i szybkością zmian kolorów<br /> * -  zapisujemy całą strukture diody na stosie */<br />if(chose_led&#91;set_chosen_led&#93; == 1 ){<br />if(chose_led&#91;chosen_led&#93; == 1) {//Jeżeli zostałą wybrana dioda w kominie (dioda 1). command == &lt;1,2&gt; mówi nam o ilości funkcji do wyboru<br /><br /><br />//lcd_locate(0,0);<br />//lcd_str(&quot;    &quot;);<br />//lcd_locate(0,0);<br />//lcd_int(window_left.timer_set);<br />//<br />//lcd_locate(0,4);<br />//lcd_str(&quot;       &quot;);<br />//lcd_locate(0,4);<br />//lcd_long(window_left.period_time);<br /><br />//lcd_locate(0,0);<br />//lcd_str(&quot;    &quot;);<br />//lcd_locate(0,0);<br />//lcd_int(chimney.timer_set);<br />//<br />//lcd_locate(0,4);<br />//lcd_str(&quot;       &quot;);<br />//lcd_locate(0,4);<br />//lcd_long(chimney.period_time);<br /><br />//lcd_locate(0,8);<br />//lcd_str(&quot;   &quot;);<br />//lcd_locate(0,8);<br />//lcd_int(chimney.saturation_max);<br /><br />lcd_locate(1,12);<br />lcd_str(&quot;   &quot;);<br />lcd_locate(1,12);<br />lcd_int(chose_led&#91;chosen_led&#93;);<br /><br />//<br />//lcd_locate(0,4);<br />//lcd_str(&quot;    &quot;);<br />//lcd_locate(0,4);<br />//lcd_int(chimney.LED_timer);<br /><br />//lcd_locate(0,8);<br />//lcd_str(&quot;    &quot;);<br />//lcd_locate(0,8);<br />//lcd_int(*new_value_max);<br /><br />//lcd_locate(0,12);<br />//lcd_str(&quot;   &quot;);<br />//lcd_locate(0,12);<br />//lcd_int(chimney.saturation_max);<br /><br /><br />//lcd_locate(1,0);<br />//lcd_str(&quot;   &quot;);<br />//lcd_locate(1,0);<br />//lcd_int(chose_led&#91;set_chosen_led&#93;);<br /><br /><br /><br /><br /><br />change_paramiters_diode_rgb(&amp;chimney, command, chose_led&#91;chosen_led&#93;);<br />selected_rgb = chimney;//na potrzeby testów<br />}<br />if(chose_led&#91;chosen_led&#93; == 2){//Jeżeli zostałą wybrana dioda w lewym oknie (dioda 2)<br />change_paramiters_diode_rgb(&amp;window_left, command, chose_led&#91;chosen_led&#93;);<br />//selected_rgb = window_left;//na potrzeby testów<br />}<br />if(chose_led&#91;chosen_led&#93; == 3){//Jeżeli zostałą wybrana dioda w lewym oknie (dioda 2)<br />change_paramiters_diode_rgb(&amp;window_right, command, chose_led&#91;chosen_led&#93;);<br />//selected_rgb = window_right;//na potrzeby testów<br />}<br />}<br /><br />//lcd_locate(1,0);<br />//lcd_str(&quot;   &quot;);<br />//lcd_locate(1,0);<br />//lcd_int(chose_led&#91;set_chosen_led&#93;);<br />//<br />//lcd_locate(0,4);<br />//lcd_str(&quot;           &quot;);<br />//lcd_locate(0,4);<br />//lcd_int(selected_rgb.LED_timer);<br />//<br />//<br />//lcd_locate(0,0);<br />//lcd_str(&quot;    &quot;);<br />//lcd_locate(0,0);<br />//lcd_int(selected_rgb.timer_set);<br />//<br />//lcd_locate(0,12);<br />//lcd_str(&quot;   &quot;);<br />//lcd_locate(0,12);<br />//lcd_int(selected_rgb.saturation_max);<br />//<br />//lcd_locate(1,5);<br />//lcd_str(&quot;   &quot;);<br />//lcd_locate(1,5);<br />//lcd_int(selected_rgb.value_max);<br /><br /><br /><br />/* wyzerowanie flagi odbioru oraz wartości odebranych kodów */<br />Ir_key_press_flag=0;<br />command=0xff;<br />address=0xff;<br /><br />}<br /><br />hsv_to_rgb(&amp;chimney, gamma_correctionR, gamma_correctionR, gamma_correctionR);<br />hsv_to_rgb(&amp;window_left, gamma_correctionR, gamma_correctionR, gamma_correctionR);<br />hsv_to_rgb(&amp;window_right, gamma_correctionR, gamma_correctionR, gamma_correctionR);<br /><br />}<br />}[/syntax]<br /><br />d_led.h<br />[syntax=c]/*<br /> * d_led.h<br /> *<br /> *  Created on: 9 lis 2016<br /> *      Author: Piotr<br /> */<br /><br />#ifndef D_LED_D_LED_H_<br />#define D_LED_D_LED_H_<br /><br />#include &quot;../MAKRAU/makrau.h&quot;<br /><br /><br />//----------------------------------------------------------------------------------------<br />//<br />//Ustawienia sprzętowe połączeń LEDów z mikrokontrolerem<br />//<br />//----------------------------------------------------------------------------------------<br />// tu konfigurujemy port i piny do jakich podłączymy diody<br />//**** dioda RGB w koninie ****//<br />#define LED1_RPORT  C<br />#define LED1_R 0<br />#define LED1_GPORT  C<br />#define LED1_G 1<br />#define LED1_BPORT  C<br />#define LED1_B 2<br /><br />//**** dioda RGB w lewym oknie ****//<br />#define LED2_RPORT  B<br />#define LED2_R 0<br />#define LED2_GPORT  B<br />#define LED2_G 1<br />#define LED2_BPORT  B<br />#define LED2_B 2<br />//<br />//**** dioda RGB w prawym oknie ****//<br />#define LED3_RPORT  C<br />#define LED3_R 3<br />#define LED3_GPORT  C<br />#define LED3_G 4<br />#define LED3_BPORT  C<br />#define LED3_B 5<br /><br />//**** diody przed domkiem ****//<br />#define LED4_1PORT  C<br />#define LED4_1 6<br />#define LED4_2PORT  C<br />#define LED4_2 7<br />#define LED4_3PORT  D<br />#define LED4_3 0<br />#define LED4_4PORT  D<br />#define LED4_4 1<br />#define LED4_5PORT  D<br />#define LED4_5 2<br /><br />#define TRUE 1<br />#define FALSE 0<br /><br />#define PERIOD_TIME_LED 1500000//czas rozjaśniania i ściemniania diody w us<br />#define MAX_GAMMA255//maksymalny rozmiar tablicy korekcji gamma<br />#define TIMER_PWM_SET 50//podstawa czasowa timera sprzętowego w us<br /><br />//****Wartości dla poszczególnych kolorów w przesrzeni HSV****//<br />#define RED 0<br />#define ORANGE 17<br />#define YELLOW 32<br />#define GREEN 85<br />#define AQUA 128<br />#define BLUE 171<br />#define MAGENTA 214<br /><br />#define ON_OFF  12<br />#define BRIGHTNES_UP  16<br />#define BRIGHTNES_DOWN  17<br />#define TIMER_SLOW  21<br />#defineTIMER_FAST  22<br />#define COLORS_UP  19<br />#define COLORS_DOWN  56<br />#define SUBMIT  23<br />#defineSATURATION_UP 32<br />#define SATURATION_DOWN  33<br />#define RESET  19<br />#define COPY_SETINGS_RGB 43<br /><br />uint8_t *new_value_max; //wskaźnik umożliwiający przekaznie nowej maksymalnej wartości pwm (maksymalnego rozświetlania) wybranej diody; zwraca go funkcja set_flashing_time<br />//uint16_t *new_time_set;<br />//uint32_t *new_period_time;// wskaźnik umożliwiający przekazanie nowej wartości długości czasu rozświetlania i ściemniania diody<br /><br /><br /><br /><br />//Makrodefinicja wyliczające rozmiar dowolnej tablicy<br />#define SIZE_TAB(x) ((sizeof(x)/sizeof(uint8_t))-2)<br /><br /><br /><br />enum {R,G,B,H,S,V}; //Tablica typu enum z nazwwami i numerami poszczególnych zmiennych R=0, G=1, B=2, H=3, S=4, V=5<br /><br />enum{KEY_0 = 0, KEY_1 = 1, KEY_2 = 2, KEY_3 = 3, KEY_4 = 4, KEY_5 = 5, KEY_6 = 6, KEY_7 = 7, KEY_8 = 8, KEY_9 = 9};<br />enum {chosen_led, set_chosen_led, chosen_function};<br />enum {chimney_rgb = 1, window_left_rgb, window_right_rgb};<br /><br /><br />//deklaracja struktury typu TLED_RGB<br />typedef struct {<br />uint8_t color&#91;6&#93;;//wartość PWM diod RGB: R=0, G=1, B=2, H=3, S=4, V=5<br />volatile uint16_t timer_set;//zapamiętany czas rozświetlania i ściemniania diody RGB, ładowany do licznika LED_timer<br />volatile uint16_t LED_timer;//czas odliczany w przerwaniu<br />volatile uint32_t period_time;//zmienna za pomocą której ustawiamy nowy czas szybkości rozświetlania i ściemniania diody<br />uint8_t chosen_function;//zmienna informująca o wybranej funkcji do sterowania ledem<br />volatile uint8_t value_max;//zmienna odpowiedzialna za maksymalny strumień świetlny<br />volatile uint8_t saturation_max;//zmienna odpowiadajaca za maksymalne nasycenie kolorów<br />} TLED_RGB;<br /><br />TLED_RGB chimney, window_left, window_right, selected_rgb;// deklaracja DIOD RGB typu TLED_RGB<br /><br /><br /><br />//deklaracja struktury typu TLED<br />typedef struct {<br />volatile uint8_t pwm_max; // maksymalna wartość sygnału PWM (0-255)<br />volatile uint8_t LED_pwm;//wartość PWM diody<br />volatile uint16_t timer_set;//zapamiętany czas rozświetlania i ściemniania diody<br />volatile uint16_t LED_timer;//czas rozświetlania i ściemniania diody<br />uint8_t flag;//flaga informująca o narastaniu strumienia świetlnego<br />uint8_t i;//zmienna odpowiedzialna za wybór elementu tablicy korekty gamma<br />} TLED;<br /><br />TLED ground1, ground2, tree1, selected_led;// deklaracja DIODY TLED<br /><br /><br />// definicje zmiennych do sterowania 8 kanałami programowych PWM<br />// zmienne typu uint8_t, rozdzielczość 8-bitowa<br /><br />volatile uint16_t Timer1, Timer2, Timer3,Timer4, Timer5;// timery programowe<br /><br /><br />//------------------------------------------------  koniec ustawień sprzętowych ---------------<br /><br />void d_led_init (void); //ustawienia pinów uP i LEDow<br />void timer2_init(void);// ustawienie Timera2<br />void control_leds (TLED *SLED, const uint8_t *gamma ); // funkcja obsługi pojedynczego LEDa<br />void set_flashing_led (uint8_t command, TLED *SLED);//****funkcja usttawiająca parametry świecenia pojedynczego LEDa****//<br />void hsv_to_rgb (TLED_RGB *myrgb, const uint8_t *gamma_r, const uint8_t *gamma_g, const uint8_t *gamma_b);//funkxja skalująca kolory HSV na RGB<br />void select_set_colors_rgb (TLED_RGB *sel_rgb);//funkcja zmieniająca kolory zgodnie z zadeklarowaną tablicą<br /><br /><br />uint8_t set_max_brightness (uint8_t command, uint8_t value_max, uint32_t period_time_led);//****funkcja ustawiająca maksymalne natężenie jasności diody oraz rozświetlania i ściemniania****//<br />uint16_t time_change (uint8_t command, uint8_t value_max, uint32_t period_time );// funkcja umożliwiająca zmianę czasu rozjaśniania i ściemniania diody<br />uint8_t set_max_saturation (uint8_t command, uint8_t saturation);//funkcja zwracająca maksymalne nasycenie kolorów<br />void flow_colors_rgb (TLED_RGB *sel_rgb);//Funkcja cyklicznie zmieniająca kolory<br />void blink_selected_led (TLED_RGB *led_rgb); //funkcja mrugnąca wybraną diodą<br /><br />void change_paramiters_diode_rgb(TLED_RGB *diode_rgb, uint8_t command, uint8_t chose_led);//funkcja zmieniająca parametry wybranej diody rgb<br />uint16_t set_new_time_set(uint8_t max_value, uint32_t period_time);//funkcja wyznaczająca nowy czas czas do odliczania w przerwaniu dla dowolnej diody<br /><br />#endif /* D_LED_D_LED_H_ */[/syntax]<br /><br />d_led.c<br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 9 lis 2016<br /> *       Autor: Piotr Łączny<br /> */<br />#include &lt;avr/io.h&gt;//dołączenie głównego systemowego pliku nagłówkowego<br />#include &lt;avr/interrupt.h&gt;//dołączenie pliku nagłówkowego do obsługi przerwań<br />#include &lt;avr/pgmspace.h&gt;//dołączenie pliku nagłówkowego do obsługi pamięci FLASH??<br /><br />#include &quot;d_led.h&quot;<br />#include &quot;../MAKRAU/makrau.h&quot;<br />#include &quot;../gamma_CORRECTION/gamma.h&quot;<br />#include &quot;../LCD/lcd44780.h&quot;<br /><br /><br /><br />// definicje zmiennych do sterowania 6 kanałami programowych PWM<br />// zmienne typu uint8_t, rozdzielczość 8-bitowa<br />//volatile uint8_t LED1_color&#91;R&#93;, LED1_color&#91;G&#93;, LED1_color&#91;B&#93;, LED2_color&#91;R&#93;, LED2_color&#91;G&#93;, LED2_color&#91;B&#93;, LED3_color&#91;R&#93;, LED3_color&#91;G&#93;, LED3_color&#91;B&#93;;//programowe wyjścia PWM diod RGB<br />//volatile uint8_t pwm4, pwm5, pwm6, pwm7, pwm8;//programowe wyjścia PWM<br /><br />//----------------------------------------------------------------------------------------<br />//<br />// ******* INICJALIZACJA LEDÓW ********<br />//<br />//----------------------------------------------------------------------------------------<br />void d_led_init(void)<br />{<br /><br />// **** ustawienie pinów kanałów programowych PWM jako WYJŚCIA **** //<br />//** dioda RGB w kominie **//<br />DDR(LED1_RPORT) |= (1&lt;&lt;LED1_R);<br />DDR(LED1_GPORT) |= (1&lt;&lt;LED1_G);<br />DDR(LED1_BPORT) |= (1&lt;&lt;LED1_B);<br /><br />////** dioda RGB w lewym oknie **//<br />DDR(LED2_RPORT) |= (1&lt;&lt;LED2_R);<br />DDR(LED2_GPORT) |= (1&lt;&lt;LED2_G);<br />DDR(LED2_BPORT) |= (1&lt;&lt;LED2_B);<br />//<br />////** dioda RGB w prawym oknie **//<br />DDR(LED3_RPORT) |= (1&lt;&lt;LED3_R);<br />DDR(LED3_GPORT) |= (1&lt;&lt;LED3_G);<br />DDR(LED3_BPORT) |= (1&lt;&lt;LED3_B);<br /><br />//** diody przed domkiem **//<br />DDR(LED4_1PORT) |= (1&lt;&lt;LED4_1);<br />DDR(LED4_2PORT) |= (1&lt;&lt;LED4_2);<br />DDR(LED4_3PORT) |= (1&lt;&lt;LED4_3);<br />DDR(LED4_4PORT) |= (1&lt;&lt;LED4_4);<br />DDR(LED4_5PORT) |= (1&lt;&lt;LED4_5);<br /><br />// **** wyłączenie diod LED podłączonych katodami do wyjść **** //<br />//** dioda RGB w kominie **//<br />PORT(LED1_RPORT) |= (1&lt;&lt;LED1_R);<br />PORT(LED1_GPORT) |= (1&lt;&lt;LED1_G);<br />PORT(LED1_BPORT) |= (1&lt;&lt;LED1_B);<br /><br />//// ** dioda RGB w lewym oknie ** //<br />PORT(LED2_RPORT) |= (1&lt;&lt;LED2_R);<br />PORT(LED2_GPORT) |= (1&lt;&lt;LED2_G);<br />PORT(LED2_BPORT) |= (1&lt;&lt;LED2_B);<br />//<br />//// ** dioda RGB w lprawym oknie ** //<br />PORT(LED3_RPORT) |= (1&lt;&lt;LED3_R);<br />PORT(LED3_GPORT) |= (1&lt;&lt;LED3_G);<br />PORT(LED3_BPORT) |= (1&lt;&lt;LED3_B);<br /><br />// ** diody przed domkiem ** //<br />PORT(LED4_1PORT) |= (1&lt;&lt;LED4_1);<br />PORT(LED4_2PORT) |= (1&lt;&lt;LED4_2);<br />PORT(LED4_3PORT) |= (1&lt;&lt;LED4_3);<br />PORT(LED4_4PORT) |= (1&lt;&lt;LED4_4);<br />PORT(LED4_5PORT) |= (1&lt;&lt;LED4_5);<br /><br /><br />}<br /><br /><br />//----------------------------------------------------------------------------------------<br />//<br />// ******* INICJALIZACJA TIMERA2 ********<br />//<br />//----------------------------------------------------------------------------------------<br />void timer2_init(void)<br />{<br /><br />// ustawienia TIMER2 w tryb CTC<br />TCCR2 |= (1&lt;&lt;WGM21);// tryb  CTC<br />TCCR2 |=(1&lt;&lt;CS22);// preskaler = 64  //(1&lt;&lt;CS21);// preskaler = 8<br />OCR2 = 12;// dodatkowy podział częsttotliwości przez 50 (przerwanie co 50us) //// dodatkowy podział częsttotliwości przez 50 (przerwanie co 50us)<br />TIMSK |= (1&lt;&lt;OCIE2);// zezwolenie na przerwanie CompareMatch<br />}<br /><br />//----------------------------------------------------------------------------------------<br />//<br />// *******FUNKCJE DIOD RGB********<br />//<br />//----------------------------------------------------------------------------------------<br /><br />//----------------------------------------------------------------------------------------<br />//<br />// ******* SKALOWANIE HSV NA RGB ********<br />//<br />//H:0-255, 0=R, 42=Yellow, 85= GREEN, 128=Aqua, 171=Blue, 214=Magenta<br />//S:0-255, 0 = tylko biała barwa, 255 = pełne kolory<br />//V: 0-255, 0 = brak światła, 255 = maksymalna jasność<br />//<br />//----------------------------------------------------------------------------------------<br />void hsv_to_rgb (TLED_RGB *myrgb, const uint8_t *gamma_r, const uint8_t *gamma_g, const uint8_t *gamma_b){//funkxja skalująca kolory HSV na RGB<br />uint16_t region, remainder, p, q, t;<br />if (myrgb-&gt;color&#91;S&#93;==0){<br />myrgb-&gt;color&#91;R&#93; = pgm_read_byte(&amp;gamma_r&#91;(myrgb-&gt;color&#91;V&#93;)&#93;);<br />myrgb-&gt;color&#91;G&#93; = pgm_read_byte(&amp;gamma_g&#91;(myrgb-&gt;color&#91;V&#93;)&#93;);<br />myrgb-&gt;color&#91;B&#93; = pgm_read_byte(&amp;gamma_b&#91;(myrgb-&gt;color&#91;V&#93;)&#93;);<br />}//(myrgb-&gt;color&#91;S&#93;==0)<br />else {<br />region =myrgb-&gt;color&#91;H&#93;*6/256;<br />remainder =(myrgb-&gt;color&#91;H&#93;*6)%256;<br /><br />p = (myrgb-&gt;color&#91;V&#93; *(255 - myrgb-&gt;color&#91;S&#93;))/256;<br />q = (myrgb-&gt;color&#91;V&#93; *(255 - (myrgb-&gt;color&#91;S&#93; * remainder) / 256)) / 256;<br />t = (myrgb-&gt;color&#91;V&#93; *(255 - (myrgb-&gt;color&#91;S&#93; * (255 - remainder)) / 256)) / 256;<br /><br />switch (region) {<br />case 0:<br />myrgb-&gt;color&#91;R&#93; = pgm_read_byte(&amp;gamma_r&#91;(myrgb-&gt;color&#91;V&#93;)&#93;);myrgb-&gt;color&#91;G&#93; = pgm_read_byte(&amp;gamma_g&#91;t&#93;);myrgb-&gt;color&#91;B&#93; = pgm_read_byte(&amp;gamma_b&#91;p&#93;);<br />break;<br />case 1:<br />myrgb-&gt;color&#91;R&#93; = pgm_read_byte(&amp;gamma_r&#91;q&#93;); myrgb-&gt;color&#91;G&#93; = pgm_read_byte(&amp;gamma_g&#91;(myrgb-&gt;color&#91;V&#93;)&#93;); myrgb-&gt;color&#91;B&#93; = pgm_read_byte(&amp;gamma_b&#91;p&#93;);<br />break;<br />case 2:<br />myrgb-&gt;color&#91;R&#93; = pgm_read_byte(&amp;gamma_r&#91;p&#93;);myrgb-&gt;color&#91;G&#93; = pgm_read_byte(&amp;gamma_g&#91;(myrgb-&gt;color&#91;V&#93;)&#93;); myrgb-&gt;color&#91;B&#93; = pgm_read_byte(&amp;gamma_b&#91;t&#93;);<br />break;<br />case 3:<br />myrgb-&gt;color&#91;R&#93; = pgm_read_byte(&amp;gamma_r&#91;p&#93;); myrgb-&gt;color&#91;G&#93; = pgm_read_byte(&amp;gamma_g&#91;q&#93;); myrgb-&gt;color&#91;B&#93; = pgm_read_byte(&amp;gamma_b&#91;(myrgb-&gt;color&#91;V&#93;)&#93;);<br />break;<br />case 4:<br />myrgb-&gt;color&#91;R&#93; = pgm_read_byte(&amp;gamma_r&#91;t&#93;); myrgb-&gt;color&#91;G&#93; = pgm_read_byte(&amp;gamma_g&#91;p&#93;); myrgb-&gt;color&#91;B&#93; = pgm_read_byte(&amp;gamma_b&#91;(myrgb-&gt;color&#91;V&#93;)&#93;);<br />break;<br />case 5:<br />myrgb-&gt;color&#91;R&#93; = pgm_read_byte(&amp;gamma_r&#91;(myrgb-&gt;color&#91;V&#93;)&#93;);myrgb-&gt;color&#91;G&#93; = pgm_read_byte(&amp;gamma_g&#91;p&#93;); myrgb-&gt;color&#91;B&#93; = pgm_read_byte(&amp;gamma_b&#91;q&#93;);<br />break;<br />}// (region)<br />}//else<br />}<br /><br />//****Funkcja mrugająca wybraną diodą RGB****//<br />void blink_selected_led(TLED_RGB *led_rgb){<br />led_rgb-&gt;color&#91;S&#93;= 0;<br />led_rgb-&gt;color&#91;V&#93;= 255;<br />led_rgb-&gt;LED_timer = 200;<br />}<br /><br /><br /><br />//****Funkcja zmieniająca kolory diody RGB zgodnie z zadeklarowaną tablicą COLOR****//<br />void select_set_colors_rgb (TLED_RGB *sel_rgb){<br /><br />uint8_t COLORS&#91;&#93;={RED, ORANGE, YELLOW ,GREEN, AQUA, BLUE, MAGENTA };//<br />static uint8_t select_color = 0, flaga_rgb = 0, i = 0;<br /><br />if (!flaga_rgb){<br />if(i&gt;=sel_rgb-&gt;value_max)<br />{<br />flaga_rgb = 1;<br />i = sel_rgb-&gt;value_max;<br />sel_rgb-&gt;color&#91;V&#93;=i;<br />sel_rgb-&gt;color&#91;S&#93; = sel_rgb-&gt;saturation_max;<br />}//(i&gt;=sel_rgb-&gt;pwm_max)<br />else<br />{<br />sel_rgb-&gt;color&#91;H&#93;=COLORS&#91;select_color&#93;;<br />sel_rgb-&gt;color&#91;V&#93;=i;<br />sel_rgb-&gt;color&#91;S&#93; = sel_rgb-&gt;saturation_max;<br />i ++;<br />}//else<br /><br />}//(!flaga_rgb)<br />else{<br />if(i==0){<br />flaga_rgb = 0;<br />if (select_color &lt;= SIZE_TAB(COLORS))select_color ++;<br />else select_color =0 ;<br />}//if(i==0)<br />else<br />{<br />sel_rgb-&gt;color&#91;V&#93;=i;<br />i--;<br />}//else<br />}//else<br />}<br /><br />//****Funkcja cyklicznie zmieniająca kolory****//<br />void flow_colors_rgb (TLED_RGB *sel_rgb){<br /><br />static uint8_t i_h = 0;<br />sel_rgb-&gt;color&#91;H&#93; = i_h;<br />sel_rgb-&gt;color&#91;S&#93; = sel_rgb-&gt;saturation_max;<br />sel_rgb-&gt;color&#91;V&#93; = sel_rgb-&gt;value_max;<br />i_h += 1;<br />}<br /><br /><br />//****funkcja zmieniająca parametry wybranej diody rgb****//<br />void change_paramiters_diode_rgb(TLED_RGB *diode_rgb, uint8_t command, uint8_t chose_led ){<br />switch(command){<br />case KEY_1:<br />diode_rgb-&gt;chosen_function = 1;<br />break;<br /><br />case KEY_2:<br />diode_rgb-&gt;chosen_function = 2;<br />break;<br /><br />case BRIGHTNES_UP:<br />if(diode_rgb-&gt;value_max &gt; 245) diode_rgb-&gt;value_max = 255;<br />else diode_rgb-&gt;value_max += 10;<br />diode_rgb-&gt;timer_set = set_new_time_set(diode_rgb-&gt;value_max,diode_rgb-&gt;period_time);<br />break;<br /><br />case BRIGHTNES_DOWN:<br />if(diode_rgb-&gt;value_max &lt;10 ) diode_rgb-&gt;value_max = 0;<br />else diode_rgb-&gt;value_max -= 10;<br />diode_rgb-&gt;timer_set = set_new_time_set(diode_rgb-&gt;value_max,diode_rgb-&gt;period_time);<br />break;<br /><br />case TIMER_FAST:<br />if(diode_rgb-&gt;period_time&gt;= PERIOD_TIME_LED) diode_rgb-&gt;period_time  = PERIOD_TIME_LED; //sprawdzenie czy nasze wypełnienie jest więsze od 245 i czy został ponownie wciśnięty klawisz zwiększania<br />else diode_rgb-&gt;period_time +=15000;<br />diode_rgb-&gt;timer_set = set_new_time_set(diode_rgb-&gt;value_max,diode_rgb-&gt;period_time);<br />break;<br /><br />case TIMER_SLOW:<br />if(diode_rgb-&gt;period_time &lt;= 15000) diode_rgb-&gt;period_time = 1;<br />else diode_rgb-&gt;period_time -= 15000;<br />diode_rgb-&gt;timer_set = set_new_time_set(diode_rgb-&gt;value_max,diode_rgb-&gt;period_time);<br />break;<br /><br />case SATURATION_UP:<br />if(diode_rgb-&gt;saturation_max != 255)diode_rgb-&gt;saturation_max += 5;<br />break;<br /><br />case SATURATION_DOWN:<br />if(diode_rgb-&gt;saturation_max)diode_rgb-&gt;saturation_max -= 5;<br />break;<br /><br />//case COPY_SETINGS_RGB://kopiowanie ustawiń wybranej diody do pozostałych diod RGB<br />//PORT(LED4_3PORT) ^= (1&lt;&lt;LED4_3);<br />//<br />//switch(chose_led){<br />//<br />//case chimney_rgb:<br />//<br />////lcd_locate(0,0);<br />////lcd_str(&quot;    &quot;);<br />////lcd_locate(0,0);<br />////lcd_int(window_left.timer_set);<br />////<br />////lcd_locate(0,4);<br />////lcd_str(&quot;       &quot;);<br />////lcd_locate(0,4);<br />////lcd_long(window_left.period_time);<br />//<br />//<br />////<br />////window_left.chosen_function = chimney.chosen_function;<br />////window_left.color&#91;H&#93; = chimney.color&#91;H&#93;;<br />////window_left.color&#91;S&#93; = chimney.color&#91;S&#93;;<br />////window_left.color&#91;V&#93; = chimney.color&#91;V&#93;;<br />////window_left.saturation_max = chimney.saturation_max;<br />////window_left.value_max = chimney.value_max;<br />////window_left.timer_set = chimney.timer_set;<br />//<br />//<br />//window_left = chimney;//*diode_rgb;<br />////window_left = chimney;<br />//<br />//<br />////PORT(LED4_3PORT) ^= (1&lt;&lt;LED4_3);<br />//<br />////lcd_locate(1,0);<br />////lcd_str(&quot;    &quot;);<br />////lcd_locate(1,0);<br />////lcd_int(window_left.timer_set);<br />////<br />////lcd_locate(1,4);<br />////lcd_str(&quot;       &quot;);<br />////lcd_locate(1,4);<br />////lcd_long(window_left.period_time);<br />//<br />////lcd_locate(1,8);<br />////lcd_str(&quot;   &quot;);<br />////lcd_locate(1,8);<br />////lcd_int(window_right.saturation_max);<br />//<br />//<br />////lcd_locate(0,0);<br />////lcd_str(&quot;    &quot;);<br />////lcd_locate(0,0);<br />////lcd_int(window_right.timer_set);<br />////<br />////lcd_locate(0,4);<br />////lcd_str(&quot;           &quot;);<br />////lcd_locate(0,4);<br />////lcd_int(window_right.LED_timer);<br />////<br />////lcd_locate(0,8);<br />////lcd_str(&quot;    &quot;);<br />////lcd_locate(0,8);<br />////lcd_int(*new_value_max);<br />////<br />////lcd_locate(0,12);<br />////lcd_str(&quot;   &quot;);<br />////lcd_locate(0,12);<br />////lcd_int(window_right.saturation_max);<br />////<br />////if (!*new_value_max){<br />////lcd_locate(1,0);<br />////lcd_str(&quot;   &quot;);<br />////lcd_locate(1,0);<br />////lcd_int(chose_led);<br />////<br />////lcd_locate(1,5);<br />////lcd_str(&quot;   &quot;);<br />////lcd_locate(1,5);<br />////lcd_int(window_right.value_max);<br />////}<br />//<br />//break;<br />//<br />//case window_left_rgb:<br />//chimney = window_left ;<br />//window_right = window_left ;<br />//break;<br />//<br />//case window_right_rgb:<br />//chimney =  window_right ;<br />//window_left = window_right ;<br />//break;<br />//<br />//}<br />//break;<br /><br /><br />}<br /><br /><br />}<br /><br /><br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br /><br /><br />//----------------------------------------------------------------------------------------<br />//<br />// *******FUNKCJE POJEDYNCZEJ DIODY********<br />//<br />//----------------------------------------------------------------------------------------<br /><br /><br />//****funkcja automatycznie rozjaśniająca i ściemniająca diodę z uwzględnieniem ograniczenia maksymalnego rozświetlenia****//<br />void control_leds (TLED *SLED, const uint8_t *gamma)// funkcja obsługi pojedynczego LEDa<br />{<br />//pętla rozjaśniająca<br />if (!SLED-&gt;LED_timer &amp;&amp; SLED-&gt;flag)<br />{<br />if(SLED-&gt;i &lt; SLED-&gt;pwm_max){//sprawdzenie czy został osiągnięty maksymelny strumień świetlny<br />SLED-&gt;i++;//zwiększenie wartości współczynnika PWM<br />SLED-&gt;LED_pwm=(pgm_read_byte(&amp;gamma&#91;(SLED-&gt;i)&#93;));//zapisanie wartości korekcji gamma do sygnału PWM<br />}<br />else SLED-&gt;flag = FALSE;// jeżeli osiągną to zeruj flagę}<br />SLED-&gt;LED_timer = SLED-&gt;timer_set;//ponowne ustawienie okresu sygnału PWM<br />}<br /><br />// pętla stopniowo ściemniająca<br />if(!SLED-&gt;LED_timer &amp;&amp; !SLED-&gt;flag)<br />{<br />if (!SLED-&gt;i)SLED-&gt;flag = TRUE;//sprawdzenie czy &quot;i=0&quot; jeśli tak, to przejdź do rozjaśniania pętli<br />else{<br />SLED-&gt;i--;//zmniejszanie wartości współczynnika PWM<br />SLED-&gt;LED_pwm=(pgm_read_byte(&amp;gamma&#91;(SLED-&gt;i)&#93;));//zapisanie wartości korekcji gamma do sygnału PWM<br />}<br />SLED-&gt;LED_timer = SLED-&gt;timer_set;//ponowne ustawienie okresu sygnału PWM<br />}<br />}<br /><br /><br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br />//----------------------------------------------------------------------------------------<br /><br /><br />//----------------------------------------------------------------------------------------<br />//<br />// *******FUNKCJE WSPÓLNE********<br />//<br />//----------------------------------------------------------------------------------------<br /><br /><br />////****funkcja ustawiająca maksymalne natężenie jasności diody<br />////uwzględniajać założony czas rozświetlania i ścieminiania diody<br />////wynoszący PERIOD_TIME_LED****//<br />//uint8_t set_max_brightness (uint8_t command, uint8_t value_max, uint32_t period_time_led)<br />//{<br />//uint16_t temp = 0;<br />//<br />//if(command == BRIGHTNES_UP)<br />//{<br />////zwiększenie jasności świecenia diody diody<br />//if(value_max &gt; 245) value_max =255; //sprawdzenie czy nasze wypełnienie jest więsze od 245 i czy został ponownie wciśnięty klawisz zwiększania<br />//else value_max +=10;<br />//}<br />//<br />//if(command == BRIGHTNES_DOWN)//zmniejszenie jesności świecenia diody diody<br />//{<br />//if(value_max &lt; 10) value_max = 0;<br />//else value_max -= 10;<br />//}<br />//<br />//if(value_max) temp = TIMER_PWM_SET * value_max;//zapobiegnięcie dzielenia przez 0<br />//else temp =600 * TIMER_PWM_SET;//mnożenie przez 600 powoduje szybsze zgaśnięcie diody dla PWM =0<br />//temp = period_time_led / temp;<br />//<br />//*new_time_set = temp;<br />//return value_max;<br />//}<br /><br />////****funkcja ustawiająca zmianę czasu rozjaśniania i ściemniania diody****//<br />//uint16_t time_change (uint8_t command, uint8_t value_max, uint32_t period_time )<br />//{<br />//uint16_t temp = 0;<br />//<br />//if(command == TIMER_FAST)//zwiększenie jasności świecenia diody diody<br />//{<br />//if(period_time &gt;= PERIOD_TIME_LED) period_time  = PERIOD_TIME_LED; //sprawdzenie czy nasze wypełnienie jest więsze od 245 i czy został ponownie wciśnięty klawisz zwiększania<br />//else period_time +=15000;<br />//}<br />//<br />//if(command == TIMER_SLOW)//zmniejszenie jesności świecenia diody diody<br />//{<br />//if(period_time &lt;= 15000) period_time = 1;<br />//else period_time -= 15000;<br />//}<br />//<br />//if(value_max) temp = TIMER_PWM_SET * value_max;//zapobiegnięcie dzielenia przez 0<br />//else temp =600 * TIMER_PWM_SET;//mnożenie przez 600 powoduje szybsze zgaśnięcie diody dla PWM =0<br />//temp = period_time/ temp;<br />//<br />//*new_period_time = period_time;<br />//return temp;<br />//}<br /><br /><br />//****funkcja zwracająca maksymalne nasycenie kolorów****//<br />uint8_t set_max_saturation (uint8_t command, uint8_t saturation){<br /><br />if(command == SATURATION_UP &amp;&amp; saturation != 255){<br />saturation += 5;<br />}<br />if(command == SATURATION_DOWN &amp;&amp; saturation){<br />saturation -= 5;<br />}<br /><br />return saturation;<br />}<br /><br />//****funkcja wyznaczająca nowy czas czas do odliczania w przerwaniu dla dowolnej diody****//<br />uint16_t set_new_time_set(uint8_t max_value, uint32_t period_time)<br />{<br />uint16_t temp =0;<br />if(max_value) temp = TIMER_PWM_SET * max_value;//zapobiegnięcie dzielenia przez 0<br />else temp =600 * TIMER_PWM_SET;//mnożenie przez 600 powoduje szybsze zgaśnięcie diody dla PWM =0<br />return period_time / temp;<br />}<br /><br /><br /><br /><br /><br /><br />// ciało procedury obsługi przerwania Compare Match Timera2, wywoływane co 50us<br />ISR( TIMER2_COMP_vect )<br />{<br /><br />uint16_t n;// zmienna na potrzeby przerwania<br />static uint8_t cnt; // definicja naszego licznika PWM<br /><br />n = ground1.LED_timer;/* 20 kHz ground1.LED_timer - 50us*/<br />if (n) ground1.LED_timer = --n;<br /><br />n = ground2.LED_timer; /* 1000Hz ground2.LED_timer  50us*/<br />if (n) ground2.LED_timer = --n;<br /><br />n = chimney.LED_timer;/* */<br />if(n) chimney.LED_timer = --n;<br /><br />n = window_left.LED_timer;/*  */<br />if(n) window_left.LED_timer = --n;<br /><br />n = window_right.LED_timer;/*  */<br />if(n) window_right.LED_timer = --n;<br /><br />n = Timer3;/*Timer3  */<br />if(n) Timer3 = --n;<br />//n = Timer4;/*Timer3  */<br />//if(n) Timer4 = --n;<br />//n = Timer5;/*Timer3  */<br />//if(n) Timer5 = --n;<br /><br /><br />// **** BEZPOŚREDNIE STEROWANIE WYJŚCIAMI KANAŁÓW PWM **** //<br /><br />//**** dioda RGB w kominie ****//<br />if(cnt &gt;= chimney.color&#91;G&#93;) PORT(LED1_GPORT) |= (1&lt;&lt;LED1_G); else PORT(LED1_GPORT) &amp;= ~ (1&lt;&lt;LED1_G);<br />if(cnt &gt;= chimney.color&#91;R&#93;) PORT(LED1_RPORT) |= (1&lt;&lt;LED1_R); else PORT(LED1_RPORT) &amp;= ~ (1&lt;&lt;LED1_R);<br />if(cnt &gt;= chimney.color&#91;B&#93;) PORT(LED1_BPORT) |= (1&lt;&lt;LED1_B); else PORT(LED1_BPORT) &amp;= ~ (1&lt;&lt;LED1_B);<br /><br />////**** dioda RGB w lewym oknie ****//<br />if(cnt &gt;= window_left.color&#91;G&#93;) PORT(LED2_GPORT) |= (1&lt;&lt;LED2_G); else PORT(LED2_GPORT) &amp;= ~ (1&lt;&lt;LED2_G);<br />if(cnt &gt;= window_left.color&#91;R&#93;) PORT(LED2_RPORT) |= (1&lt;&lt;LED2_R); else PORT(LED2_RPORT) &amp;= ~ (1&lt;&lt;LED2_R);<br />if(cnt &gt;= window_left.color&#91;B&#93;) PORT(LED2_BPORT) |= (1&lt;&lt;LED2_B); else PORT(LED2_BPORT) &amp;= ~ (1&lt;&lt;LED2_B);<br /><br />////**** dioda RGB w prawym oknie ****//<br />if(cnt &gt;= window_right.color&#91;G&#93;) PORT(LED3_GPORT) |= (1&lt;&lt;LED3_G); else PORT(LED3_GPORT) &amp;= ~ (1&lt;&lt;LED3_G);<br />if(cnt &gt;= window_right.color&#91;R&#93;) PORT(LED3_RPORT) |= (1&lt;&lt;LED3_R); else PORT(LED3_RPORT) &amp;= ~ (1&lt;&lt;LED3_R);<br />if(cnt &gt;= window_right.color&#91;B&#93;) PORT(LED3_BPORT) |= (1&lt;&lt;LED3_B); else PORT(LED3_BPORT) &amp;= ~ (1&lt;&lt;LED3_B);<br /><br />//**** diody przed domkiem ****//<br />if(cnt &gt;= ground1.LED_pwm) PORT(LED4_1PORT) |= (1&lt;&lt;LED4_1); else PORT(LED4_1PORT) &amp;= ~ (1&lt;&lt;LED4_1);<br />if(cnt &gt;= ground2.LED_pwm) PORT(LED4_2PORT) |= (1&lt;&lt;LED4_2); else PORT(LED4_2PORT) &amp;= ~ (1&lt;&lt;LED4_2);<br /><br /><br />//if(cnt &gt;= ground5.LED_pwm) PORT(LED4_5PORT) |= (1&lt;&lt;LED4_5); else PORT(LED4_5PORT) &amp;= ~ (1&lt;&lt;LED4_5);<br /><br />//LED_DATA = data;<br />//SendSPI(data);<br /><br /><br /><br />cnt++;// zwiększanie licznika o 1<br />}[/syntax]<br /><br /><br /><br />Wczoraj pobawiłem się trochę programem i zrobiłem po trzy kopie funkcji <em>select_set_colors_rgb</em> oraz <em>flow_colors_rgb</em> (oczywiście lekko zmodyfikowałem ich nazwy) i każdą z kopi wywołuję w main.c<br />[syntax=c]//**************************************************************//<br />////<br />//****Fragment kodu wywołujący funkcję sterujące diodami RGB****//<br />////<br />//**************************************************************//<br />//**Dioda w kominie**//<br />if(!chimney.LED_timer){<br />if(chimney.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb_ch(&amp;chimney);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(chimney.chosen_function == 2){<br />flow_colors_rgb_ch (&amp;chimney);//cykliczna zmiana pomiędzy kolorami<br />}<br />chimney.LED_timer=chimney.timer_set;<br />}<br />//**Dioda w lewym oknie**//<br />if(!window_left.LED_timer){<br />if(window_left.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb_w_l(&amp;window_left);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(window_left.chosen_function == 2){<br />flow_colors_rgb_w_l (&amp;window_left);//cykliczna zmiana pomiędzy kolorami<br />}<br />window_left.LED_timer=window_left.timer_set;<br />}<br />//**Dioda w prawym oknie**//<br />if(!window_right.LED_timer){<br />if(window_right.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb_w_r(&amp;window_right);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(window_right.chosen_function == 2){<br />flow_colors_rgb_w_r (&amp;window_right);//cykliczna zmiana pomiędzy kolorami<br />}<br />window_right.LED_timer=window_right.timer_set;<br />}[/syntax]<br />Efektem tego jest poprawne działanie programu (tzn. działanie programu wg moich założeń)<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3824">amilo_pa</a> — 11 gru 2016, o 12:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2016-12-11T10:07:12+01:00</updated>
<published>2016-12-11T10:07:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177088#p177088</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177088#p177088"/>
<title type="html"><![CDATA[Re: Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177088#p177088"><![CDATA[
<div class="quotetitle">amilo_pa napisał(a):</div><div class="quotecontent"><br />Powyższe funkcje wykonywane są w programie głównym<br />[syntax=c]//**Dioda w kominie**//<br />                if(!chimney.LED_timer){<br />                        if(chimney.chosen_function == 1){//wybór funkcji wyświetlania led<br />                                select_set_colors_rgb(&amp;chimney);//rozświetlanie i ściemnianie wybranych kolorów<br />                        }<br />                        else if(chimney.chosen_function == 2){<br />                                flow_colors_rgb (&amp;chimney);//cykliczna zmiana pomiędzy kolorami<br />                        }<br />                        chimney.LED_timer=chimney.timer_set;<br />                }[/syntax]<br /></div><br />Na podstawie pokazanych fragmentów nie widać dokładnie, jak to masz zrobione, ale zwrócę uwagę, że wszelkiego rodzaju <strong><span style="color: #AA4000">dostęp do zmiennej wielobajtowej, współdzielonej pomiędzy przerwaniami a pętlą główną programu powinien odbywać się atomowo</span></strong>, czyli w pętli głównej na czas operacji porównania lub przypisania należy wyłączyć globalne zezwolenie na przerwania (np. używając makra ATOMIC_BLOCK), czyli przykładowo:<br />[syntax=c]//<br />    uint16_t tmp;<br />    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { tmp = chimney.LED_timer; }<br />    if(!tmp){<br />        if(chimney.chosen_function == 1){//wybór funkcji wyświetlania led<br />            select_set_colors_rgb(&amp;chimney);//rozświetlanie i ściemnianie wybranych kolorów<br />        }<br />        else if(chimney.chosen_function == 2){<br />            flow_colors_rgb (&amp;chimney);//cykliczna zmiana pomiędzy kolorami<br />        }<br />        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br />            chimney.LED_timer=chimney.timer_set;<br />        }<br />    }<br />// i tak samo dla pozostałych struktur[/syntax]<br /><br />Trudno ocenić na podstawie tych fragmentów, czy nie ma innych błędów, ale od tego bym zaczął, ponieważ jeśli tak nie zrobiłeś, zachowanie programu może być nieprzewidywalne.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 11 gru 2016, o 10:07</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[amilo_pa]]></name></author>
<updated>2016-12-11T11:01:03+01:00</updated>
<published>2016-12-11T00:14:35+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177081#p177081</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177081#p177081"/>
<title type="html"><![CDATA[Struktury + funkcje + przerwanie + stos = ?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17037&amp;p=177081#p177081"><![CDATA[
Witam,<br />Mam zadeklarowane cztery struktury :<br />[syntax=c]//deklaracja struktury typu TLED_RGB<br />typedef struct {<br />uint8_t color&#91;6&#93;;//wartość PWM diod RGB: R=0, G=1, B=2, H=3, S=4, V=5<br />volatile uint16_t timer_set;//zapamiętany czas rozświetlania i ściemniania diody RGB, ładowany do licznika LED_timer<br />volatile uint16_t LED_timer;//czas odliczany w przerwaniu<br />volatile uint32_t period_time;//zmienna za pomocą której ustawiamy nowy czas szybkości rozświetlania i ściemniania diody<br />uint8_t chosen_function;//zmienna informująca o wybranej funkcji do sterowania ledem<br />volatile uint8_t value_max;//zmienna odpowiedzialna za maksymalny strumień świetlny<br />volatile uint8_t saturation_max;//zmienna odpowiadajaca za maksymalne nasycenie kolorów<br />} TLED_RGB;<br /><br />TLED_RGB chimney, window_left, window_right, selected_rgb;// deklaracja DIOD RGB typu TLED_RGB[/syntax]<br /><br />Oraz dwie funkcję. Pierwsza:<br />[syntax=c]void select_set_colors_rgb (TLED_RGB *sel_rgb, uint8_t COLOR&#91;7&#93;){<br /><br />uint8_t COLORS&#91;&#93;={RED, ORANGE, YELLOW ,GREEN, AQUA, BLUE, MAGENTA };//<br />static uint8_t select_color = 0, flaga_rgb = 0, i = 0;<br /><br />if (!flaga_rgb){<br />if(i&gt;=sel_rgb-&gt;value_max)<br />{<br />flaga_rgb = 1;<br />i = sel_rgb-&gt;value_max;<br />sel_rgb-&gt;color&#91;V&#93;=i;<br />sel_rgb-&gt;color&#91;S&#93; = sel_rgb-&gt;saturation_max;<br />}//(i&gt;=sel_rgb-&gt;pwm_max)<br />else<br />{<br />sel_rgb-&gt;color&#91;H&#93;=COLOR&#91;select_color&#93;;<br />sel_rgb-&gt;color&#91;V&#93;=i;<br />sel_rgb-&gt;color&#91;S&#93; = sel_rgb-&gt;saturation_max;<br />i ++;<br />}//else<br /><br />}//(!flaga_rgb)<br />else{<br />if(i==0){<br />flaga_rgb = 0;<br />if (select_color &lt;= SIZE_TAB(COLOR))select_color ++;<br />else select_color =0 ;<br />}//if(i==0)<br />else<br />{<br />sel_rgb-&gt;color&#91;V&#93;=i;<br />i--;<br />}//else<br />}//else<br />}[/syntax]<br /><br />Druga<br />[syntax=c]//****Funkcja cyklicznie zmieniająca kolory****//<br />TLED_RGB flow_colors_rgb (TLED_RGB *sel_rgb){<br /><br />static uint8_t i_h = 0;<br />sel_rgb-&gt;color&#91;H&#93; = i_h;<br />sel_rgb-&gt;color&#91;S&#93; = sel_rgb-&gt;saturation_max;<br />sel_rgb-&gt;color&#91;V&#93; = sel_rgb-&gt;value_max;<br />i_h += 1;<br /><br />return *sel_rgb;<br />}[/syntax]<br /><br /><br /><br />Powyższe funkcje wykonywane są w programie głównym<br />[syntax=c]//**Dioda w kominie**//<br />if(!chimney.LED_timer){<br />if(chimney.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb(&amp;chimney);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(chimney.chosen_function == 2){<br />flow_colors_rgb (&amp;chimney);//cykliczna zmiana pomiędzy kolorami<br />}<br />chimney.LED_timer=chimney.timer_set;<br />}<br />//**Dioda w lewym oknie**//<br />if(!window_left.LED_timer){<br />if(window_left.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb(&amp;window_left);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(window_left.chosen_function == 2){<br />flow_colors_rgb (&amp;window_left);//cykliczna zmiana pomiędzy kolorami<br />}<br />window_left.LED_timer=window_left.timer_set;<br />}<br />//**Dioda w prawym oknie**//<br />if(!window_right.LED_timer){<br />if(window_right.chosen_function == 1){//wybór funkcji wyświetlania led<br />select_set_colors_rgb(&amp;window_right);//rozświetlanie i ściemnianie wybranych kolorów<br />}<br />else if(window_right.chosen_function == 2){<br />flow_colors_rgb (&amp;window_right);//cykliczna zmiana pomiędzy kolorami<br />}<br />window_right.LED_timer=window_right.timer_set;<br />}[/syntax]<br /><br />a ich wywołanie uzależnione jest od przerwania <br />[syntax=c]// ciało procedury obsługi przerwania Compare Match Timera2, wywoływane co 50us<br />ISR( TIMER2_COMP_vect )<br />{<br /><br />uint16_t n;// zmienna na potrzeby przerwania<br />static uint8_t cnt; // definicja naszego licznika PWM<br /><br />n = ground1.LED_timer;/* 20 kHz ground1.LED_timer - 50us*/<br />if (n) ground1.LED_timer = --n;<br /><br />n = ground2.LED_timer; /* 1000Hz ground2.LED_timer  50us*/<br />if (n) ground2.LED_timer = --n;<br /><br />n = chimney.LED_timer;/* */<br />if(n) chimney.LED_timer = --n;<br /><br />n = window_left.LED_timer;/*  */<br />if(n) window_left.LED_timer = --n;<br /><br />n = window_right.LED_timer;/*  */<br />if(n) window_right.LED_timer = --n;<br /><br /><br />// **** BEZPOŚREDNIE STEROWANIE WYJŚCIAMI KANAŁÓW PWM **** //<br /><br />//**** dioda RGB w kominie ****//<br />if(cnt &gt;= chimney.color&#91;G&#93;) PORT(LED1_GPORT) |= (1&lt;&lt;LED1_G); else PORT(LED1_GPORT) &amp;= ~ (1&lt;&lt;LED1_G);<br />if(cnt &gt;= chimney.color&#91;R&#93;) PORT(LED1_RPORT) |= (1&lt;&lt;LED1_R); else PORT(LED1_RPORT) &amp;= ~ (1&lt;&lt;LED1_R);<br />if(cnt &gt;= chimney.color&#91;B&#93;) PORT(LED1_BPORT) |= (1&lt;&lt;LED1_B); else PORT(LED1_BPORT) &amp;= ~ (1&lt;&lt;LED1_B);<br /><br />////**** dioda RGB w lewym oknie ****//<br />if(cnt &gt;= window_left.color&#91;G&#93;) PORT(LED2_GPORT) |= (1&lt;&lt;LED2_G); else PORT(LED2_GPORT) &amp;= ~ (1&lt;&lt;LED2_G);<br />if(cnt &gt;= window_left.color&#91;R&#93;) PORT(LED2_RPORT) |= (1&lt;&lt;LED2_R); else PORT(LED2_RPORT) &amp;= ~ (1&lt;&lt;LED2_R);<br />if(cnt &gt;= window_left.color&#91;B&#93;) PORT(LED2_BPORT) |= (1&lt;&lt;LED2_B); else PORT(LED2_BPORT) &amp;= ~ (1&lt;&lt;LED2_B);<br /><br />////**** dioda RGB w prawym oknie ****//<br />if(cnt &gt;= window_right.color&#91;G&#93;) PORT(LED3_GPORT) |= (1&lt;&lt;LED3_G); else PORT(LED3_GPORT) &amp;= ~ (1&lt;&lt;LED3_G);<br />if(cnt &gt;= window_right.color&#91;R&#93;) PORT(LED3_RPORT) |= (1&lt;&lt;LED3_R); else PORT(LED3_RPORT) &amp;= ~ (1&lt;&lt;LED3_R);<br />if(cnt &gt;= window_right.color&#91;B&#93;) PORT(LED3_BPORT) |= (1&lt;&lt;LED3_B); else PORT(LED3_BPORT) &amp;= ~ (1&lt;&lt;LED3_B);<br /><br />//**** diody przed domkiem ****//<br />if(cnt &gt;= ground1.LED_pwm) PORT(LED4_1PORT) |= (1&lt;&lt;LED4_1); else PORT(LED4_1PORT) &amp;= ~ (1&lt;&lt;LED4_1);<br />if(cnt &gt;= ground2.LED_pwm) PORT(LED4_2PORT) |= (1&lt;&lt;LED4_2); else PORT(LED4_2PORT) &amp;= ~ (1&lt;&lt;LED4_2);<br /><br /><br />//if(cnt &gt;= ground5.LED_pwm) PORT(LED4_5PORT) |= (1&lt;&lt;LED4_5); else PORT(LED4_5PORT) &amp;= ~ (1&lt;&lt;LED4_5);<br /><br />//LED_DATA = data;<br />//SendSPI(data);<br /><br /><br /><br />cnt++;// zwiększanie licznika o 1<br />}[/syntax]<br /><br /><br />I teraz clou całej sprawy:<br />W momencie wywołania powyższych funkcji (zmienna ze struktur <em>LED_timer == 0</em>) dla wszystkich struktur, zmienne tych struktur  kopiują się i wszystkie diody zaczynają jednocześnie mrugać. Czym to jest spowodowane? <br />Czy może to być wina/przyczyna, że np dla struktury <em>chimney</em> wykonujemy pierwszą funkcję (select_set_colors_rgb) - czyli cała struktura oraz funkcja są na stosie - a w trakcie tej operacji zostaje spełniony warunek dla struktury <em>window_left</em> i zostaje wywołana ta sama funkcja, w efekcie zmienne z wywołanych funkcji nakładają się na siebie i zapisują te same wartości do różnych struktur ?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3824">amilo_pa</a> — 11 gru 2016, o 00:14</p><hr />
]]></content>
</entry>
</feed>