Skocz do zawartości

Pomocna odpowiedź

Napisano

Witam, mam problem związany z komunikacją PC z uC a tak naprawdę wydawaniem poleceń(sterowaniem) uC spod PC. Poniżej zamieszczam kod, który działa pod uC. Niestety gdy wyślę z aplikacji w C# wartość 128 następuje wejście do case 128 wysłanie wartości PIND0 lecz po przejściu całej pętli while program zatrzymuje się (czeka) na warunku bit=odbierz(); Jak sprawdziłem w UDR cały czas przechowywana jest jakaś wartość tzn. warunek z funkcji odbierz, który czeka na pusty bufor wstrzymuje prace programu. Czy ktoś ma pomysł jak temu zaradzić?

#include <avr/io.h>
#include <util/delay.h>
# include <inttypes.h>
#define F_CPU 16000000
void USART_Init(void)
{
UCSRC = (1<<URSEL)|(1<<UPM1)|(1<<UCSZ1)|(1<<UCSZ0);
// URSEL = 1 - korzystanie z rejestru UCSRC
// UPM1 = 1 even parity
// UCSZ1 = 1 i UCSZ0 = 0 8 bitowa transmisja
UBRRL = 103; // 9600bps przy F_CPU 16Mhz
UCSRB = (1<<RXEN)|(1<<TXEN);
}
void nadaj(char dana1)
{
while(!(UCSRA&(1<<UDRE)));
UDR=dana1;
}
uint8_t odbierz(void)
{
//while(!(UCSRA&(1<<RXC)));
return UDR;
}

int main(void)
{
USART_Init();
DDRB = 0xFF;
PORTB = 0xFF;
DDRD = 0;		// input - przycisk startu nadawania
PORTD = 0xFF;		// poczatkowo nie pracuje //1
DDRC = 0;			// nadawanie zer
PORTC = 0xFF;		// przy rozwartym przycisku daje jedynke	
unsigned char Push, Transmit;
uint8_t bit;
Transmit = Push = 0;
   for(;;)
   {
	bit =0;
	bit = odbierz();
	PORTB = ~bit;
	if(bit_is_clear(PINC,0)) Push = 1;
	switch(bit)
	{
		case(128):	
			{
				Transmit = 1;
				if(Push==1) nadaj(~PIND0);
				if(Push==0) nadaj(PIND0);
				break;
			} 
		case(129):
			{
				Transmit = 0;
				break;
			}
		default:
			{
				if(Transmit == 1) nadaj(PIND0);
				break;
			}
	}
	Push = 0;

}	

	/*while(PORTD == 0xFE)
		{
			PORTB = 0xFE;
			bit = PINC0;
			if(bit_is_clear(PINC,0)) bit = ~bit;
			nadaj(bit);
			if(bit_is_clear(PIND,0)) {PORTD ^= 0x01; _delay_ms(50);}
		}				
		if(bit_is_clear(PIND,0)) {PORTD ^= 0x01; _delay_ms(50);}
		PORTB = 0xFF;*/
}

Ale jak poprzez obsługę przerwania spowodować, że np. po przesłaniu 0x80 (128) uC rozpocznie nadawanie i będzie nadawał aż do otrzymania 0x81 (129) ?

Musiałbym zdefiniować zmienne globalne, których wartość zmienia obsługa przerwania. A w wiecznej pętli postawić warunek np.

ISR (UART_RXC_vect)
{
if(UDR == 0x80) Transmit = 1;
if(UDR == 0x81) Transmit = 0;
}
void main(void)
{
while(1)
 {
   if(Transmit ==1) nadaj(PIND0);
 }
}

Czy tak miałoby to wyglądać i czy to ma szanse powodzenia?

__________

Komentarz dodany przez: Nawyk

Dodałem znaczniki "code"

Zakładając, że nie zamierzasz odbierać więcej niż jeden bajt danych, możesz użyć jednej zmiennej globalnej, do której wpisujesz odebrany znak, a w pętli głownej dokonać jego porównania, a potem wyzerować. Z grubsza wyglądało by to tak:

volatile char byte;
ISR (UART_RXC_vect) 
{ 
byte = UDR; 
} 
void main(void) 
{ 
while(1) 
{ 
switch(byte){
case 0x80:
//jakas czynnosc
byte = 0x00;
break;
case 0x90:
//inna czynnosc;
byte = 0x00;
break;
}
} 
} 

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...