SM0,SM1:控制串行口的工作方式:
SM0 | SM1 | 方式 | 功能说明 |
0 | 0 | 方式0 | 移位寄存器方式(同步通信) |
0 | 1 | 方式1 | 8位UART,波特率可变 |
1 | 0 | 方式2 | 9位UART,波特率位时钟频率/64或者时钟频率/32 |
1 | 1 | 方式3 | 9位UART,波特率可变 |
SM2:允许方式2和方式3进行多机通信控制位
REN:允许串行接收控制位,REN=1,允许接收
TB8:是工作在方式2和方式3时要发送第9位数据,根据需要由软件置位和复位
RB8:是工作在方式2和方式3时接收到的第9位数据
TI:发送中断标志位。必须由软件清零(手动清零)
RI:接收中断标志位。必须由软件清零(手动清零)
串口配置:
步骤:数据发送用等待,接收用判断
- 根据STC配置串口初始化(波特率,模式,分频...)+手动打开串口中断允许位(ES=1)。
- 编写串口数据发送函数,将数据写入SBUF寄存器中),等待数据发送完成(TI置一)<等待使用while(TI==0);>,该标志位需手动清零;
- 串口中断函数(主要用于数据接收),判断数据接收完成标志位(RI)是否置一<if(RI==1)表示数据接收完成>;诺置一,则将SBUF内的数据读取出来,该标志位需手动清零。
参考代码:
/*******************************************************/
//函数名称:串口初始化函数
//入口参数:无
//返 回 值:无
//函数功能:串口初始化
/*******************************************************/
void UartInit(void) //4800bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x8F; //设置定时初始值
T2H = 0xFD; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //开启串口中断
}
/*******************************************************/
//函数名称:串口数据发送函数
//入口参数:待发送字符串
//返 回 值:无
//函数功能:串口发送数据
/*******************************************************/
void Uart_Sendstring(unsigned char *pucstr)
{
while(*pucstr!='\0')
{
SBUF = *pucstr++;
while(!TI);//SBUF寄存器发送数据完成标志位
TI=0;
}
}
/*******************************************************/
//函数名称:串口1中断函数
//入口参数:无
//返 回 值:无
//函数功能:串口数据接收(RI)
/*******************************************************/
void uart_0(void) interrupt 4
{
if(RI)//SBUF寄存器接收数据完成标志位
{
Uart_Buf[Uart_Num++]=SBUF;//获取数据
RI=0;//手动清除串口接收标志位(RI)
}
}
串口接收字符串注意事项:
- 设置一个中断接收标志位
- 设置一个数据接收等待时间(10ms),当数据接收时间持续在这个范围内时表示接收的数据还未停止,一直持续到当数据接收时间超过设定的数据等待时间时,在对串口接收的数据标志位进行判断(避免一串数据触发多次条件);
- 判断中断标志位是否被置一(表示串口接收到新数据),从而进入串口数据处理函数,并将串口接收的数据标志位置零,以及下标置零。
- 在一串字符串指令发送完成后,在字符串末尾必须添加'\0'结束符;
//串口中断参考函数 void Uart_Rx() interrupt 4 { if(RI) { RI=0; if(All_State)//项目要求(无关紧要) { uart_Buf_RI[uart_i++]=SBUF;//将串口发送的字符串数据转移到自定义的数组中 Uart_Flag = 1;//数据接收标志位(接收到新的数据后置一) Uart_Slow_Down=0;//重新清零数据接收等待时间,超过时间表示一次数据发送结束 } } } /*************************************************************************/ //或者是 void uart1_isr() interrupt 4 { if(RI) { Uart_10ms=0; Uart_String[Uart_i++]=SBUF; RI=0; } }
//字符处理参考函数 if(All_State)//项目要求(无关紧要) { Tempare_Value=Read_DS18B20_Value();//(无关紧要) ADC_Value=PCF8591_ADC_Tran();//(无关紧要) if(Uart_Flag)//数据接收标志位 { if(Uart_Slow_Down==10)//串口数据接收等待时间(10ms),当一个串口数据据发送结束后置一 { if(uart_Buf_RI[0]=='1'||uart_Buf_RI[0]=='2') { if(uart_Buf_RI[0]=='1') sprintf(uart_String_TI,"C:%2.1f",Tempare_Value); else sprintf(uart_String_TI,"D:%1.2fppm",ADC_Value); String_TI(uart_String_TI); } //else if((uart_Buf_RI[0]=='O')&&(uart_Buf_RI[1]=='p')&&(uart_Buf_RI[2]=='e')&&(uart_Buf_RI[3]=='n')&&(uart_Buf_RI[4]=='\r')&&(uart_Buf_RI[5]=='\n')) else if(strcmp(uart_Buf_RI,"Open\r\n")==0)//处理字符串 { sprintf(uart_String_TI,"Open\r\n"); String_TI(uart_String_TI); } uart_i=0;//自定义数组标志位清零,用于接收新的数据 Uart_Flag=0;//数据接收标志位清零,避免一次数据触发多次条件 } } } /*************************************************************************/ //或者是 if(Uart_10ms>=10&&Uart_i!=0) { Uart_String[Uart_i]='\0';//字符串结束符,在一串字符指令接收完成后,必须在字符串末尾添加结束符。 if(strcmp(Uart_String,"ST\r\n")==0) { sprintf(Seg_String,"$%02d,%4.2f\r\n",(unsigned int)Ultrasonic_Value,Tempera_Value); Uart_T_String(Seg_String); } else if(strcmp(Uart_String,"PARA\r\n")==0) { sprintf(Seg_String,"#%02d,%02d\r\n",(unsigned int)Ultrasonic_Value_Para,(unsigned int)Tempera_Value_Para); Uart_T_String(Seg_String); } else { sprintf(Seg_String,"ERROR\r\n"); Uart_T_String(Seg_String); } Uart_i=0; }
如有不妥之处,还请指出,如有补充,洗耳恭听。此笔记仅供参考,如若对你有所帮助,点个赞加个关注呗,谢谢。最后祝愿你旗开得胜,金榜题名。