求单片机串口通信协议,做设计要求:上位机通过串口实现点亮和灭3盏LED灯,不太懂协议,最好有示例代码
课程设计:上位机通过串口实现三种控制LED灯的控制:全亮,全灭,点亮或者灭其中的一盏灯。不太懂这地方的协议,求帮助,最好有类似的代码参考,要求C语言。谢谢。...
课程设计:上位机通过串口实现三种控制LED灯的控制:全亮,全灭,点亮或者灭其中的一盏灯。不太懂这地方的协议,求帮助,最好有类似的代码参考,要求C语言。谢谢。
展开
2个回答
展开全部
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar idata trdata[]={'R','I','C','H','M','C','U','R','Z','-','5','1','V','2','.','0',0x0d,0x0a,0x00};
sbit K1=P3^2; //对应开发板K1按键
/*-------------------------------------------------------------*/
//串口初始化
void UART_Init(void)
{
SCON = 0x50; //串口工作方式为1 , 串行允许接收
//SM0=0;
//SM1=1;
//REN=1;
TMOD = 0x20; //定时器1 工作在方式2
//PCON = 0x80; //SMOD = 1; 波特率加倍
TH1 = 0xfd; //波特率 9600bps fosc="11".0592MHz
TL1 = 0xfd;
ES = 1; //开串口中断
TR1 = 1; //允许定时器1工作
EA = 1; //开总中断
}
void delay1ms(uint i)
{
uchar j;
while(i--)
{
for(j=0;j<115;j++) //1ms基准延时程序
{
;
}
}
}
/*-------------------------------------------------------------*/
//串口发送一个字节
void Uart_SendChar(unsigned char dat)
{
SBUF = dat; //待发送的数据写入缓冲区
while(!TI); //等待发送完成
TI = 0; //清零发送标志位
}
/*-------------------------------------------------------------*/
//串口发送一个字符串
void Uart_SendString()
{ uchar
i=0;
while(trdata[i]!=0x00)
{
SBUF=trdata[i];
while(!TI);
TI=0;
i++;
}
}
/*-------------------------------------------------------------*/
//主函数
void main(void)
{
UART_Init(); //初始化串口
while(1)
{
if(K1==0)
{
delay1ms(20);
if(K1==0)
{
Uart_SendString(); //发送数据
while(!K1); //等待按键释放
}
}
}
}
/*-------------------------------------------------------------*/
//串口接收中断函数
void INT_UartRcv(void) interrupt 4
{
unsigned char Rcv = 0;
if(RI) //查询接收标志位(有数据发送过来时置为1)
{
RI = 0; //接收标志位清零
Rcv = SBUF; //存储缓冲区的数据
P1=SBUF;
Uart_SendChar(Rcv); //让从计算机上传到单片机的数据 , 传回的计算机显示
}
}
///////////////////////////////
9600波特率,P1口接LED
用串口大师发送数据,要勾选十六进制发送和接受。
发送:ff (全亮/全灭)
00 (全灭/全亮)
01 (p1.0亮/p1.0灭)
这个方式是最简单的,
其意思就是把你发送的十六进制数据直接赋值到P1端口
#define uchar unsigned char
#define uint unsigned int
uchar idata trdata[]={'R','I','C','H','M','C','U','R','Z','-','5','1','V','2','.','0',0x0d,0x0a,0x00};
sbit K1=P3^2; //对应开发板K1按键
/*-------------------------------------------------------------*/
//串口初始化
void UART_Init(void)
{
SCON = 0x50; //串口工作方式为1 , 串行允许接收
//SM0=0;
//SM1=1;
//REN=1;
TMOD = 0x20; //定时器1 工作在方式2
//PCON = 0x80; //SMOD = 1; 波特率加倍
TH1 = 0xfd; //波特率 9600bps fosc="11".0592MHz
TL1 = 0xfd;
ES = 1; //开串口中断
TR1 = 1; //允许定时器1工作
EA = 1; //开总中断
}
void delay1ms(uint i)
{
uchar j;
while(i--)
{
for(j=0;j<115;j++) //1ms基准延时程序
{
;
}
}
}
/*-------------------------------------------------------------*/
//串口发送一个字节
void Uart_SendChar(unsigned char dat)
{
SBUF = dat; //待发送的数据写入缓冲区
while(!TI); //等待发送完成
TI = 0; //清零发送标志位
}
/*-------------------------------------------------------------*/
//串口发送一个字符串
void Uart_SendString()
{ uchar
i=0;
while(trdata[i]!=0x00)
{
SBUF=trdata[i];
while(!TI);
TI=0;
i++;
}
}
/*-------------------------------------------------------------*/
//主函数
void main(void)
{
UART_Init(); //初始化串口
while(1)
{
if(K1==0)
{
delay1ms(20);
if(K1==0)
{
Uart_SendString(); //发送数据
while(!K1); //等待按键释放
}
}
}
}
/*-------------------------------------------------------------*/
//串口接收中断函数
void INT_UartRcv(void) interrupt 4
{
unsigned char Rcv = 0;
if(RI) //查询接收标志位(有数据发送过来时置为1)
{
RI = 0; //接收标志位清零
Rcv = SBUF; //存储缓冲区的数据
P1=SBUF;
Uart_SendChar(Rcv); //让从计算机上传到单片机的数据 , 传回的计算机显示
}
}
///////////////////////////////
9600波特率,P1口接LED
用串口大师发送数据,要勾选十六进制发送和接受。
发送:ff (全亮/全灭)
00 (全灭/全亮)
01 (p1.0亮/p1.0灭)
这个方式是最简单的,
其意思就是把你发送的十六进制数据直接赋值到P1端口
更多追问追答
追问
老师给提出的比较繁琐,例如协议是/ooo;表示3盏灯全点亮,/就表示单片机准备接收控制LED的指令,然后匹配看是不是正确的指令,还有意外的情况就是要使接收的时候上位机操作者不发了怎么办,要求延时等几秒,还有就是;表示指令结束,再比如/xxx;就代表3盏灯全灭,同时还要求校验,比如几个符号的ASCII码等于多少来判定指令是否正确。。。是不是有些复杂
追答
的确比较繁琐。
这个只是一个和简单的 协议
这种在工业上用的很多,而且很复杂。
上面的程序是一个简化版的,不过你可以把他当作一个模型。
下面,你可以在中断里面把串口发送的数据接受存下来,
然后在用判断,最后在执行相应的操作就OK。
多试试就出来了,写协议还是很简单的。
不过,你如果把上面的程序发给老是,估计老师也算认可。
但是绝对会有违老师额初衷,你这叫剑走偏锋。哈哈
展开全部
协议都可以自己定义的
一般协议都
有帧头,数据部分,帧尾。
其中,帧头和帧尾包含一些必要得控制信息,比如序号信息、地址信息
例如 68 00 02 01 XX XX XX XX YY 16
那68 就是帧起始标识
16就是帧结束标识
00 02 可以是设备地址或标识 通讯序号
01 是发送的数据类型 告诉下面 这个指令是干嘛用的
XXX之类是具体数据
YY 就是校验码 我一般使用累加校验 就是YY之前所有数据的累加和 抛弃进位 起校验数据只用
这个是最简单的协议了
一般协议都
有帧头,数据部分,帧尾。
其中,帧头和帧尾包含一些必要得控制信息,比如序号信息、地址信息
例如 68 00 02 01 XX XX XX XX YY 16
那68 就是帧起始标识
16就是帧结束标识
00 02 可以是设备地址或标识 通讯序号
01 是发送的数据类型 告诉下面 这个指令是干嘛用的
XXX之类是具体数据
YY 就是校验码 我一般使用累加校验 就是YY之前所有数据的累加和 抛弃进位 起校验数据只用
这个是最简单的协议了
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询