单片机缓冲区串口读写代码
单片机通讯应用,可以读写内部缓冲区中的数据,协议如下:
1. 读数据
表1 读Len个字节数据指令格式
指令格式:
地址
读命令
01
读取数据的长度
Len
接收缓冲区的起始地址
(00,01,…)
接收Len个数据
XX,XX,…
举例:
01
01
03
05
23,44,37
说明:可在MCU内部定义一数组out_data[k],存放要发送出去的数据。
则对于该例,读取的数据为out_data[05],out_data[06],out_data[07],值依次为:23,44,37。
2. 写数据
表2 写Len个字节数据指令格式
指令格式:
地址
写命令
00
写出数据的长度
Len
发送缓冲区的起始地址
(00,01,…)
写出Len个数据
XX,XX,…
举例:
01
00
04
01
10,21,32, 56
说明:可在MCU内部定义一数组in_data[k],存放要接收的数据。则对于该例,数据为:
in_data[01],in_data[02],in_data[03],in_data[04],值依次为:10,21,32, 56。
//---------------------------------------------------------------------------------------------------------
// 串行通讯代码//start
//
//---------------------------------------------------------------------------------------------------------
//////////////////////////// RS232串行通信相关函数///////////////////////////////////////////
// uchar out_data[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; //待发送的数据
// uchar in_data[16]; //接收数据缓冲区
/*******************************************************************/
/* */
/* 等待发送完毕 */
/* */
/*******************************************************************/
void send_wait()
{
while(!TI);
TI = 0;
}
/*******************************************************************/
/* */
/* 等待接收完毕 */
/* */
/* */
/*******************************************************************/
void receive_wait()
{
while(!RI);
RI = 0;
}
/*******************************************************************/
/* */
/* 串口初始化 ,11.0592M,波特率9600b/s,方式3 */
/* */
/* */
/*******************************************************************/
void init_serial()
{
/* 数据格式: 1,8,1(1个起始位,8个数据位,1个停止位 ) */
SCON = 0X50; //方式3,SM2=0,REN = 1
TMOD = 0X20; //T1工作于方式2
TH1 = 0XFD; //装入初值
TL1 = 0XFD;
PCON &=0x7F;
ET1=0; //禁止定时器T1中断,因为T1用作波特率发生器
ES = 1; //串口开中断
EA = 1; //全局开中断
TR1 = 1; //启动T1
}
/*******************************************************************/
/* */
/* 串行中断处理函数 */
/* */
/* */
/*******************************************************************/
void serial_int() interrupt 4 using 1
{
uchar command; //接收字节命令
uchar rcv_length; //待接收的字节长度
uchar snd_length; //要发送的字节长度
uchar rcv_start_addr; //接收数据缓冲区起始地址
uchar snd_start_addr; //发送数据缓冲区起始地址
uchar i;
if(RI) //接收中断
{ RI = 0;
if(SBUF!=1) //判断第一字节是否本机地址(1)
return ;
SM2 = 0;
receive_wait();
command = SBUF;
switch(command)
{
case 0: //判断第2字节是否为PC写命令(00),若是则接收来自PC机的数据
receive_wait();
rcv_length = SBUF; //待接收的字节长度
receive_wait();
rcv_start_addr = SBUF; //接收缓冲区的起始地址(0,1,2....,14,15)
for(i=0; i //循环接收rcv_length个数据
{
receive_wait();
in_data[rcv_start_addr] = SBUF; //将接收的数据依次存放入接缓冲区(in_data[16])中
rcv_start_addr ++;
if(rcv_start_addr>15)
break;
}
break;
case 1: //判断第2字节是否为PC机读命令(01),若是则发送数据给PC机
receive_wait();
snd_length = SBUF; //要读取的字节长度
receive_wait();
snd_start_addr = SBUF; //发送缓冲区的起始地址(0,1,2....,14,15)
for(i=0; i //循环接收rcv_length个数据
{
SBUF = out_data[snd_start_addr]; //将发送缓冲区(out_data[15])中请求的数据依次发送出去
snd_start_addr ++;
send_wait();
if(snd_start_addr>15)
break;
}
break;
default: //若是非法命令,则返回
return ;
break;
}
}
else //发送中断
{
}
}
//---------------------------------------------------------------------------------------------------------
// 串行通讯代码//end
//