????????基本思路是觸發(fā)串口接收中斷之后,在串口中斷服務函數(shù)中處理接收到的字節(jié)并將其連接成字符串存入全局變量中。
隱含的額外工作有:
1.區(qū)分是發(fā)送中斷還是接收中斷,兩者都會進入同一個中斷服務子函數(shù);
2.判斷已接收到了句末,暫停接收,并通過標志位告知其他函數(shù)。
串口初始化省略,網(wǎng)上到處都是,但基本都是做到串口回聲為止,教接收數(shù)據(jù)的少,所以著重講如何接收字符串。
uart.h中需要添加的用于存放相關(guān)數(shù)據(jù)的全局結(jié)構(gòu)體:
typedef struct
{
u8 buff[65]; //用于存放接收到的字符串
u8 flag; //接收完成中斷標志位
u8 len; //用于偏移字符串指針,可以理解為長度,如果buff設(shè)得很長,對應這里需要改成u16
}REC;
extern REC UART_rec;//設(shè)為全局
uart.c中中斷服務子函數(shù):
REC UART_rec={0}; //初始化結(jié)構(gòu)體
void UART(void) interrupt 4
{
u8 temp=0;
RI=0;//清除接收中斷標志
temp=SBUF;
if(temp==0||temp=='\r'||temp=='\n'||UART_rec.len>=65||temp=='{')
{
UART_rec.buff[UART_rec.len]='\0';
UART_rec.flag=1; //數(shù)據(jù)包接收完成標志
UART_rec.len=0; //為下一個數(shù)據(jù)包做準備
}
else
{
UART_rec.buff[UART_rec.len++]=temp;
}
?其中:
if(temp==0||temp=='\r'||temp=='\n'||UART_rec.len>=65||temp=='{')
可以自定義各自接收完畢的標準,包括常規(guī)的回車以外還有到達指定長度結(jié)束以及MQTT數(shù)據(jù)包的封裝'{',可以用來丟棄封裝的開頭節(jié)省一些字節(jié)之類的;
main.c測試:
void main (void)
{
UART_Config(); //串口初始化,本文不涉及
printf("Hello!\r\n");
while(1)
{
if(UART_rec.flag)//若接收完成
{
printf("接收到了:%s\r\n",UART_rec.buff);
UART_rec.flag=0; //接收標志位清零,準備接收下一字符串
}
}
}
串口助手現(xiàn)象:
接收ASCII:
?接收中文:
接收帶空格的句子(順便測試了超出長度的情況):
不足:
1.必須要有句末的標志,若不發(fā)送\r、\n、\r\n結(jié)尾將不會結(jié)束接收;
2.某些情況下句末標志為\r\n時將會吞掉下一句的開頭第一個字節(jié),比如通過串口發(fā)送數(shù)據(jù)到PC之后的下一次接收不能接收以\r\n結(jié)尾的數(shù)據(jù)。評論區(qū)可以討論一下解決方法,也教教我。
如果是STM32可以通過串口空閑中斷來判斷接收完畢,更穩(wěn)妥,不會出現(xiàn)這兩個問題文章來源:http://www.zghlxwxcb.cn/news/detail-419635.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-419635.html
到了這里,關(guān)于51單片機UART串口通信實現(xiàn)接收PC的字符串的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!