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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2016-09-11T09:02:54+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=50&amp;t=15678&amp;mode</id>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-09-11T09:02:54+01:00</updated>
<published>2016-09-11T09:02:54+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=168564#p168564</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=168564#p168564"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=168564#p168564"><![CDATA[
Przyznam się, że ja też zawsze chciałem zrobić model takiego skrzyżowania ze światłami, ale jak zwykle brak czasu. Więc w ramach ćwiczeń w programowaniu napisałem taki program do sterowania sygnalizatorami. Może komuś się to przyda.<br />[syntax=c]/*                  e-gadget.header<br /> * main.c<br /> *<br /> *  Created on: 2016-08-27<br /> *    Modyfied: 2016-08-27 21:38:29<br /> *      Author: Janusz M.<br /> *<br /> * Project name: &quot;Skrzyzowanie_sygnalizacja&quot;<br /> *<br /> *          MCU: ATmega328P<br /> *        F_CPU: 16 000 000 Hz<br /> *<br /> *    Flash: 1 458 bytes   &#91; 4,4 % &#93;<br /> *      RAM:  10 bytes   &#91; 0,5 % &#93;<br /> *   EEPROM:  0 bytes   &#91; 0,0 % &#93;<br /> *<br /> */<br /><br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />#include &quot;makra.h&quot;<br /><br />/* Podłączenie lamp sygnalizatorów do procesora */<br /><br />#define K1_A_R_PORTD// Kierunek1_Auta_Red<br />#define K1_A_R_PIN0<br /><br />#define K1_A_Y_PORTD// Kierunek1_Auta_Yellow<br />#define K1_A_Y_PIN1<br /><br />#define K1_A_G_PORTD// Kierunek1_Auta_Green<br />#define K1_A_G_PIN2<br /><br />#define K1_P_R_PORTD// Kierunek1_Piesi_Red<br />#define K1_P_R_PIN3<br /><br />#define K1_P_G_PORTD// Kierunek1_Piesi_Green<br />#define K1_P_G_PIN4<br /><br /><br /><br /><br />#define K2_A_R_PORTD// Kierunek2_Auta_Red<br />#define K2_A_R_PIN5<br /><br />#define K2_A_Y_PORTD// Kierunek2_Auta_Yellow<br />#define K2_A_Y_PIN6<br /><br />#define K2_A_G_PORTD// Kierunek2_Auta_Green<br />#define K2_A_G_PIN7<br /><br />#define K2_P_R_PORTB// Kierunek2_Piesi_Red<br />#define K2_P_R_PIN0<br /><br />#define K2_P_G_PORTB// Kierunek2_Piesi_Green<br />#define K2_P_G_PIN1<br /><br /><br /><br />/* Podłączenie przycisków */<br />#define SW_FLASH_PORTC// przycisk włączający tryb pulsującego żółtego światła<br />#define SW_FLASH_PIN0<br /><br />#define SW_NORMAL_PORTC// przycisk włączający normalny tryb zmiany świateł<br />#define SW_NORMAL_PIN1<br /><br />#define SW_K1P_PORTC// przycisk aktywujący zielone światło dla pieszych, dla kierunku 1<br />#define SW_K1P_PIN2<br /><br />#define SW_K2P_PORTC// przycisk aktywujący zielone światło dla pieszych, dla kierunku 2<br />#define SW_K2P_PIN3<br /><br />/* Podświetlenie przycisków */<br />#define LED_SW_K1P_PORTC// podświetlenie przycisku aktywacji świateł dla pieszych, dla kierunku 1<br />#define LED_SW_K1P_PIN4<br /><br />#define LED_SW_K2P_PORTC// podświetlenie przycisku aktywacji świateł dla pieszych, dla kierunku 2<br />#define LED_SW_K2P_PIN5<br /><br /><br />/* Makra ułatwiające sterowanie światłami - stan niski włącza światło, stan wysoki wyłącza */<br /><br />#define K1_A_R_ONPORT(K1_A_R_PORT) &amp;= ~(1 &lt;&lt; K1_A_R_PIN)// włączenie światła czerwonego dla samochodów, dla kierunku 1<br />#define K1_A_R_OFFPORT(K1_A_R_PORT) |= (1 &lt;&lt; K1_A_R_PIN)// wyłączenie światła czerwonego dla samochodów, dla kierunku 1<br /><br />#define K1_A_Y_ONPORT(K1_A_Y_PORT) &amp;= ~(1 &lt;&lt; K1_A_Y_PIN)// włączenie światła żółtego dla samochodów, dla kierunku 1<br />#define K1_A_Y_OFFPORT(K1_A_Y_PORT) |= (1 &lt;&lt; K1_A_Y_PIN)// wyłączenie światła żółtego dla samochodów, dla kierunku 1<br /><br />#define K1_A_G_ONPORT(K1_A_G_PORT) &amp;= ~(1 &lt;&lt; K1_A_G_PIN)// włączenie światła zielonego dla samochodów, dla kierunku 1<br />#define K1_A_G_OFFPORT(K1_A_G_PORT) |= (1 &lt;&lt; K1_A_G_PIN)// wyłączenie światła zielonego dla samochodów, dla kierunku 1<br /><br />#define K1_P_R_ONPORT(K1_P_R_PORT) &amp;= ~(1 &lt;&lt; K1_P_R_PIN)// włączenie światła czerwonego dla pieszych, dla kierunku 1<br />#define K1_P_R_OFFPORT(K1_P_R_PORT) |= (1 &lt;&lt; K1_P_R_PIN)// wyłączenie światła czerwonego dla pieszych, dla kierunku 1<br /><br />#define K1_P_G_ONPORT(K1_P_G_PORT) &amp;= ~(1 &lt;&lt; K1_P_G_PIN)// włączenie światła zielonego dla pieszych, dla kierunku 1<br />#define K1_P_G_OFFPORT(K1_P_G_PORT) |= (1 &lt;&lt; K1_P_G_PIN)// wyłączenie światła zielonego dla pieszych, dla kierunku 1<br /><br /><br /><br /><br />#define K2_A_R_ONPORT(K2_A_R_PORT) &amp;= ~(1 &lt;&lt; K2_A_R_PIN)// włączenie światła czerwonego dla samochodów, dla kierunku 2<br />#define K2_A_R_OFFPORT(K2_A_R_PORT) |= (1 &lt;&lt; K2_A_R_PIN)// wyłączenie światła czerwonego dla samochodów, dla kierunku 2<br /><br />#define K2_A_Y_ONPORT(K2_A_Y_PORT) &amp;= ~(1 &lt;&lt; K2_A_Y_PIN)// włączenie światła żółtego dla samochodów, dla kierunku 2<br />#define K2_A_Y_OFFPORT(K2_A_Y_PORT) |= (1 &lt;&lt; K2_A_Y_PIN)// wyłączenie światła żółtego dla samochodów, dla kierunku 2<br /><br />#define K2_A_G_ONPORT(K2_A_G_PORT) &amp;= ~(1 &lt;&lt; K2_A_G_PIN)// włączenie światła zielonego dla samochodów, dla kierunku 2<br />#define K2_A_G_OFFPORT(K2_A_G_PORT) |= (1 &lt;&lt; K2_A_G_PIN)// wyłączenie światła zielonego dla samochodów, dla kierunku 2<br /><br />#define K2_P_R_ONPORT(K2_P_R_PORT) &amp;= ~(1 &lt;&lt; K2_P_R_PIN)// włączenie światła czerwonego dla pieszych, dla kierunku 2<br />#define K2_P_R_OFFPORT(K2_P_R_PORT) |= (1 &lt;&lt; K2_P_R_PIN)// wyłączenie światła czerwonego dla pieszych, dla kierunku 2<br /><br />#define K2_P_G_ONPORT(K2_P_G_PORT) &amp;= ~(1 &lt;&lt; K2_P_G_PIN)// włączenie światła zielonego dla pieszych, dla kierunku 2<br />#define K2_P_G_OFFPORT(K2_P_G_PORT) |= (1 &lt;&lt; K2_P_G_PIN)// wyłączenie światła zielonego dla pieszych, dla kierunku 2<br /><br /><br /><br />#define K12_A_Y_ONPORT(K1_A_Y_PORT) &amp;= ~(1 &lt;&lt; K1_A_Y_PIN); PORT(K2_A_Y_PORT) &amp;= ~(1 &lt;&lt; K2_A_Y_PIN)// włączenie światła żółtego dla samochodów, dla wszystkich kierunków<br />#define K12_A_Y_OFFPORT(K1_A_Y_PORT) |= (1 &lt;&lt; K1_A_Y_PIN); PORT(K2_A_Y_PORT) |= (1 &lt;&lt; K2_A_Y_PIN)// wyłączenie światła żółtego dla samochodów, dla wszystkich kierunków<br /><br />#define LED_SW_K1P_OFFPORT(LED_SW_K1P_PORT) |= (1 &lt;&lt; LED_SW_K1P_PIN)// wyłączenie podświetlania przycisku aktywacji światła zielonego dla pieszych, dla kierunku 1<br />#define LED_SW_K2P_OFFPORT(LED_SW_K2P_PORT) |= (1 &lt;&lt; LED_SW_K2P_PIN)// wyłączenie podświetlania przycisku aktywacji światła zielonego dla pieszych, dla kierunku 2<br />#define LED_SW_K1P_ONPORT(LED_SW_K1P_PORT) &amp;= ~(1 &lt;&lt; LED_SW_K1P_PIN)// włączenie podświetlania przycisku aktywacji światła zielonego dla pieszych, dla kierunku 1<br />#define LED_SW_K2P_ONPORT(LED_SW_K2P_PORT) &amp;= ~(1 &lt;&lt; LED_SW_K2P_PIN)// włączenie podświetlania przycisku aktywacji światła zielonego dla pieszych, dla kierunku 2<br />#define FLASH_SW_K1PPORT(LED_SW_K1P_PORT) ^= (1 &lt;&lt; LED_SW_K1P_PIN)// miganie podświetlaniem przycisku aktywacji światła zielonego dla pieszych, dla kierunku 1<br />#define FLASH_SW_K2PPORT(LED_SW_K2P_PORT) ^= (1 &lt;&lt; LED_SW_K2P_PIN)// miganie podświetlaniem przycisku aktywacji światła zielonego dla pieszych, dla kierunku 2<br /><br />/* definicje czsów poszczególnych cykli w ms * 10    */<br />#define T_K1_G800// czas trwania zielonego światła dla kierunku 1<br />#define T_K2_G800// czas trwania zielonego światła dla kierunku 2<br />#define T_P30// czas pojedynczego mignięcia światła zielonego dla pieszych (czas świecenia, czas przerwy jest taki sam)<br />#define T_Y300// czas trwania światła żółtego<br />#define T_R100// czas trwania światła czerwonego dla wszystkich kierunków<br />#define N_MIGNIEC4// liczba mignięc światła zielonego dla pieszych<br /><br />#define T_TEST1000// czas w ms włączenia kolejnych lamp w teście<br /><br />/* Informacja o źle dobranym czasie trwania światła zielonego dla poszczególnych kierunków,<br /> * jeśli całkowity czas cyklu migania światła zielonego dla pieszych będzie dłuższy lub równy czasowi trwania światła zielonego dla aut */<br />#if(T_K1_G &lt;= N_MIGNIEC * 2 * T_P)<br />#error Źle dobrany czas T_K1_G w stosunku do N_MIGNIEC i T_P<br />#endif<br /><br />#if(T_K2_G &lt;= N_MIGNIEC * 2 * T_P)<br />#error Źle dobrany czas T_K2_G w stosunku do N_MIGNIEC i T_P<br />#endif<br /><br /><br />/* Funkcja inicjalizująca piny do których podłączone są lampy sygnalizatorów i przyciski */<br />void lamp_port_init(void);<br /><br />/* Funkcja testowa podłączenia lamp sygnalizatorów<br /> * Kolejno zapalane bedą na czas T_TEST światła sygnalizatorów i podświetlenia przycisków<br /> */<br />void lamp_test(void);<br /><br />/* Funkcja wyłączająca wszystkie światła */<br />void lamps_off(void);<br /><br />/* Zmienne globalne */<br />uint8_t tryb_pracy = 0;// dla wartości 0, 1, 2 - pulsujące żółte, dla wartości 3, 4 - rormalny cykl zmiany świateł<br />uint8_t sekwencja = 0;// numer sekwencji układu świateł<br />uint8_t n_powtorzen = 0;// licznik powtórzeń migającego zielonego dla pieszych<br />uint8_t k1p = 0;// flaga wciśniętego przycisku dla pieszych dla kierunku 1<br />uint8_t k2p = 0;// flaga wciśniętego przycisku dla pieszych dla kierunku 2<br />uint8_t sw_flash = 0;// flaga wciśniętego przycisku SW_FLASH<br />volatile uint16_t Timer1, Timer2;// Timer1 odmierza czasy przełączania swiateł sygnalizatorów,<br />// Timer2 miganie podświetlania przycisków aktywujących zielone światło dla pieszych<br /><br /><br /><br /><br />int main(void) {<br /><br />// inicjalizacja portów mikrokontrolera<br />lamp_port_init();<br /><br />// konfiguracja timera programowego<br />TCCR1B |= (1 &lt;&lt; WGM12);// tryb pracy CTC<br />TCCR1B |= (1 &lt;&lt; CS12);// prescaler = 256<br />OCR1A = 624;// przerwanie co 10 ms dla F_CPU = 16 MHz<br />TIMSK1 |= (1 &lt;&lt; OCIE1A);// odblokowanie przerwania CompareMatch<br /><br />// włączenie przerwań<br />sei();<br /><br /><br />while(1) {<br />/***** sprawdzenie stanu przycisków *****/<br />if(!(PIN(SW_FLASH_PORT) &amp; (1 &lt;&lt; SW_FLASH_PIN))) sw_flash = 1;// jeśli wciśnięty przycisk SW_FLASH, ustaw flagę sw_flash<br />if(!(PIN(SW_NORMAL_PORT) &amp; (1 &lt;&lt; SW_NORMAL_PIN)) &amp;&amp; (tryb_pracy == 1 || tryb_pracy == 2)) {// jeśli wciśnięty przycisk SW_NORMAL i układ w trybie<br />// żółtego światła pulsującego<br />tryb_pracy = 3;// ustaw tryb pracy na 3<br />sekwencja = 0;// zeruj zmienną sekwencja<br />sw_flash = 0;// zeruj flagę sw_flash<br />}<br />// jeśli wciśnięty przycisk aktywujący zielone światło dla pieszych dla kierunku1, ustaw flagę k1p<br />if(!(PIN(SW_K1P_PORT) &amp; (1 &lt;&lt; SW_K1P_PIN)) &amp;&amp; tryb_pracy == 4) k1p = 1;<br />// jeśli wciśnięty przycisk aktywujący zielone światło dla pieszych dla kierunku2, ustaw flagę k2p<br />if(!(PIN(SW_K2P_PORT) &amp; (1 &lt;&lt; SW_K2P_PIN)) &amp;&amp; tryb_pracy == 4) k2p = 1;<br /><br />/***** sterowanie podświetleniem przycisków aktywujących zielone światło dla pieszych *****/<br />if(Timer2 == 0) {<br />Timer2 = 30;// czas migania światła<br />if(k1p) FLASH_SW_K1P;// jeśli ustawiona flaga wciśnięcia przycisku SW_K1P, zmień stan podświetlania przycisku na przeciwny<br />else<br />LED_SW_K1P_OFF;// jeśli flaga wciśnięcia przycisku SW_K1P wyzerowana, wyłącz podswietlanie przycisku<br /><br />if(k2p) FLASH_SW_K2P;// jeśli ustawiona flaga wciśnięcia przycisku SW_K2P, zmień stan podświetlania przycisku na przeciwny<br />else<br />LED_SW_K2P_OFF;// jeśli flaga wciśnięcia przycisku SW_K2P wyzerowana, wyłącz podswietlanie przycisku<br />}<br /><br />/**** tryb pulsującego żółtego światła *****/<br />if(tryb_pracy == 0 &amp;&amp; Timer1 == 0) {<br />lamps_off();// wyłącz wszystkie światła<br />k1p = 0;// zeruj flagi wciśnięcia przycisków aktywujących zielone światło dla pieszych<br />k2p = 0;<br />tryb_pracy = 1;// ustaw tryb pracy 1<br />}<br />// żółte światło ostrzegawcze powinno pulsowac z częstotliwością 2 Hz i czas włączenia do czasu wyłączenia powinien wynosic 0.6 : 0.4<br />if(tryb_pracy == 1 &amp;&amp; Timer1 == 0) {// jeśli ustawiony jest tryb pracy 1 i minął czas 0.2 s<br />Timer1 = 30;// wpisz do Timera1 czas 300 ms<br />K12_A_Y_ON;// włącz żółte światła<br />tryb_pracy = 2;// ustaw tryb pracy 2<br />}<br /><br />if(tryb_pracy == 2 &amp;&amp; Timer1 == 0) {// jeśli ustawiony jest tryb pracy 2 i minął czas 0.3 s<br />Timer1 = 20;// wpisz do Timera1 czas 200 ms<br />K12_A_Y_OFF;// wyłącz światła żółte<br />tryb_pracy = 1;// ustaw tryb pracy 1<br />}<br /><br />/***** wstępne ustawienie świateł przy przejściu od trybu pulsującego żółtego do trybu normalnej zmiany świateł *****/<br />if(tryb_pracy == 3) {<br />Timer1 = 300;// wpisz do timera1 czas 3 s<br />K1_A_Y_ON;// dla Kierunku1, dla Aut, Yellow - żółte światło, ON - włącz<br />K1_P_R_ON;// dla Kierunku1, dla Pieszych, Red - czerwone światło, ON - włącz<br />K2_A_Y_ON;// dla Kierunku2, dla Aut, Yellow - żółte światło, ON - włącz<br />K2_P_R_ON;// dla Kierunku2, dla Pieszych, Red - czerwone światło, ON - włącz<br />tryb_pracy = 4;// ustaw tryb pracy 3<br />}<br /><br />/***** tryb normalnego działania sygnalizacji świetlnej *****/<br />if(tryb_pracy == 4 &amp;&amp; Timer1 == 0) {// jeśli ustawiony tryb normalnej zmiany świateł i odliczony został kolejny czas<br />switch(sekwencja) {// ustaw odpowiednią kombinację świateł w zależności od numeru sekwencji<br />case 0:<br />Timer1 = T_R;// wpisz do Timera1 czas trwania światła czerwonego dla obydwu kierunków<br />sekwencja = 1;// wpisz numer kolejnej do wykonania sekwencji świateł<br />K1_A_R_ON;// dla Kierunku1, dla Aut, Red - czerwone światło, ON - włącz<br />K1_A_Y_OFF;// dla Kierunku1, dla Aut, Yellow - żółte światło, OFF - wyłącz<br />K1_A_G_OFF;// dla Kierunku1, dla Aut, Green - zielone światło, OFF - wyłącz<br />K1_P_R_ON;// dla Kierunku1, dla Pieszych, Red - czerwone światło, ON - włącz<br />K1_P_G_OFF;// dla Kierunku1, dla Pieszych, Green - zielone światło, OFF - wyłącz<br /><br />K2_A_R_ON;// itd...<br />K2_A_Y_ON;<br />K2_A_G_OFF;<br />K2_P_R_ON;<br />K2_P_G_OFF;<br />break;<br /><br />case 1:<br />if(k2p) {// jeśli ustawiona flaga wciśnięcia przycisku aktywacji zielonego światła dla pieszych, dla kierunku 2<br />Timer1 = (T_K2_G - N_MIGNIEC * 2 * T_P); // wpisz do Timera1 czas trwania swiatła zielonego dla kierunku 2,<br /> // pomniejszony o czas trwania sekwencji migania światła zielonego dla pieszych<br />sekwencja = 2;// ustaw numer następnej sekwencji do wykonania<br />K2_A_R_OFF;// ustaw odpowiednio światła sygnalizatorów<br />K2_A_Y_OFF;<br />K2_A_G_ON;<br />K2_P_R_OFF;<br />K2_P_G_ON;<br />k2p = 0;// zeruj flagę wciśnięcia przycisku aktywacji zielonego światła dla pieszych dla kierunku 2<br />break;<br />}<br />else {// jesli flaga nie ustawiona<br />Timer1 = T_K2_G;// wpisz do Timera1 czas trwania zielonego światła dla kierunku 2<br />sekwencja = 4;// ustaw numer następnej sekwencji<br />K2_A_R_OFF;// ustaw odpowiednio światła sygnalizatorów<br />K2_A_Y_OFF;<br />K2_A_G_ON;<br />break;<br />}<br /><br />case 2:// sekwencja migania zielonego światła dla pieszych dla kierunku 2<br />Timer1 = T_P;<br />if(n_powtorzen == N_MIGNIEC) sekwencja = 4;<br />else<br />sekwencja = 3;<br />K2_P_G_OFF;<br />break;<br /><br />case 3:// sekwencja migania zielonego światła dla pieszych dla kierunku 2<br />Timer1 = T_P;<br />sekwencja = 2;<br />n_powtorzen++;<br />K2_P_G_ON;<br />break;<br /><br />case 4:<br />Timer1 = T_Y;<br />sekwencja = 5;<br />n_powtorzen = 0;<br />K2_A_Y_ON;<br />K2_A_G_OFF;<br />K2_P_R_ON;<br />break;<br /><br />case 5:<br />Timer1 = T_R;<br />sekwencja = 6;<br />K2_A_R_ON;<br />K2_A_Y_OFF;<br />if(sw_flash) tryb_pracy = 0;// sprawdzenie czy nie został wciśnięty przycisk trybu pulsującego światła żoltego<br />break;<br /><br />case 6:<br />Timer1 = T_R;<br />sekwencja = 7;<br />K1_A_Y_ON;<br />break;<br /><br />case 7:<br />if(k1p) {// jeśli ustawiona flaga wciśnięcia przycisku aktywacji zielonego światła dla pieszych, dla kierunku 1<br />Timer1 = (T_K1_G - N_MIGNIEC * 2 * T_P);<br />sekwencja = 8;<br />K1_A_R_OFF;<br />K1_A_Y_OFF;<br />K1_A_G_ON;<br />K1_P_R_OFF;<br />K1_P_G_ON;<br />k1p = 0;<br />break;<br />}<br />else {<br />Timer1 = T_K1_G;<br />sekwencja = 10;<br />K1_A_R_OFF;<br />K1_A_Y_OFF;<br />K1_A_G_ON;<br />break;<br />}<br /><br />case 8:// sekwencja migania zielonego światła dla pieszych dla kierunku 1<br />Timer1 = T_P;<br />if(n_powtorzen == N_MIGNIEC) sekwencja = 10;<br />else<br />sekwencja = 9;<br />K1_P_G_OFF;<br />break;<br /><br />case 9:// sekwencja migania zielonego światła dla pieszych dla kierunku 1<br />Timer1 = T_P;<br />sekwencja = 8;<br />n_powtorzen++;<br />K1_P_G_ON;<br />break;<br /><br />case 10:<br />Timer1 = T_Y;<br />sekwencja = 11;<br />n_powtorzen = 0;<br />K1_A_Y_ON;<br />K1_A_G_OFF;<br />K1_P_R_ON;<br />break;<br /><br />case 11:<br />Timer1 = T_R;<br />sekwencja = 0;// koniec pełnego cyklu zmiany świateł<br />K1_A_R_ON;<br />K1_A_Y_OFF;<br />if(sw_flash) tryb_pracy = 0;// sprawdzenie czy nie został wciśnięty przycisk trybu pulsującego światła żoltego<br />break;<br />}<br />}<br />}<br />}<br /><br /><br />/* Obsługa przerwania */<br />ISR(TIMER1_COMPA_vect)<br />{<br />uint16_t x;<br /><br />x = Timer1;<br />if(x) Timer1 = --x;<br /><br />x = Timer2;<br />if(x) Timer2 = --x;<br />}<br /><br /><br />/* Inicjalizacja portów */<br />void lamp_port_init(void) {<br />// podciągnięcie pinów przycisków do Vcc<br />PORT(SW_FLASH_PORT) |= (1 &lt;&lt; SW_FLASH_PIN);<br />PORT(SW_NORMAL_PORT) |= (1 &lt;&lt; SW_NORMAL_PIN);<br />PORT(SW_K1P_PORT) |= (1 &lt;&lt; SW_K1P_PIN);<br />PORT(SW_K2P_PORT) |= (1 &lt;&lt; SW_K2P_PIN);<br /><br /><br />// ustawiamy odpowiednie piny jako wyjście<br />DDR(K1_A_R_PORT) |= (1 &lt;&lt; K1_A_R_PIN);<br />DDR(K1_A_Y_PORT) |= (1 &lt;&lt; K1_A_Y_PIN);<br />DDR(K1_A_G_PORT) |= (1 &lt;&lt; K1_A_G_PIN);<br />DDR(K1_P_R_PORT) |= (1 &lt;&lt; K1_P_R_PIN);<br />DDR(K1_P_G_PORT) |= (1 &lt;&lt; K1_P_G_PIN);<br /><br />DDR(K2_A_R_PORT) |= (1 &lt;&lt; K2_A_R_PIN);<br />DDR(K2_A_Y_PORT) |= (1 &lt;&lt; K2_A_Y_PIN);<br />DDR(K2_A_G_PORT) |= (1 &lt;&lt; K2_A_G_PIN);<br />DDR(K2_P_R_PORT) |= (1 &lt;&lt; K2_P_R_PIN);<br />DDR(K2_P_G_PORT) |= (1 &lt;&lt; K2_P_G_PIN);<br /><br />DDR(LED_SW_K1P_PORT) |= (1 &lt;&lt; LED_SW_K1P_PIN);<br />DDR(LED_SW_K2P_PORT) |= (1 &lt;&lt; LED_SW_K2P_PIN);<br /><br />// wyłączamy wszystkie lampy<br />lamps_off();<br /><br />// sprawdzimy czy wszystko jest dobrze podłączone<br />lamp_test();<br /><br />}<br /><br /><br />/* Testowanie lamp */<br />void lamp_test(void) {<br />K1_A_R_ON;<br />_delay_ms(T_TEST);<br />K1_A_R_OFF;<br />K1_A_Y_ON;<br />_delay_ms(T_TEST);<br />K1_A_Y_OFF;<br />K1_A_G_ON;<br />_delay_ms(T_TEST);<br />K1_A_G_OFF;<br />K1_P_R_ON;<br />_delay_ms(T_TEST);<br />K1_P_R_OFF;<br />K1_P_G_ON;<br />_delay_ms(T_TEST);<br />K1_P_G_OFF;<br />_delay_ms(T_TEST);<br />LED_SW_K1P_ON;<br />_delay_ms(T_TEST);<br />LED_SW_K1P_OFF;<br />_delay_ms(2 * T_TEST);<br />K2_A_R_ON;<br />_delay_ms(T_TEST);<br />K2_A_R_OFF;<br />K2_A_Y_ON;<br />_delay_ms(T_TEST);<br />K2_A_Y_OFF;<br />K2_A_G_ON;<br />_delay_ms(T_TEST);<br />K2_A_G_OFF;<br />K2_P_R_ON;<br />_delay_ms(T_TEST);<br />K2_P_R_OFF;<br />K2_P_G_ON;<br />_delay_ms(T_TEST);<br />K2_P_G_OFF;<br />_delay_ms(T_TEST);<br />LED_SW_K2P_ON;<br />_delay_ms(T_TEST);<br />LED_SW_K2P_OFF;<br />_delay_ms(2 * T_TEST);<br />}<br /><br /><br />void lamps_off(void) {<br />K1_A_R_OFF;<br />K1_A_Y_OFF;<br />K1_A_G_OFF;<br />K1_P_R_OFF;<br />K1_P_G_OFF;<br /><br />K2_A_R_OFF;<br />K2_A_Y_OFF;<br />K2_A_G_OFF;<br />K2_P_R_OFF;<br />K2_P_G_OFF;<br /><br />LED_SW_K1P_OFF;<br />LED_SW_K2P_OFF;<br />}[/syntax]<br />[syntax=c]/*<br /> * makra.h<br /> *<br /> *  Created on: 2012-08-23<br /> *      Author: Janusz M.<br /> */<br /><br />#ifndef MAKRA_H_<br />#define MAKRA_H_<br /><br />// Makra upraszczające dostęp do portów<br />// *** PORT<br />#define PORT(x) XPORT(x)<br />#define XPORT(x) (PORT##x)<br />// *** PIN<br />#define PIN(x) XPIN(x)<br />#define XPIN(x) (PIN##x)<br />// *** DDR<br />#define DDR(x) XDDR(x)<br />#define XDDR(x) (DDR##x)<br /><br /><br /><br />#endif /* MAKRA_H_ */[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 11 wrz 2016, o 09:02</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-08-09T08:26:36+01:00</updated>
<published>2016-08-09T08:26:36+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165697#p165697</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165697#p165697"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165697#p165697"><![CDATA[
Dokładnie puki co pracuje nad programem co niejako jest ćwiczeniem, jak tylko rozbuduje makietę wtedy będę mógł sprawdzić na żyjącym organizmie i wtedy pewne nowe kłopoty wypłyną, czyli nowe wyzwania.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 9 sie 2016, o 08:26</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[skandal_obyczajowy]]></name></author>
<updated>2016-08-05T02:54:56+01:00</updated>
<published>2016-08-05T02:54:56+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165450#p165450</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165450#p165450"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165450#p165450"><![CDATA[
Instrukcje zerujące rejestr licznika  TCNT0 z linii 23 oraz 104 możesz śmiało usunąć.  Stan  tego rejestru po włączeniu zasilania układu oraz po resecie wynosi 0, zaś po przepełnieniu się tego rejestru  licznik  zaczyna zliczać od zera,  gdyż jego pojemność wynosi 8 bitów. <br /><br />Stosuj makra i/lub  typy wyliczeniowe enum, które zwiększą czytelność programu. Obecnie można jedynie zgadywać, które światła sterowane są którymi pinami układu. Staraj się, by wiersze w edytorze nie były dłuższe niż 80 znaków. To również ułatwia  czytanie kodu.<br /><br />Jeden wielki switch  w pętli głównej nie jest najszczęśliwszym rozwiązaniem. Owszem, działa,  ale z fajnym  programem ma niewiele wspólnego. Postaraj  się podzielić kod na funkcje, w ten sposób ograniczysz również  dublujące się instrukcje.<br /><br />Pozdrawiam.<br /><br />PS.  Ćwicz, ćwicz... przez ćwiczenia  do mistrzostwa. Zaczynałem bardzo podobnie <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=13646">skandal_obyczajowy</a> — 5 sie 2016, o 02:54</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-08-03T13:44:41+01:00</updated>
<published>2016-08-03T13:44:41+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165324#p165324</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165324#p165324"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165324#p165324"><![CDATA[
Racja. Kilka razy o ty czytałem, oglądałem filmik o maskowaniu bitów, wydawało mi się że mnie to nie spotka. Ale chyba na tym polega nauka. Poprawiłem program , na szybko zaadaptowałem obsługę przycisku i o dziwo działa. Żadnych samoczynnych nie planowanych zmian stanów, i dziwnych zachowań programu. Zamierzam rozszerzyć całość i rozbudować, ale bazę mam już solidną.<br /><br />Wielkie dzięki za pomoc i sugestie. Jeśli uda mi się domknąć całość wrzucę na forum może się komuś przyda.<br /><br />Ostateczny działający program:<br /><br />[syntax=cpp]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />volatile uint16_t cnt=0;<br />int przycisk;<br /><br />int main(void)<br /><br />{<br /><br />  // I/O<br />  DDRB = 0b0111111;<br />  DDRC = 0b0111111;<br />  DDRD = 0b0011111;<br />  DDRD &amp;= ~(1&lt;&lt;PD4);<br /><br />  PORTD |= (1&lt;&lt;PD4);   //ustawienie stanu wysokiego na przycisku<br /><br />  // timer<br />  TIMSK |= (1&lt;&lt;TOIE0);                                  //przerwanie overflow (przepełnienie timera)<br />  TCCR0 |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);                // źródłem CLK, preskaler 1024<br />  TCNT0 = 0;                                               //początkowa wartość licznika<br /><br />  przycisk=0;<br /><br />  sei();<br /><br />while(1)<br /><br />{<br /><br />if( !(PIND &amp; (1&lt;&lt;PD4))) //kiedy przycisk wcisniety zmienna przycisk=1<br />{<br />przycisk=1;<br />}<br /><br />switch(cnt)<br /><br />{<br /><br />case 80:// 1 krok : zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />//PORTC &amp;= ~((1&lt;&lt;PC2) | (1&lt;&lt;PC5));<br />PORTC |= (1&lt;&lt;PC2) | (1&lt;&lt;PC5);<br />PORTB |= (1&lt;&lt;PB0) | (1&lt;&lt;PB3);                                                                     <br />PORTD |= (1&lt;&lt;PD1) | (1&lt;&lt;PD3);                                                                    <br />break;<br /><br />case 180:<br />if(przycisk==1)//kiedy przycisk==1<br />{<br />PORTD &amp;= ~((1&lt;&lt;PD1) | (1&lt;&lt;PD3));<br />PORTD |= (1&lt;&lt;PD0) | (1&lt;&lt;PD2); //0b00000101;<br />przycisk=0;<br />}<br />break;<br /><br />case 280 : //2 krok : zielone i zolte dla pojazdow czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />//przycisk=0;<br />PORTC |= (1&lt;&lt;PC1) | (1&lt;&lt;PC2) | (1&lt;&lt;PC4)| (1&lt;&lt;PC5);                 <br />PORTB &amp;= ~((1&lt;&lt;PB0) | (1&lt;&lt;PB3));<br />PORTB |= (1&lt;&lt;PB1) | (1&lt;&lt;PB4);<br />PORTD &amp;= ~((1&lt;&lt;PD0) | (1&lt;&lt;PD2));<br />PORTD |= (1&lt;&lt;PD1) | (1&lt;&lt;PD3); <br />break;<br /><br />case 480: //3 krok :  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone dla pojazdow czerwone dla pieszych<br />//przycisk=0;<br />PORTC &amp;= ~((1&lt;&lt;PC1) | (1&lt;&lt;PC2) | (1&lt;&lt;PC4)| (1&lt;&lt;PC5));<br />PORTC |= (1&lt;&lt;PC0) | (1&lt;&lt;PC3);                   <br />PORTB &amp;= ~((1&lt;&lt;PB1) | (1&lt;&lt;PB4));<br />PORTB |= (1&lt;&lt;PB2) | (1&lt;&lt;PB5);    <br />PORTD |= (1&lt;&lt;PD1) | (1&lt;&lt;PD3);                                  <br />break;<br /><br />case 680: //4 krok :  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone i zolte dla pojazdow czerwone dla pieszych<br />//przycisk=0;<br />PORTC &amp;= ~((1&lt;&lt;PC0) | (1&lt;&lt;PC3));<br />PORTC |= (1&lt;&lt;PC1) | (1&lt;&lt;PC4);                                   <br />PORTB |= (1&lt;&lt;PB1) | (1&lt;&lt;PB2) | (1&lt;&lt;PB4) | (1&lt;&lt;PB5);             <br />PORTD |= (1&lt;&lt;PD1) | (1&lt;&lt;PD3);        <br />//cnt=80;<br />break;<br /><br />case 880: //5 krok : zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />//przycisk=0;<br />PORTC &amp;= ~((1&lt;&lt;PC1) | (1&lt;&lt;PC4));<br />PORTC |= (1&lt;&lt;PC2) | (1&lt;&lt;PC5);    <br />PORTB &amp;= ~((1&lt;&lt;PB1) | (1&lt;&lt;PB2) | (1&lt;&lt;PB4) | (1&lt;&lt;PB5));<br />PORTB |= (1&lt;&lt;PB0) | (1&lt;&lt;PB3);                                   <br />PORTD |= (1&lt;&lt;PD1) | (1&lt;&lt;PD3);            <br />cnt=0;<br />break;<br /><br />}<br /><br />}<br /><br />}<br /><br />ISR(TIMER0_OVF_vect)//procedura obsługi przerwania od przepełnienia timera<br /><br />  {<br />  TCNT0 = 0;<br />  cnt++;<br />  }[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 3 sie 2016, o 13:44</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-08-02T13:37:36+01:00</updated>
<published>2016-08-02T13:37:36+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165271#p165271</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165271#p165271"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165271#p165271"><![CDATA[
A ten przycisk podłaczony do pinu PD4, to masz podciągnięty rezystorem zewnętrznym do Vcc? Bo jeśli nie to pojawiają się tam przypadkowe stany i nawet nie przyciskając przycisku możesz mieć tam stan niski.<br />Myślę, że chciałeś raczej podciągać ten pin programowo, bo wpisujesz jedynkę do portu na samym początku przy konfiguracji portów. Ale popatrz teraz na koniec programu. Wpisujesz do portu D wartość 0 na wszystkich pinach. I tak po pierwszym obiegu pętli while, podciągania wejścia do Vcc już nie ma.<br />To jest właśnie przykład na to, że dobrze się nauczyć pewnych zasad poprawnego pisania kodu. Jedną z tych zasad jest to, aby nie ustawiać stanów portu przez wpisywanie konkretnej liczby. Powinno się to robić tak aby zmiany jednego czy kilku pinów nie zmieniały pozostałych.<br />[syntax=c]// np. ustawienie stanu wysokiego na pinie 2 portu D<br />PORTD |= (1 &lt;&lt; PD2);<br />// zerowanie tego pinu<br />PORTD &amp;= ~(1 &lt;&lt; PD2);[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 2 sie 2016, o 13:37</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-08-02T06:54:06+01:00</updated>
<published>2016-08-02T06:54:06+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165240#p165240</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165240#p165240"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165240#p165240"><![CDATA[
Jeśli chodzi o zerowanie flagi to wykonuje się w kroku drugim (case 280), tylko odnoszę wrażenie, że nie do końca się to sprawdza. Czasami kiedy program zrobi jeden pełen obieg i nie zostanie wciśnięty przycisk to przy następnym obiegu reaguje jak był by wciśnięty, podejrzewam że mam jakieś błędy składniowe i staram się je namierzyć.<br /><br />Program wgrywam z eclipsy za pomocą atnelowskiego ATB-USBASP, cały układ mam na stykówce. Wiem że stykówki mają opinie wysoce nie stabilnych i awaryjnych, ale moje problemy mają dość stały charakter i co jakiś czas sprawdzam sobie na przykład działanie samego przycisku na innym programie, więc fizycznie powinno być ok.<br /><br />                                                                               #<br /><br />Poniżej program który ma za zadanie skrócić czas trwania pętli jeśli wciśnie się przycisk, dodaje do wartości zmiennej i 100. Pierwszy obieg trwa około 34 sekundy, a następny nawet jak nie jest wciśnięty przycisk już tylko 2 sekundy. Wygląda to taj jak by po wciśnięciu przycisku lub jednym obiegu głównej pętli przycisk na stałe miał wartość 1. To chyba z powodu problemu z wyzerowaniem przycisku mam kłopoty z tą sygnalizacją.<br /><br />[syntax=cpp]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />int przycisk;<br />int i;<br /><br />int main(void)<br />{<br />//************************ustawienia portow<br />DDRB = 0b0111111;<br />DDRC = 0b0111111;<br />DDRD = 0b0011111;<br />DDRD &amp;= ~(1&lt;&lt;PD4);<br /><br />PORTD |= (1&lt;&lt;PD4);<br /><br />while(1)<br />{<br /><br />i=0;//zmienna i uzywana w petli<br /><br />//************************petla ktora podczas wykonywania sprawdza stan przycisku<br /><br />while(i&lt;200)//ilosc petli ktora determinuje czas zapalenia diod<br />{<br />if( !(PIND &amp; (1&lt;&lt;PD4)))// jesli przycisk wcisniety to przycisk=1<br />{<br />przycisk=1;<br />}<br /><br />if(przycisk==1)//jesli przycisk==1 to zmienna i zwieksza o 100<br />{<br />i=i+100;<br />}<br />PORTC = 0b11111111;//zapalenie diod na portach c ib<br />PORTB = 0b11111111;<br />_delay_ms(500);<br />i++;<br />}<br /><br />i=0;//po wykonaniu petli zeruja sie zmienn i , przycisk<br />przycisk=0;<br />PORTC = 0b00000000;//gasna diody<br />PORTB = 0b00000000;<br />PORTD = 0b11111111;//zapala sie port c aby widoczny byl koniec petli<br />_delay_ms(3000);<br />PORTD = 0b0000000;<br /><br />}<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 2 sie 2016, o 06:54</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-08-01T13:41:31+01:00</updated>
<published>2016-08-01T13:41:31+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165191#p165191</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165191#p165191"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165191#p165191"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />nie jestem pewien czy takie wplatanie przycisków w procedury przerwań nie jest dla nich zbyt dużym obciążeniem?<br /></div><br />Ale w tym wariancie obsługę przycisku masz wstawioną w pętli głównej.<br />Mnie tu brakuje tylko zerowania flagi wciśnietego przycisku. No bo teraz jak juz raz wciśniesz przycisk to ta flaga przycisk jest ustawiana na 1 i tak trwa w nieskończoność. Trzeba by ją wyzerować w tym if sprawdzającym czy ona jest ustawiona.<br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />I jeszcze jedno techniczne pytanie: czy to normalne że nie zawsze wgrywa mi się program do mikrokontrolera? Naciskam upload i proces wykonuje się poprawnie ale zawartość jednostki się nie zmienia, dopiero za drugim lub trzecim razem jest ok. Na początku wprowadzało to sporo zamętu.<br /></div><br />To napewno nie jest normalne. A czym wgrywasz program do procka? I jak masz wogóle ten układ zrobiony (na zestawie ATB, stykówce, płytka drukowana...)?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 1 sie 2016, o 13:41</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-08-01T11:31:30+01:00</updated>
<published>2016-08-01T11:31:30+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165188#p165188</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165188#p165188"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=165188#p165188"><![CDATA[
Rzeczywiście mój błąd, całość działa poprawnie aż do momentu próby dodania obsługi przycisku. Kiedy w drugim kroku dodaje instrukcje która ma się spełnić dopiero po wciśnięciu przycisku to wykonuje się ona od razu. Nie wiem czy źle interpretuje zasadę działania, sama instrukcja do obsługi przycisku działa poprawnie w innym programie. <br /><br />Cały czas kłopoty napotykam przy łączeniu obsługi przycisku i przerwań. nie jestem pewien czy takie wplatanie przycisków w procedury przerwań nie jest dla nich zbyt dużym obciążeniem?<br /><br />I jeszcze jedno techniczne pytanie: czy to normalne że nie zawsze wgrywa mi się program do mikrokontrolera? Naciskam upload i proces wykonuje się poprawnie ale zawartość jednostki się nie zmienia, dopiero za drugim lub trzecim razem jest ok. Na początku wprowadzało to sporo zamętu.<br /><br />[syntax=cpp]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />volatile uint16_t cnt=0;<br />int przycisk;<br /><br />int main(void)<br /><br />{<br /><br />  // I/O<br />  DDRB = 0b0111111;<br />  DDRC = 0b0111111;<br />  DDRD = 0b0011111;<br />  DDRD &amp;= ~(1&lt;&lt;PD4);<br /><br />  PORTD |= (1&lt;&lt;PD4);   //ustawienie stanu wysokiego na przycisku<br /><br />  // timer<br />  TIMSK |= (1&lt;&lt;TOIE0);                           //przerwanie overflow (przepełnienie timera)<br />  TCCR0 |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);                // źródłem CLK, preskaler 1024<br />  TCNT0 = 0;                                     //początkowa wartość licznika<br /><br />  przycisk=0;<br /><br />  sei();<br /><br />while(1)<br /><br />{<br /><br />if( !(PIND &amp; (1&lt;&lt;PD4))) //kiedy przycisk wcisniety zmienna przycisk=1<br />{<br />przycisk=1;<br />}<br /><br />switch(cnt)<br /><br />{<br /><br />case 80:// 1 krok : zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00001001;<br />PORTD = 0b00001010;<br />break;<br /><br />case 180:<br />if(przycisk==1)//kiedy przycisk=1<br />{<br />PORTD = 0b00000101;<br />}<br />break;<br /><br />case 280 : //2 krok : zielone i zolte dla pojazdow czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />przycisk=0;<br />PORTC = 0b00110110;<br />PORTB = 0b00010010;<br />PORTD = 0b00001010;<br />break;<br /><br />case 480: //3 krok :  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone dla pojazdow czerwone dla pieszych<br />PORTC = 0b00001001;<br />PORTB = 0b00100100;<br />PORTD = 0b00001010;<br />break;<br /><br />case 680: //4 krok :  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone i zolte dla pojazdow czerwone dla pieszych<br />PORTC = 0b00010010;<br />PORTB = 0b00110110;<br />PORTD = 0b00001010;<br />break;<br /><br />case 880: //5 krok : zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00001001;<br />PORTD = 0b00001010;<br />cnt=0;<br />break;<br /><br />}<br /><br />}<br /><br />}<br /><br />ISR(TIMER0_OVF_vect)//procedura obsługi przerwania od przepełnienia timera<br /><br />  {<br />  TCNT0 = 0;<br />  cnt++;<br />  }[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 1 sie 2016, o 11:31</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-07-28T14:26:01+01:00</updated>
<published>2016-07-28T14:26:01+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164932#p164932</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164932#p164932"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164932#p164932"><![CDATA[
No jak miała by działać ta pierwsza wersja skoro w pętli głównej wstawiłeś while(1); Czyli po inicjalizacji portów i timera nic się już dalej nie wykonuje oprócz oczywiście zwiększania cnt w przerwaniu. Ale jeśli usuniesz średnik za while, to zapewne i ta wersja będzie działać. A w obsłudze przerwania naprawdę wstawia się możliwie najkrótszy kod.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 28 lip 2016, o 14:26</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-07-27T10:41:21+01:00</updated>
<published>2016-07-27T10:41:21+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164811#p164811</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164811#p164811"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164811#p164811"><![CDATA[
Zrobiłem jak zasugerowałeś, jednak układ nie reaguje, nie wykonuje się żaden krok programu.<br /><br />Poniżej kod:<br /><br />[syntax=cpp]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />volatile uint16_t cnt=0;<br />int przycisk;<br /><br />int main(void)<br /><br />{<br /><br />  // I/O<br />  DDRB = 0b0111111;<br />  DDRC = 0b0111111;<br />  DDRD = 0b0011111;<br />  DDRD &amp;= ~(1&lt;&lt;PD4);<br /><br />  PORTD |= (1&lt;&lt;PD4);   //ustawienie stanu wysokiego na przycisku<br /><br />  // timer<br />  TIMSK |= (1&lt;&lt;TOIE0);                           //przerwanie overflow (przepełnienie timera)<br />  TCCR0 |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);                // źródłem CLK, preskaler 1024<br />  TCNT0 = 0;                                     //początkowa wartość licznika<br /><br />  przycisk=0;<br /><br />  sei();<br /><br />while(1);<br /><br />{<br /><br />if( !(PIND &amp; (1&lt;&lt;PD4)))<br />{<br />przycisk=1;<br />}<br /><br />switch(cnt)<br /><br />{<br /><br />case 80:// 1 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00001001;<br /><br />if(przycisk==1)<br />{<br />PORTD = 0b00001001;<br />}<br />break;<br /><br />case 160 : //2 sekwencja: zielone i zolte dla pojazdow czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00011011;<br />//PORTD = 0b00001001;<br />break;<br /><br />case 240: //3 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone dla pojazdow czerwone dla pieszych<br />PORTC = 0b00001001;<br />PORTB = 0b00100100;<br />//PORTD = 0b00000110;<br />break;<br /><br />case 320: //4 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone i zolte dla pojazdow czerwone dla pieszych<br />PORTC = 0b00011011;<br />PORTB = 0b00100100;<br />//PORTD = 0b00000110;<br />break;<br /><br />case 400: //5 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00001001;<br />//PORTD = 0b00001001;<br />cnt=0;<br />break;<br /><br />}<br /><br />}<br /><br />}<br /><br />ISR(TIMER0_OVF_vect)//procedura obsługi przerwania od przepełnienia timera<br /><br />  {<br />  TCNT0 = 0;<br />  cnt++;<br />  }[/syntax]<br /><br />Jednak trochę pozmieniałem wcześniejszą wersję i o dziwo działa, program się wykonuje a po naciśnięciu przycisku wykonuje się zawarta po nim pętla. Poniżej kod może się komuś przyda.<br /><br />[syntax=cpp]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />volatile uint16_t cnt=0;<br /><br />int przycisk;<br /><br />int main(void)<br />{<br />       // I/O<br />            DDRB = 0b0111111;<br />            DDRC = 0b0111111;<br />            DDRD = 0b0011111;<br />            DDRD &amp;= ~(1&lt;&lt;PD4);<br /><br />            PORTD |= (1&lt;&lt;PD4);<br /><br />            // timer<br />            TIMSK |= (1&lt;&lt;TOIE0);                           //przerwanie overflow (przepełnienie timera)<br />            TCCR0 |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);                // źródłem CLK, preskaler 1024<br />            TCNT0 = 0;                                     //początkowa wartość licznika<br /><br />            sei();<br /><br />while(1);<br /><br />}<br /><br />//procedura obsługi przerwania od przepełnienia timera<br />ISR(TIMER0_OVF_vect)<br />{<br />  TCNT0 = 0;<br />  cnt++;<br /><br />    {<br /><br />        przycisk=0;//jeśli przycisk wciśnięty to zmienna przycisk=1<br />        if( !(PIND &amp; (1&lt;&lt;PD4)))<br />        {<br />        przycisk=1;<br />        }<br /><br /><br /><br /><br />        if(cnt&gt;80)            // 1 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />        {<br /><br />         PORTC = 0b00100100;<br />         PORTB = 0b00001001;<br />         <br />              if(przycisk==1)//jeśli przycisk wciśnięty to oprócz zadanych stanów dochodzą jeszcze te z portu d<br />              {<br />                PORTC = 0b00100100;<br />                PORTB = 0b00001001;             <br />              PORTD = 0b00001001;             <br />              }<br /><br />        }<br /><br /><br /><br />        if(cnt&gt;160)          //2 sekwencja: zielone i zolte dla pojazdow czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />        {<br />        przycisk=0;<br />        PORTD = 0b00000000;<br />              PORTC = 0b00100100;<br />              PORTB = 0b00011011;<br />              if(przycisk==1)<br />                 {<br />                PORTD = 0b00001001;<br />                 }<br /><br />        }<br /><br />        if(cnt&gt;240)       //3 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone dla pojazdow czerwone dla pieszych<br />          {<br /><br />        PORTC = 0b00001001;<br />              PORTB = 0b00100100;<br />              if(przycisk==1)<br />                {<br />                PORTD = 0b00001001;<br />                }<br /><br />          }<br /><br />        if(cnt&gt;320)     //4 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone i zolte dla pojazdow czerwone dla pieszych<br />        {<br />              PORTC = 0b00011011;<br />              PORTB = 0b00100100;<br />              if(przycisk==1)<br />                {<br />                      PORTD = 0b00001001;<br />                }<br /><br />          }<br /><br />        if(cnt&gt;400)          //5 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />        {<br />              PORTC = 0b00100100;<br />              PORTB = 0b00001001;<br />              if(przycisk==1)<br />                {<br />                      PORTD = 0b00001001;<br />                }<br /><br />              cnt=0;<br />          }<br /><br />    }<br /><br />}[/syntax]<br /><br />Co prawda całość wymaga jeszcze totalnej optymalizacji, na razie jedynie mam szkielet tego jak mogło by być. Puki co zauważyłem że jeśli umieszczę opóźnienie lub spróbuje zmienić wartość cnt w pętli zagnieżdżonej w drugiej to program się wysypuje. Szału nie ma ale jest światełko w tunelu.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 27 lip 2016, o 10:41</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-07-20T15:07:29+01:00</updated>
<published>2016-07-20T15:07:29+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164360#p164360</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164360#p164360"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164360#p164360"><![CDATA[
Ja proponuje zrobić coś takiego. W obsłudze przerwania zostaw tylko inkrementację licznika cnt. Instrukcję switch przenieś do pętli while.<br />W pętli while musi też być zawarta obsługa przycisku. Ale nie z jakimś delayem i sterowaniem portem, tylko z ustawieniem flagi, że przycisk został wciśnięty. Musisz powołać po prostu jeszcze jedną zmienną.<br />W istrukcji switch umieszczasz wszystkie możliwe stany jakie mają być wyświetlane na semaforach, czyli z sekwencjami świateł dla pieszych tak jakby był wciśnięty przycisk. W instrukcji switch dla tych pozycji, które odpowiadają za włączenie świateł zielonych dla pieszych dodajesz na początku warunek if i sprawdzasz w nim czy ustawiona jest flaga włączenia przycisku. Jeśli tak to dana sekwencja switch się wykona. Jeśli nie ustawiasz cnt na nastepną pozycję która ma być wykonana. Dodatkowo w tej sekwencji switch, w której kończy się sterowanie światłami dla pieszych trzeba będzie skasować flagę przycisku. W ten sposób jesli nie był wciśnięty przycisk zmieniać się będą tylko światła dla samochodów, dla pieszych zawsze czerwone. Jeśli przycisk wciśnięty to zostanie wykonana dodatkowa sekwencja zmiany świateł dla pieszych. Mam nadzieję, że nie napisałem tego bardzo zawile.<br />I jeszcze taki drobiazg na koniec, main jest typu int a nie void.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 20 lip 2016, o 15:07</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-07-20T12:23:09+01:00</updated>
<published>2016-07-20T12:23:09+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164344#p164344</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164344#p164344"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=164344#p164344"><![CDATA[
Witam, udało się oprzeć cały schemat działania na instrukcji switch, ale mimo wielu prób nie mogę zaadoptować udziału przycisku w całej procedurze. Umieszczałem instrukcje obsługi przycisku w poszczególnych case, w pętli głównej i nijak nie chce działać. Powątpiewam już czy możliwe jest użycie w jednym programie przerwań od przepełnienia timera i przycisku w czasie realnym.<br /><br />Poniżej poprawiony kod i instrukcja do przycisku w komentarzu pod nim.<br /><br />[syntax=cpp]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />volatile uint16_t cnt=0;<br />int przycisk;<br /><br />void main(void)<br /><br />{<br /><br />// I/O<br />DDRB = 0b0111111;<br />DDRC = 0b0111111;<br />DDRD = 0b0011111;<br />DDRD &amp;= ~(1&lt;&lt;PD4);<br /><br />PORTD |= (1&lt;&lt;PD4);   //ustawienie stanu wysokiego na przycisku<br /><br />// timer<br />TIMSK |= (1&lt;&lt;TOIE0);                           //przerwanie overflow (przepełnienie timera)<br />TCCR0 |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);                // źródłem CLK, preskaler 1024<br />TCNT0 = 0;                                     //początkowa wartość licznika<br /><br />sei();<br /><br />while(1);<br /><br />}<br /><br />ISR(TIMER0_OVF_vect)//procedura obsługi przerwania od przepełnienia timera<br />{<br />TCNT0 = 0;<br />cnt++;<br /><br />{<br /><br />switch(cnt)<br /><br />{<br /><br />case 80:// 1 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00001001;<br />PORTD = 0b00001001;<br />break;<br /><br />case 160 : //2 sekwencja: zielone i zolte dla pojazdow czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00011011;<br />PORTD = 0b00001001;<br />break;<br /><br />case 240: //3 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone dla pojazdow czerwone dla pieszych<br />PORTC = 0b00001001;<br />PORTB = 0b00100100;<br />PORTD = 0b00000110;<br />break;<br /><br />case 320: //4 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone i zolte dla pojazdow czerwone dla pieszych<br />PORTC = 0b00011011;<br />PORTB = 0b00100100;<br />PORTD = 0b00000110;<br />break;<br /><br />case 400: //5 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />PORTC = 0b00100100;<br />PORTB = 0b00001001;<br />PORTD = 0b00001001;<br />cnt=0;<br />break;<br /><br />}<br />}<br />}<br /><br />/*instrukcja do przycisku  <br />                           <br /> if( !(PIND &amp; (1&lt;&lt;PD4)))<br />{<br />PORTB ^= 0b0111111;<br />         _delay_ms(3000);<br />}<br /><br />*/[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 20 lip 2016, o 12:23</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-07-01T20:30:25+01:00</updated>
<published>2016-07-01T20:30:25+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163234#p163234</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163234#p163234"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163234#p163234"><![CDATA[
Rzeczywiście cały trzon programu będzie się realizował w pętli głównej, cnt będzie jedynie wyznaczały takty zmian świateł. Na pewno spróbuje to wcielić w życie tylko nie fartownie zaczynam urlop więc najszybciej za około dwa tygodnie. Dam znać czy udało mi się uporać z problemem.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 1 lip 2016, o 20:30</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-07-01T13:02:15+01:00</updated>
<published>2016-07-01T13:02:15+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163198#p163198</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163198#p163198"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163198#p163198"><![CDATA[
Nie no, nie jest tak źle. Powinieneś w przerwaniu tylko zwiększać wartość licznika cnt. Resztę przenieś do pętli głównej i tam sprawdzaj warunki, jaki jest stan. Jeśli zrobisz to instrukcją if to porównuj konkretną wartość np. if(cnt==160). Wtedy faktycznie wykona się tylko warunek dla tej wartości. To wystarczy bo wtedy ma się zmienić układ świateł. Potem przez chwilę nic się nie dzieje. Dopiero jak zostanie osiągnięty następny warunek nastąpi kolejna zmiana. Świetnie nadaje się do tego właśnie istrukcja switch().<br />[syntax=c]switch(cnt)<br />{<br />  case 80: /*tu wpisujesz odpowiednią wartość do portu*/ break;<br />  case 160: /* następna wartość*/ break;<br />  //i tak dalej<br />  case 400: cnt = 0; /*następna wartość*/ break;<br />}[/syntax]<br />Spróbuj tylko pokombinować jak w zależności od stanu przycisku dodać wykonywanie dodatkowych pozycji wyświetlania świateł.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 1 lip 2016, o 13:02</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-07-01T06:38:12+01:00</updated>
<published>2016-07-01T06:38:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163183#p163183</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163183#p163183"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163183#p163183"><![CDATA[
Rzeczywiście gołym okiem w tym przypadku nie widać tego problemu, dzięki za zwrócenie uwagi. Gdyby to rzutowało na działanie programu to może użycie _delay_ms z krótkim czasem pod koniec pętli rozwiązało by problem? Choć czytałem żeby go unikać w przerwaniach, ale w sumie i tak nie zamuli programu bo cały mój główny program to to przerwanie.<br /><br />Po dłuższych próbach i konsultacjach mam wrażenie że w takiej formie ten program nie ma racji bytu, muszę albo go gruntownie przebudować albo zacząć od nowa. Obsługę przycisków prawdopodobnie muszę zawrzeć w głównej pętli, w przerwaniach się raczej  nie sprawdzą.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 1 lip 2016, o 06:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-06-30T19:28:49+01:00</updated>
<published>2016-06-30T19:28:49+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163172#p163172</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163172#p163172"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163172#p163172"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Ogólnie wszystkie wartości zawarte w instrukcjach pętli ustawiają żądaną konfigurację diod. Co do zliczania cnt, to wydaje mi się, że kiedy dojdzie do 80 ustawia konfiguracje z tej pętli, dalej liczy i ustawia kolejną, tą ze 160. Sprawdziłem to na płytce, cały cykl przejścia świateł działa poprawnie.<br /></div><br /><br />Ale jeśli w if masz warunek cnt&gt;80, to oczywiście , że dla wartości 160 wykona się kolejny if ale wczesniej na ułamek sekundy wykona się też warunek poprzedni. Dla kazdej następnej wartości cnt będą się wykonywały warunki poprzednie. Dzieje się to bardzo szybko i nawet tego nie zauważysz. W tym przypadku to zapewne nie jest problem, ale chodzi o pewne zasady w programowaniu i zrozumienie jak się to będzie wykonywać. W pewnych przypadkach to może być poważny problem, a co najgorsze bardzo trudny do wychwycenia.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 30 cze 2016, o 19:28</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[maverick_as]]></name></author>
<updated>2016-06-29T15:49:30+01:00</updated>
<published>2016-06-29T15:49:30+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163093#p163093</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163093#p163093"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163093#p163093"><![CDATA[
<div class="quotetitle">black_currant napisał(a):</div><div class="quotecontent"><br />Co do komentarzy i sposobu pisania kodu to rzeczywiście jeszcze nie nabrałem nawyku, czytałem o tym że to ułatwia prace z kodem tylko kwestia żebym się przyzwyczaił.<br /></div><br />Przyjmij na wiarę, warto dodawać komentarze <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> !<br />Zdziwisz się , jak po pewnym czasie powrócisz do  własnego kodu (bez komentarzy), zaczniesz go analizować i dojdziesz do wniosku...: &quot;co autor miał na myśli ?&quot;.<br />Nie komentowanie programu to bardzo pozorna oszczędność czasu.<br />Pozdr.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9169">maverick_as</a> — 29 cze 2016, o 15:49</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-06-29T14:55:09+01:00</updated>
<published>2016-06-29T14:55:09+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163091#p163091</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163091#p163091"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163091#p163091"><![CDATA[
Jeśli chodzi o rozszycie diod to w układzie mam dwie pary świateł dla każdej z dróg (proste skrzyżowanie, dwie przecinające się drogi), dla pojazdów i pieszych.<br /><br />Pierwsza z dróg: PB2,PB5-czerwone ; PB1,PB4-żółte ; PB0,PB3-zielone ; PD3,PD2-czerwone,zielone dla pieszych;<br /><br />Druga z dróg: PC5,PC2-czerwone ; PC4,PC1-żółte ; PC3,PC0-zielone ; PD1,PD0-czerwone,zielone dla pieszych;<br /><br />Co do komentarzy i sposobu pisania kodu to rzeczywiście jeszcze nie nabrałem nawyku, czytałem o tym że to ułatwia prace z kodem tylko kwestia żebym się przyzwyczaił.<br /><br />Ogólnie wszystkie wartości zawarte w instrukcjach pętli ustawiają żądaną konfigurację diod. Co do zliczania cnt, to wydaje mi się, że kiedy dojdzie do 80 ustawia konfiguracje z tej pętli, dalej liczy i ustawia kolejną, tą ze 160. Sprawdziłem to na płytce, cały cykl przejścia świateł działa poprawnie. Chciałem aby wciśnięcie przycisku zmieniało wartość cnt, tak aby kiedy przycisk nie jest wciśnięty cykl światła czerwonego dla pojazdów trwał dwa razy dłużej (po przez ustawienie wartości cnt tak aby powtórzyć pętle), kiedy pieszy wciska przycisk krócej czeka. Kwestia czy realizacja jest możliwa.  <br /><br />Z flagą walczyłem dziś rano, ale muszę jeszcze zgłębić temat bo wychodziły mi dziwne rzeczy. Jeśli chodzi o switch to rzeczywiście pozwoliło by to rozpatrzenie kilku wariantów, z wciśniętym przyciskiem lub nie.<br /><br />Po szybkiej lekturze artykułu na temat maszyny stanów, wydaje mi się że pasował by idealnie, tylko kwestia doboru narzędzi w postaci timerów i obsługi przycisków.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 29 cze 2016, o 14:55</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[janusz17]]></name></author>
<updated>2016-06-29T13:04:02+01:00</updated>
<published>2016-06-29T13:04:02+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163084#p163084</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163084#p163084"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163084#p163084"><![CDATA[
Trochę trudno to analizować bo nic nie piszesz o tym gdzie masz podłączone lampki.<br />Ale ponieważ dopiero się uczysz, to staraj się bardziej czytelnie pisać kod. Dodawaj komentarze. Wpisywanie wartości do portu w postaci binarnej nie jest dobrym pomysłem. Nie ma potrzeby inicjalizować zerem portów mikrokontrolera bo one sa zerowane po resecie. To samo dotyczy rejestru TCNT. W tym przypadku może nie ma to dużego znaczenia , ale kod realizowany w przerwaniu powinien być jak najkrótszy. Zwróć też uwagę, że w tym kodzie dla cnt=80 wykona się tylko pierwszy warunek. Jednak im większa wartość cnt to bedą się wykonywać kolejno wszystkie warunki po kolei, a to chyba nie tak ma działać. Tu raczej bardziej pasowała by instrukcja switch().<br />Co do samej ideii działania takiego układu to ja zrobił bym to tak. Powołuje sobie zmienną - taką flagę w której będzie zapisana informacja czy przycisk został wciśnięty. Światła powinny normalnie się przełączać z pominieciem stanu włączenia zielonego dla pieszych. Dopiero kiedy spełniony jest warunek, że przycisk został wciśnięty powinna  wykonywać sie dodatkowa sekwencja włączenia światła zielonego dla pieszych.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1226">janusz17</a> — 29 cze 2016, o 13:04</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[maverick_as]]></name></author>
<updated>2016-06-29T06:40:53+01:00</updated>
<published>2016-06-29T06:40:53+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163058#p163058</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163058#p163058"/>
<title type="html"><![CDATA[Re: sterowanie sygnalizacją świetlną na skrzyżowaniu drogowy]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163058#p163058"><![CDATA[
Witaj,<br />sugeruję lekturę na temat; maszyny stanów.<br />Na początek np. to:<br /><!-- m --><a class="postlink" href="http://ep.com.pl/files/1436.pdf" >http://ep.com.pl/files/1436.pdf</a><!-- m --><br /><br />Z pomocą forumowej &quot;szukajki&quot; znajdziesz posty odnośnie jej (maszyny stanów) implementacji na AVR. <br />Pozdr.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9169">maverick_as</a> — 29 cze 2016, o 06:40</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[black_currant]]></name></author>
<updated>2016-06-29T15:03:04+01:00</updated>
<published>2016-06-28T21:09:19+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163049#p163049</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163049#p163049"/>
<title type="html"><![CDATA[sterowanie sygnalizacją świetlną na skrzyżowaniu drogowym]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15678&amp;p=163049#p163049"><![CDATA[
Witam, w oparciu o artykuł &quot;LED sterowany przez Timer&quot; który opracował <strong>drzasiek</strong>  postanowiłem spróbować napisać program sterujący sygnalizacją świetlną na skrzyżowaniu drogowym. <br /><br />Jeśli chodzi o sam proces zmiany świateł to nie miałem żadnych problemów, kłopoty zaczęły się kiedy chciałem dodać przycisk dla pieszych który miał by skracać czas trwania światła zielonego dla samochodów. Całą idę oparłem na schemacie że jeżeli zmienna pomocnicza licznika przekroczy odpowiednią wartość to zostanie wykonana instrukcja zawarta w pętli if ( if(cnt&gt;...) ), w moim przypadku zmieni się stan diod.  <br /><br />Kiedy umieszczam podobną instrukcję ale zawierającą obsługę przycisku lub zerowanie cnt, program zaczyna dziwnie reagować, albo nie wykonują się żadne zmiany stanu diod albo działa tylko instrukcja obsługiwana przez przycisk. Wydaje mi się, że albo wpisuje ją w złym miejscu albo ma ona złą formę. Same połączenie przycisku oraz kod który go uruchamia raczej są w porządku gdyż w innym testowym programie zapalają i gaszą diody.<br /><br />Jak zapewne nie trudno wywnioskować z powyższej lektury jeśli chodzi o mikrokontrolery dopiero zaczynam swoją przygodę, chciał bym prosić o sugestie czy w oparciu o taki timer i techniki których próbuje użyć do rozwiązania tego problemu ten projekt ma rację bytu? Ewentualnie jak inaczej można by podejść do zagadnienia przycisku dla pieszych na takim domniemanym skrzyżowaniu? <br /><br />Na samym dole kodu zamieściłem w komentarzach dwie pętle których próbowałem użyć, zawarte w nich instrukcje mają charakter jedynie testowy.<br /><br />Kod programu:<br /><br />[syntax=cpp]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />volatile uint16_t cnt=0;<br /><br />void main(void)<br />{<br /> // I/O<br />DDRB = 0b0111111;<br />DDRC = 0b0111111;<br />DDRD = 0b0011111;<br />DDRD &amp;= ~(1&lt;&lt;PD4);<br />// stany poczatkowe<br />PORTB = 0b00000000;<br />PORTC = 0b00000000;<br />PORTD = 0b00000000;<br /><br />PORTD |= (1&lt;&lt;PD4);<br /><br /> // timer<br /> TIMSK |= (1&lt;&lt;TOIE0);           //przerwanie overflow (przepełnienie timera)<br /> TCCR0 |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00); // źródłem CLK, preskaler 1024<br /> TCNT0 = 0;//          //początkowa wartość licznika<br /><br /> sei();<br /><br /> while(1);<br /><br />}<br /><br />//procedura obsługi przerwania od przepełnienia timera<br />ISR(TIMER0_OVF_vect)<br />{<br />  TCNT0 = 0;<br />  cnt++;<br /><br />{<br /><br />  if(cnt&gt;80)            // 1 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />  {<br />  PORTC = 0b00100100;<br />  PORTB = 0b00001001;<br />  PORTD = 0b00001001;<br />    //cnt=0;<br />  }<br /><br />  if(cnt&gt;160)          //2 sekwencja: zielone i zolte dla pojazdow czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />    {<br />    PORTC = 0b00100100;<br />    PORTB = 0b00011011;<br />    PORTD = 0b00001001;<br />      //cnt=0;<br />    }<br /><br />  if(cnt&gt;240)       //3 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone dla pojazdow czerwone dla pieszych<br />      {<br />      PORTC = 0b00001001;<br />      PORTB = 0b00100100;<br />      PORTD = 0b00000110;<br />        //cnt=0;<br />      }<br /><br />  if(cnt&gt;320)     //4 sekwencja:  czerwone dla pojazdow, zielone dla pieszych, druga droga zielone i zolte dla pojazdow czerwone dla pieszych<br />        {<br />        PORTC = 0b00011011;<br />        PORTB = 0b00100100;<br />        PORTD = 0b00000110;<br />          //cnt=0;<br />        }<br /><br />  if(cnt&gt;400)          //5 sekwencja: zielone dla pojazdow,czerwone dla pieszych,druga droga czerwone dla pojazdow zielone dla pieszych<br />    {<br />    PORTC = 0b00100100;<br />    PORTB = 0b00001001;<br />    PORTD = 0b00001001;<br />      cnt=0;<br />    }<br /><br />}<br />}<br /><br /><br />        /*<br /><br />     if( !(PIND &amp; (1&lt;&lt;PD4)))<br />         {<br />     PORTB ^= 0b0111111;   <br />     _delay_ms(3000);<br />         }<br /><br />    if( !(PIND &amp; (1&lt;&lt;PD4)))<br />            {<br />         cnt=0;<br />            }<br /><br />            */[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14329">black_currant</a> — 28 cze 2016, o 21:09</p><hr />
]]></content>
</entry>
</feed>