1 #include<reg52.h> 2 3 //------------------串口通信协议-----------------// 4 /* 5 客户端数据包格式解释(长度恒为15): 6 例如:A01_fmq_01Off___# 7 A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种) 8 01-----设备代号 9 fmq_01Off___--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部 10 #---------数据包的结束标记 11 12 服务器端数据包格式解释(长度恒为15): 13 例如:A02_SenT010250# 14 A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种) 15 02-----设备代号 16 SenT010250--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部 17 #---------数据包的结束标记 18 */ 19 char buf_string[16]; //定义数据包长度为15个字符 20 #define deviceID_1Bit ‘0‘ //用于串口通信时,定义本地设备ID的第1位 21 #define deviceID_2Bit ‘2‘ //用于串口通信时,定义本地设备ID的第2位 22 #define datapackage_headflag ‘A‘ //用于串口通信时,定义数据包头部的验证标记 23 24 char DataPackage_DS18B20[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,‘_‘,‘S‘,‘e‘,‘n‘,‘T‘,‘X‘,‘X‘,‘X‘,‘X‘,‘X‘,‘X‘,‘#‘}; 25 char HeartBeat[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,‘_‘,‘B‘,‘e‘,‘a‘,‘t‘,‘X‘,‘X‘,‘X‘,‘X‘,‘X‘,‘X‘,‘#‘}; 26 //----------------------------------------------// 27 /******************************* 28 串口通信 29 MCU:89C52RC 11.0592MHz 30 31 //11.0592MHz 0xd0 1200bps 32 //12MHz 0xcc 1200bps 33 //11.0592MHz 0xfa 9600bps 34 //0xf4 11.0592MHz 0xf3 12MHz 4800bps 35 //均在SMOD=1的情况下(波特率倍增模式) 36 *******************************/ 37 //串口发送函数 38 void PutString(unsigned char *TXStr) 39 { 40 ES=0; 41 while(*TXStr!=0) 42 { 43 SBUF=*TXStr; 44 while(TI==0); 45 TI=0; 46 TXStr++; 47 } 48 ES=1; 49 } 50 //串口接收函数 51 bit ReceiveString() 52 { 53 char * RecStr=buf_string; 54 char num=0; 55 unsigned char count=0; 56 loop: 57 *RecStr=SBUF; 58 count=0; 59 RI=0; 60 if(num<14) //数据包长度为15个字符,尝试连续接收15个字符 61 { 62 num++; 63 RecStr++; 64 while(!RI) 65 { 66 count++; 67 if(count>130)return 0; //接收数据等待延迟,等待时间太久会导致CPU运算闲置,太短会出现"数据包被分割",默认count=130 68 } 69 goto loop; 70 } 71 return 1; 72 } 73 //定时器1用作波特率发生器 74 void Init_USART() 75 { 76 SCON=0x50; //串口方式1,使能接收 77 TMOD|=0x20; //定时器1工作方式2(8位自动重装初值) 78 TMOD&=~0x10; 79 TH1=0xfa; //9600bps 80 TL1=0xfa; 81 PCON|=0x80; //SMOD=1 82 TR1=1; 83 TI=0; 84 RI=0; 85 //PS=1; //提高串口中断优先级 86 ES=1; //开启串口中断使能 87 } 88 //比较指令头部 89 bit CompareCMD_head(char CMD_head[]) 90 { 91 unsigned char CharNum; 92 for(CharNum=0;CharNum<4;CharNum++) //指令长度为10个字符 93 { 94 if(!(buf_string[CharNum+4]==CMD_head[CharNum])) 95 { 96 return 0; //指令头部匹配失败 97 } 98 } 99 return 1; //指令头部匹配成功 100 } 101 //比较指令尾部(start:从哪里开始比较,quality:比较多少个字符,CMD_tail[]:要比较的字符串) 102 bit CompareCMD_tail(unsigned char start,unsigned char quality,char CMD_tail[]) 103 { 104 unsigned char CharNum; 105 for(CharNum=0;CharNum<quality;CharNum++) 106 { 107 if(!(buf_string[start+CharNum]==CMD_tail[CharNum])) 108 { 109 return 0; 110 } 111 } 112 return 1; 113 } 114 bit Deal_UART_RecData() //处理串口接收数据包函数(成功处理数据包则返回1,否则返回0) 115 { 116 //PutString(buf_string); 117 if(buf_string[0]==datapackage_headflag&&buf_string[14]==‘#‘) //进行数据包头尾标记验证 118 { 119 switch(buf_string[1]) //识别发送者设备ID的第1位数字 120 { 121 case ‘0‘: 122 switch(buf_string[2]) //识别发送者设备ID的第2位数字 123 { 124 case ‘3‘: 125 if(CompareCMD_head("Ligt")) //判断指令头部是否为"Ligt" 126 { 127 //下面是指令尾部分析 128 switch(buf_string[8]) 129 { 130 case ‘0‘: 131 switch(buf_string[9]) 132 { 133 case ‘0‘: 134 135 return 0; 136 case ‘1‘: 137 if(CompareCMD_tail(10,3,"Off")) //A03_Ligt01Off_# 138 { 139 //要执行的代码140 return 1; 141 } 142 if(CompareCMD_tail(10,3,"On_")) 143 { 144 145 return 1; 146 } 147 return 0; 148 default: 149 return 0; 150 } 151 case ‘1‘: 152 153 default: 154 return 0; 155 } 156 } 157 if(CompareCMD_head("SenT")) 158 { 159 160 161 } 162 if(CompareCMD_head("jdq_")) 163 { 164 165 166 } 167 if(CompareCMD_head("Try!")) 168 { 169 170 171 } 172 return 0; 173 174 default: 175 return 0; 176 } 177 default: 178 return 0; 179 } 180 } 181 return 0; 182 } 183 /************************ 184 中断函数 185 ************************/ 186 //串口中断服务函数----------- 187 void USART() interrupt 4 //标志位TI和RI需要手动复位,TI和RI置位共用一个中断入口 188 { 189 if(ReceiveString()) 190 { 191 //数据包长度正确则执行以下代码 192 Deal_UART_RecData(); 193 } 194 else 195 { 196 //数据包长度错误则执行以下代码 197 //LED1=~LED1; 198 } 199 RI=0; //接收并处理一次数据后把接收中断标志清除一下,拒绝响应在中断接收忙的时候发来的请求 200 } 201 /*************************** 202 主函数 203 ***************************/ 204 void main() 205 { 206 EA=1; 207 Init_USART(); 208 while(1) 209 { 210 //PutString(buf_string);//空格20H,回车0DH 211 212 } 213 }
这个模块代码用于快速实现可扩展的串口通信
尊重作者的劳动,转载请记得注明来源:http://www.cnblogs.com/weifeng727/p/5617924.html
时间: 2024-10-10 19:11:27