串口调试这个东西真的太经典了,虽然我对51的串口通信方式还是一知半解,但是这几天调试程序,又通过看郭天祥的书,对51的串口有了进一步的认识,串口调试的程序需要多多收集,开始德飞来板子上的串口程序感觉起来就是个渣渣,一点都不好用,在调试程序的时候老是出问题,上一篇调试串口的程序就是移植德飞来板子上的程序,不仅波特率不能自己更改,比较死板,要注意的东西很多,不适合,今天调试温度传感器那个程序,突然间发现一个比较又用的串口调试程序,就晒在园子里,供大家参考
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//****************************************************************// // AM系列读单总线使用范例 //单片机 :AT89S52 或 STC89C52RC // 功能 :串口发送温湿度数据 波特率 9600 // 晶振 :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间) // 编译环境: Keil3 // 公司 :奥松电子 //****************************************************************// #include "reg52.h" #include <intrins.h> //用户根据自己的晶振修改相应值 #define FOSC 11059200 #define BAUD 9600 //读传感器 端口位定义,可修改 sbit Sensor_SDA = P0^0; sbit Sensor_SCL = P0^1; // 变量定义 unsigned char Sensor_Data[5]={0x00,0x00,0x00,0x00,0x00}; unsigned char Sensor_Check; //校验和 unsigned char Sensor_AnswerFlag; //收到起始标志位 unsigned char Sensor_ErrorFlag; //读取传感器错误标志 unsigned int Sys_CNT; unsigned int Tmp; unsigned char *String; //字符串定义 #define S_Temp "Temp:" #define S_RH "RH:" #define S_CRCT "Check: True" #define S_CRCF "Check: Wrong" #define S_Data "Data: " #define S_NotS "Sensor Not Connected" /******************************************** |* 功能: 延时 晶振为12M时 *| |* t = 1 为 20us 然后成倍增加10us左右 *| ********************************************/ void Delay_N10us(unsigned char t) { while(t--) { _nop_(); } } /******************************************** |* 功能: 延时 晶振为12M时 *| |* 延时大约 1ms *| ********************************************/ void Delay_N1ms(unsigned int t) { unsigned int i; unsigned int j; for(j=t;j>0;j--) for(i=124;i>0;i--); //延时大约 1ms } /******************************************** |* 功能: 初始化串口 *| ********************************************/ void InitUART(void) { unsigned int iTmpBaud; unsigned long lTmpBaud; iTmpBaud = 0; //首先选定定时器2作为波特率发生器,16位定时器,自动装载 SCON = 0x50; //SM0 SM1 SM2 REN TB8 RB8 TI RI //0 1 0 1 0 0 0 0 PCON = 0x00; //PCON的地址是87H,这里SMOD =0 T2CON = 0x30; //TF2 EXF2 RCLK TCLK EXEN2 TR2 C(/T2) CP(/RL2) //0 0 1 1 0 0 0 0 T2MOD = 0x00; // / / / / / / T2OE DCEN //0 0 0 0 0 0 0 0 lTmpBaud = FOSC/BAUD; lTmpBaud /= 32; //12T-mode iTmpBaud = lTmpBaud & 0xFFFF; iTmpBaud = 65536 - iTmpBaud; RCAP2H = (iTmpBaud>>8) & 0x0FF; RCAP2L = iTmpBaud & 0x0FF; RI = 0; //清除接收中断标志 REN = 1; //允许串行接收 ES = 1; //允许串行中断 TR2 = 1; //启动定时器1 EA=1;//开总中断 } /******************************************** |* 功能: 串口发送函数 *| ********************************************/ void UARTSend(char UCHAR) { SBUF=UCHAR; while(TI==0); TI=0; } /******************************************** |* 功能: 串口中断函数 *| ********************************************/ void UARTRead(void) interrupt 4 { char temp; if(RI) { RI=0; temp = SBUF; } } /******************************************** |* 功能: 串口发送子函数 *| ********************************************/ void UART_PutString(unsigned char *buf) { while(*buf) UARTSend(*buf++); } void UART_PutStringAndNum(unsigned char *buf ,unsigned int num) { unsigned char a[3],i; a[3] = '0'+num%10; a[2] = '.'; a[1] = '0'+num/10%10; a[0] = '0'+num/100%10; while(*buf) UARTSend(*buf++); UARTSend(' '); for(i=0;i<4;i++) { UARTSend(a[i]); } } void UART_PutStringAnd_Data(unsigned char *buf ,unsigned char *bufdata) { unsigned char a[2],i,j; while(*buf) UARTSend(*buf++); UARTSend(' '); for(i=0;i<5;i++) { a[0] = bufdata[i]/16; a[1] = bufdata[i]%16; for(j=0;j<2;j++) { if(a[j]>9) { a[j] = (a[j]-10)+'A'; } else { a[j] = a[j]+'0'; } UARTSend(a[j]); } UARTSend(' '); } } /******************************************** |* 功能: 串口发送传感器数据函数 *| ********************************************/ void UARTSend_Nbyte(void) { if(Sensor_AnswerFlag == 1) { Sensor_Check = Sensor_Data[0]+Sensor_Data[1]+Sensor_Data[2]+Sensor_Data[3]; //校验成功 if(Sensor_Check ==Sensor_Data[4]) { String = S_RH;//"RH:"; Tmp = Sensor_Data[0]*256+Sensor_Data[1]; UART_PutStringAndNum(String,Tmp); UARTSend(' '); UARTSend(' '); String = S_Temp;// "Temp:"; Tmp = Sensor_Data[2]*256+Sensor_Data[3]; UART_PutStringAndNum(String,Tmp); UARTSend(' '); UARTSend(' '); String = S_CRCT;//"Check: True"; UART_PutString(String); }else //校验失败 送上读到数据 { String = S_Data;//"Data: "; UART_PutStringAnd_Data(String,Sensor_Data); UARTSend(' '); UARTSend(' '); String = S_CRCF;//"Check: Wrong"; UART_PutString(String); } }// 传感器未连接 else { String = S_NotS; //"Sensor Not Connected"; UART_PutString(String); } UARTSend(0x0A); } void Clear_Data (void) { int i; for(i=0;i<5;i++) { Sensor_Data[i] = 0x00; }//接收数据清零 } /******************************************** |* 功能: 读传感器发送的单个字节 *| ********************************************/ unsigned char Read_SensorData(void) { unsigned char i,cnt; unsigned char buffer,tmp; buffer = 0; for(i=0;i<8;i++) { cnt=0; while(!Sensor_SDA) //检测上次低电平是否结束 { if(++cnt >= 300) { break; } } //延时Min=26us Max50us 跳过数据"0" 的高电平 Delay_N10us(2); //延时30us //判断传感器发送数据位 tmp =0; if(Sensor_SDA) { tmp = 1; } cnt =0; while(Sensor_SDA) //等待高电平 结束 { if(++cnt >= 200) { break; } } buffer <<=1; buffer |= tmp; } return buffer; } /******************************************** |* 功能: 读传感器 *| ********************************************/ unsigned char Read_Sensor(void) { unsigned char i; //主机拉低(Min=800US Max=20Ms) Sensor_SDA = 0; Delay_N1ms(2); //延时2Ms //释放总线 延时(Min=30us Max=50us) Sensor_SDA = 1; Delay_N10us(1);//延时30us //主机设为输入 判断传感器响应信号 Sensor_SDA = 1; Sensor_AnswerFlag = 0; // 传感器响应标志 //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 if(Sensor_SDA ==0) { Sensor_AnswerFlag = 1;//收到起始信号 Sys_CNT = 0; //判断从机是否发出 80us 的低电平响应信号是否结束 while((!Sensor_SDA)) { if(++Sys_CNT>300) //防止进入死循环 { Sensor_ErrorFlag = 1; return 0; } } Sys_CNT = 0; //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态 while((Sensor_SDA)) { if(++Sys_CNT>300) //防止进入死循环 { Sensor_ErrorFlag = 1; return 0; } } // 数据接收 传感器共发送40位数据 // 即5个字节 高位先送 5个字节分别为湿度高位 湿度低位 温度高位 温度低位 校验和 // 校验和为:湿度高位+湿度低位+温度高位+温度低位 for(i=0;i<5;i++) { Sensor_Data[i] = Read_SensorData(); } } else { Sensor_AnswerFlag = 0; // 未收到传感器响应 } return 1; } void main(void) { Sensor_SCL = 0; InitUART(); //初始串口发送函数 while(1) { Clear_Data(); // 清除收到数据 Read_Sensor(); // 读取传感器数据 UARTSend_Nbyte(); // 串口发送读到传感器数据 Delay_N1ms(2000); // 延时 2S(两次读取间隔至少2S) } }
代码是可以调整波特率的,虽然还没有仔细的看,但是改一下晶振晶振的宏定义就可以用了,比较万能