Skocz do zawartości

Komunikacja PC z uC


mikroice90

Pomocna odpowiedź

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;*/
}
Link do komentarza
Share on other sites

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"

Link do komentarza
Share on other sites

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;
}
} 
} 
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.