STC系列单片机串口通信的总结

更新时间:2024-01-11 09:27:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

串口通信:

软件调试,在调试过程中需要使用虚拟串口助手。在编程中注意设计时钟和波特率。注意程序的串口设置和串口调试助手中串口设置相同。 单串口:

mode com2 9600,0,8,1 assign com2 sout stime = 0 多串口:

mode com2 9600,0,8,1 assign com2 s0out 0表示单片机的串口0 编程:

STC12介绍的方法:

接收一个字节的函数和发送字符串的函数,发送字符串需要知道字符串的长度。对于接收字符串的函数,可以仿照通过调用接收一个字节的函数,写出接收字符串函数。 void WriteUart(uchar *pucData ,uchar ucLength) { if(ucLength == 0) { return; } if(UartBuzy == 1) return; ucSendLength = ucLength; pucSendData = pucData; SBUF = *pucSendData; UartBuzy = 1; ucSendedCount = 0; }

uchar ReadUart(void) { uchar Data; Data = ucRecData; ucRecData = 0; return Data; }

Unsigned char RString(unsigned char *s, unsigned int len) {

Unsigned int i; For(i =0;i

*s++ = ReadUart(); } }

void UartIRQ(void) interrupt 4 {

if(RI) { RI = 0; ucRecData = SBUF; } if(TI) { TI = 0; ucSendedCount++; if(ucSendedCount >= ucSendLength) { UartBuzy = 0; return; } else { SBUF = *(pucSendData + ucSendedCount); } } }

STC15:

STC15只给出了发送函数,且发送函数有瑕疵,具体见最后分析。 void UART1_ISR(void) interrupt 4 using 1 {

if (RI) //接收数据 {

RI = 0; //清除RI位 }

if (TI) //发送数据 {

TI = 0; //清除TI位 busy = 0; //清忙标志 } }

void SendData(unsigned char dat) {

while (busy); //等待前面的数据发送完成 busy = 1;

SBUF = dat; //写数据到UART数据寄存器 }

void SendString(char *s) {

while(*s) //检测字符串结束标志 {

SendData(*s++); //发送当前字符 } }

SendString()字符串函数,当遇到发送的字符串里面有0x00就会终止,实用性不强。SendData()函数中三条语句的顺序容易引起死机。

比较好的处理串口接收一个字节数据的方法,不采用中断处理标志位。通过关中断,然后处理串口接收标志,从而减少在处理过程中因为触发中断而造成的死循环。修改好的串口接收一个字节的代码(这是采用的串口2接收一个字节数据的处理函数,其控制寄存器不支持位操作)如下:

void SendData(BYTE dat) {

EA = 0; S2BUF = dat; //SBUF=dat

while (!(S2CON & S2TI)); //等待前面的数据发送完成 while(TI); S2CON &= ~S2TI; //TI = 0; EA = 1; }

Unsigned char SendString(unsigned char *s, unsigned int len) {

Unsigned int i; For(i =0;i

SendData(*s++); } }

一个比较好的接收处理框架(利用通信协议): void UART1_ISR(void) interrupt 4 using 1 { unsigned char sbuffer; if(RI) {

RI = 0;

sbuffer = SBUF; if(nflag == 0) { REC_MAX = REC_MAX_NAME ; } else REC_MAX = REC_MAX_DATA;

if((sbuffer == CHECK_HEAD) && (Rec_Flag == 0))//如果收到文件头而且当前未接收

{

Rec_Flag = 1; Rec_Len = 0;

uarttext[0] = sbuffer; // 这里保留了包头 }

else if(Rec_Flag) // 开始接收 {

if(Rec_Len < (REC_MAX - 1)) { Rec_Len++;

uarttext[Rec_Len] = sbuffer; // 当数据送缓冲区 }

else if(Rec_Len == (REC_MAX - 1)) // 接收完成 { /* if(uarttext[Rec_Len] == CHECK_TAIL) // 表明接收成功未出错 { // }

else // 有误码 {

}

Rec_Flag = 0;// 接收完成,标志清0 } } } else if(TI) { TI = 0; busy=0; } }

本文来源:https://www.bwwdw.com/article/nqko.html

Top