我从我的Pc串行发送4个字节的数据到我的atmega16。我用UART。一种技术是使用数据表中给出的函数,但是当它们使用轮询时,它们会阻止其余的代码。所以我正在使用while循环。 但是当while循环开始时我无法理解代码的结构..请帮助我。日Thnx
#include <avr/io.h>
#define FOSC 1843200// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
void UART_Init( unsigned int ubrr)
{
/* Set baud rate */
UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}
int main( void )
{
int i = 0;
unsigned char my_data [4];
UART_Init ( MYUBRR );
while (1)
{
if (UCSRA & (1<<RXC))
{
my_data[i] = UDR;
}
i++;
if (i == 3)
{
/*my next code here and once thats done, its again in uart receive mode*/
i = 0;
}
}
}
答案 0 :(得分:2)
我已经接受了while循环并在他们旁边放了评论,所以希望你理解它:)
while (1)
{
if (UCSRA & (1<<RXC)) //If Usart control and status register A and Receive complete flag are true (Comparing the register with the value of RXC, which is a bit in the register)
{
my_data[i] = UDR; //Read Usart Data Register, which is 1 byte
i++; //Like Joachim Pileborg said, this should be in the if statement
}
if (i == 3) //If received your 4 bytes.
{
/*my next code here and once thats done, its again in uart receive mode*/
//Do something with the data
i = 0;
}
}
我希望现在很清楚! 顺便说一下:你现在也在不断地查询数据,所以这与你的想法没有任何不同。
答案 1 :(得分:1)
如果您不想使用阻塞轮询,则需要对传入数据进行中断驱动处理。 基本上,你会用你的代码写一个RX-Complete-ISR:
my_data[i] = UDR; //Read Usart Data Register, which is 1 byte
i++; //Like Joachim Pileborg said, this should be in the if statement
(当然,您需要打开一般的中断(sei();
),USART会在收到任何数据之前收到完整的中断。)
然后,在主循环中,您可以执行其他任务并通过
进行检查if (i == 3) //If received your 4 bytes.
{
/*my next code here and once thats done, its again in uart receive mode*/
//Do something with the data
i = 0;
}
如果您的ISR已收到所有字节。
您可能需要注意一些同步问题,例如将我声明为volatile
,但这是以最高效的方式完成的。