上一篇我们简单配置了下51单片机的串口,设置波特率为9600,数据格式为8N1.有同学认为这个8N1不就是通信协议吗?
这个当然不是了,这个只是对串口的硬件进行配置,如下:
串口参数设置
通信速率
波特率 数据位 停止位 校验位
9600 8位 1位 无
电脑的串口助手设置如下
只要大家把串口都配置成8N1,波特率为9600,我们就可以让单片机和电脑进行串口通信了。
但是通信也要有通信协议,否则数据传输会出现问题,就比如,一个用汉语讲话,一个用英语讲,他俩虽然在通话,但是谁也听不懂谁在讲什么。
我们的通信协议最简单的格式就是
数据头 数据
AT 123
复杂一点的协议如下图:
长度(byte) 1 2 1 1 变长 1 1
含义 79H L Ctrl Cmd Data CSUM CXOR
帧格式的各个域中,大于一个字节的域,均使用小端字节序(以下称小端)传输。
79H:帧头。
L:数据域 Data 的长度。
Ctrl:控制域。
Cmd:指令字。
Data:数据域。
CSUM:和校验,是 L、Ctrl、Cmd、Data 所有字节算术和,不考虑溢出。
CXOR:异或校验,初始值为 0,是 L、Ctrl、Cmd、Data 所有字节的异或。
协议的制定是为了保证通信的稳定性和正确性。如上面的复杂协议,最后哈加了和校验和异或校验。
好,协议的知识先讲这么多,以后我们在讲下数据发送超时判断等。接下来我们简单看下C语言是怎么实现串口协议的,我们还是以最简单的协议为例子,如下
---------------------------------------
串口发送数据程序
char RecvString_buf[16]="AT0000.0\r\n";
void main(void)
{
int data_adc;
Init_USART() ;
while(1){
RecvString_buf[2] = data_adc/10000 + '0';
RecvString_buf[3] = data_adc /1000%10 + '0';
RecvString_buf[4] = data_adc/100%10 + '0';
RecvString_buf[5] = data_adc /10 % 10 + '0';
RecvString_buf[7] = data_adc % 10 + '0';
send_data(RecvString_buf,10) ;
Delay_1ms(1000);
}
}
/*
串口发送数据
*/
void send_data(unsigned char *TXStr,char num)
{
char i;
ES=0;
//while(*TXStr!=0)
for(i = 0; i < num; i++)//
{
SBUF=*TXStr;
while(TI==0);//
TI=0;
TXStr++;
}
ES=1;
}
---------------------------------------------------
串口接收数据程序
unsigned char recv_num = 0;
unsigned int recv_data_BH = 0;
void USART() interrupt 4
{
char g_recstr;
g_recstr=SBUF;
if(RecvString_buf[0] == 'A'){
RecvString_buf[recv_num] = g_recstr;
recv_num++;
if(recv_num >= 10){
recv_data_BH = (RecvString_buf[2]-'0') * 10000 +
(RecvString_buf[3]-'0') * 1000 +
(RecvString_buf[4]-'0') * 100 +
(RecvString_buf[5]-'0') * 10 +
(RecvString_buf[7]-'0') ;
recv_num = 0;
RecvString_buf[0] = 'b';
}
}
if((g_recstr == 'A') && (recv_num == 0)){
RecvString_buf[0] = 'A';
recv_num = 1;
}
RI=0;
}
欢迎大家回复和提出问题,关于串口通信的问题我会一一解答(* ̄) ̄)
如果对大家有所帮助,也欢迎关注本贴吧
这个当然不是了,这个只是对串口的硬件进行配置,如下:
串口参数设置
通信速率
波特率 数据位 停止位 校验位
9600 8位 1位 无
电脑的串口助手设置如下
只要大家把串口都配置成8N1,波特率为9600,我们就可以让单片机和电脑进行串口通信了。
但是通信也要有通信协议,否则数据传输会出现问题,就比如,一个用汉语讲话,一个用英语讲,他俩虽然在通话,但是谁也听不懂谁在讲什么。
我们的通信协议最简单的格式就是
数据头 数据
AT 123
复杂一点的协议如下图:
长度(byte) 1 2 1 1 变长 1 1
含义 79H L Ctrl Cmd Data CSUM CXOR
帧格式的各个域中,大于一个字节的域,均使用小端字节序(以下称小端)传输。
79H:帧头。
L:数据域 Data 的长度。
Ctrl:控制域。
Cmd:指令字。
Data:数据域。
CSUM:和校验,是 L、Ctrl、Cmd、Data 所有字节算术和,不考虑溢出。
CXOR:异或校验,初始值为 0,是 L、Ctrl、Cmd、Data 所有字节的异或。
协议的制定是为了保证通信的稳定性和正确性。如上面的复杂协议,最后哈加了和校验和异或校验。
好,协议的知识先讲这么多,以后我们在讲下数据发送超时判断等。接下来我们简单看下C语言是怎么实现串口协议的,我们还是以最简单的协议为例子,如下
---------------------------------------
串口发送数据程序
char RecvString_buf[16]="AT0000.0\r\n";
void main(void)
{
int data_adc;
Init_USART() ;
while(1){
RecvString_buf[2] = data_adc/10000 + '0';
RecvString_buf[3] = data_adc /1000%10 + '0';
RecvString_buf[4] = data_adc/100%10 + '0';
RecvString_buf[5] = data_adc /10 % 10 + '0';
RecvString_buf[7] = data_adc % 10 + '0';
send_data(RecvString_buf,10) ;
Delay_1ms(1000);
}
}
/*
串口发送数据
*/
void send_data(unsigned char *TXStr,char num)
{
char i;
ES=0;
//while(*TXStr!=0)
for(i = 0; i < num; i++)//
{
SBUF=*TXStr;
while(TI==0);//
TI=0;
TXStr++;
}
ES=1;
}
---------------------------------------------------
串口接收数据程序
unsigned char recv_num = 0;
unsigned int recv_data_BH = 0;
void USART() interrupt 4
{
char g_recstr;
g_recstr=SBUF;
if(RecvString_buf[0] == 'A'){
RecvString_buf[recv_num] = g_recstr;
recv_num++;
if(recv_num >= 10){
recv_data_BH = (RecvString_buf[2]-'0') * 10000 +
(RecvString_buf[3]-'0') * 1000 +
(RecvString_buf[4]-'0') * 100 +
(RecvString_buf[5]-'0') * 10 +
(RecvString_buf[7]-'0') ;
recv_num = 0;
RecvString_buf[0] = 'b';
}
}
if((g_recstr == 'A') && (recv_num == 0)){
RecvString_buf[0] = 'A';
recv_num = 1;
}
RI=0;
}
欢迎大家回复和提出问题,关于串口通信的问题我会一一解答(* ̄) ̄)
如果对大家有所帮助,也欢迎关注本贴吧