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

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

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=12789&amp;mode</id>
<entry>
<author><name><![CDATA[PrzemRS]]></name></author>
<updated>2015-08-29T20:46:11+01:00</updated>
<published>2015-08-29T20:46:11+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12789&amp;p=138595#p138595</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12789&amp;p=138595#p138595"/>
<title type="html"><![CDATA[UART half-duplex]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12789&amp;p=138595#p138595"><![CDATA[
Witam,<br /><br />Mam do zrealizowania transmisję half-duplex na uarcie przez moduł HC-12. Kombinowałem aby zrobić coś na kształt semafora binarnego, lecz niestety nie za bardzo mi to wychodzi. Korzystam z lekko zmodyfikowanej biblioteki obsługi portu szeregowego naskrobanej przy okazji czytania BB. Same funkcje obsługi semafora wyglądają następująco:<br />[syntax=c]#if USART_HALF_DUPLEX == 1<br /><br />volatile semaphore_t semaphore_indicator;// Wskaźnik zajętości zasobów 0 - zasoby wolne, 1 - zasoby zajęte<br />uint8_t USART_semaphore_check()// Sprawdzenie dostępności zasobów<br />{<br />if(!semaphore_indicator.state)<br />return semaphore_indicator.state;// Zasoby wolne<br />else<br />return semaphore_indicator.user;// Zasoby zajęte przez Rx lub Tx<br />}<br />uint8_t USART_semaphore_take()// Pobranie semafora - możliwość nadawania<br />{<br />if(!semaphore_indicator.state)<br />return ++semaphore_indicator.state;<br />else<br />return 0;<br /><br />}<br />uint8_t USART_semaphore_give()// Zwolnienie semafora - możliwość odbierania<br />{<br />if(semaphore_indicator.state)<br />return semaphore_indicator.state--;<br />else<br />return 0;<br />}<br />#endif[/syntax]<br /><br />Dalej jest to wykorzystywane w funkcji do transmitowania znaku i w jego przerwaniu:<br />[syntax=c]// Definicja funkcji wysyłania jednego znaku<br />void USART_TxData_char(unsigned char data)<br />{<br />uint8_t tmp_head;<br /><br />ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {<br />tmp_head  = (UART_TxHead + 1) &amp; UART_TX_BUF_MASK;<br />}<br />    // Pętla oczekuje jeżeli brak miejsca w buforze cyklicznym na kolejne znaki<br />    while ( tmp_head == UART_TxTail ){}<br /><br />    UART_TxBuf&#91;tmp_head&#93; = data;<br />    UART_TxHead = tmp_head;<br /><br />    // Inicjalizujemy przerwanie występujące, gdy bufor jest pusty, dzięki<br />    // czemu w dalszej części wysyłaniem danych zajmie się już procedura<br />    // obsługi przerwania<br />#if USART_HALF_DUPLEX == 0<br />    UCSRB |= (1&lt;&lt;UDRIE);<br />#endif<br />#if USART_HALF_DUPLEX == 1<br />    if(USART_semaphore_check() == 0)<br />    {<br />    USART_semaphore_take();<br />    semaphore_indicator.user = 1;<br />    UCSRB |= (1&lt;&lt;UDRIE);<br />    }[/syntax]<br /><br />[syntax=c]// definiujemy procedurę obsługi przerwania nadawczego, pobierającą dane z bufora cyklicznego<br />ISR( USART_UDRE_vect)  {<br />    // sprawdzamy czy indeksy są różne<br />    if ( UART_TxHead != UART_TxTail ) {<br />    // obliczamy i zapamiętujemy nowy indeks ogona węża (może się zrównać z głową)<br />    UART_TxTail = (UART_TxTail + 1) &amp; UART_TX_BUF_MASK;<br />    // zwracamy bajt pobrany z bufora  jako rezultat funkcji<br />    UDR = UART_TxBuf&#91;UART_TxTail&#93;;<br />    } else {<br />// zerujemy flagę przerwania występującego gdy bufor pusty<br />UCSRB &amp;= ~(1&lt;&lt;UDRIE);<br />#if USART_HALF_DUPLEX == 1<br />if(USART_semaphore_check() == 1)<br />{<br />USART_semaphore_give();<br />semaphore_indicator.user = 0;<br />}<br />#endif<br />    }<br />}[/syntax]<br /><br />Pobieranie semafora przez nadawcę realizuję zewnętrznie przez wywoływanie z interpretera poleceń następujących funkcji:<br />[syntax=c]void semgive( void )        // Zwolnienie semafora<br />{<br />USART_semaphore_give();<br />semaphore_indicator.user = 0;<br />}<br /><br />void semtake( void )                        // Pobranie semafora<br />{<br />USART_semaphore_take();<br />semaphore_indicator.user = -1;<br />}[/syntax]<br /><br />Mimo to gdy odpalam interpreter poleceń to rozpoznaje tylko jedną komendę a dalej już nie działa. Lepiej to zobrazuje filmik, ponieważ ciężko mi to opisać <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> <br /><br /><div style="width: 583px; height: 471px; margin: 0 auto; padding-left: 26px; padding-top: 48px; background: url('https://www.atnel.pl/download/atnel_tv.png') no-repeat;"> <strong>iframe</strong> </div><br /><br />Na filmie widać, że po semtake można wprowadzić semgive i oddaje semafor i wszystko wraca do normy, działają polecenia fwd i rwd oraz stop. po wprowadzeniu komendy semtake i fwd widać, że diody gasną, a już po wprowadzaniu kolejnych poleceń nic się nie dzieje. <br /><br />Czy to będzie problem z semaforem czy może z interpreterem poleceń? Interpreter jest &quot;gotowy&quot; od Pascala Stanga.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=6607">PrzemRS</a> — 29 sie 2015, o 20:46</p><hr />
]]></content>
</entry>
</feed>