串口收发字符串
1. 串口初始化
串口初始主要涉及如下几个参数:时钟频率,波特率,产生波特率的定时器,但其实这些内容都不需要我们操心,在软件点两下就好了,下文Code1的串口配置如图1所示。需要注意的是,低版本的stcai-isp软件没有打通中断通道,需要使用者自行配置串口中断(ES=1;EA=1;)。
请注意,若是你使用了STC12或IAP15等宏晶科技的芯片,却使用<reg52.h>等作为头文件,将会在寄存器AUXR处发生报错。解决方法也很简单,只需要定义一个寄存器即可。如Code2。
图1
void Uart1_Init(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xE0; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES = 1; //使能串口1中断
EA = 1; //开启总中断
}
Code1
sfr AUXR = 0x8E;
void Uart1_Init(void) //9600bps@11.0592MHz
{
...代码省略,参考Code1...
}
Code2
2. 串口发送字符串
串口接收比发送困难,因此先讲串口发送。无论什么数据类型都可以转为字符串发送,因此这里主讲串口发送字符串。
首先编写一个发送函数UartSendString()。如Code3。该函数主要有两种使用方法,方法1:直接发送一个固定字符串,如Code4;方法2:使用sprintf函数生成字符串,如Code5。
下面主要讲一下Code5:
(1)stdio.h包含了sprintf函数,生成字符串需要sprintf函数。
(2)为什么要将unsigned char 类型的soundNow转化为unsigned int,而不是直接使用它本身?因为我们希望将125传到PC端,而不是125对应的ASCLL对应的'}'。因此需要将其转为unsigned int类型,然后使用%d进行占位。
(3)为什么要将float类型的lightNow拆分成%d.%d,而不是直接使用%.2f进行占位?原因是:若使用%.2f进行占位操作后,如果后面还有其他数据,那么这些数据会乱码。举个例子"a is %.2f and b is 23",这个and b is 23就有可能乱码。具体为什么会乱码,我也不知道,也不知道怎么解决这个乱码,只能绕路了。
void UartSendString(const unsigned char *da)
{
unsigned char i=0;
while(da[i] != '\0')
{
SBUF = da[i];
while(TI==0) ;
TI=0;
i++;
}
}
Code3
UartSendString("Hello World!");
Code4
// 导入必要的头文件
#include <stdio.h>
// 生成一些数据
unsigned char soundNow = 125;
unsigned int temNow = 59;
float lightNow = 93.48;
// 数组,用于储存字符串数据
unsigned char dataToSend[100];
// 生成字符串,并发送,需要注意数组是否越界
sprintf(dataToSend, "The sound is %d!\n", (unsigned int)soundNow);
UartSendString(dataToSend);
sprintf(dataToSend, "The tem is %d!\n", temNow);
UartSendString(dataToSend);
sprintf(dataToSend, "The light is %d.%d!\n", (unsigned int)lightNow, (unsigned int)((unsigned int)(lightNow*100)%100));
UartSendString(dataToSend);
Code5
3. 串口接收数据
数据可能有多种格式:
(1)比如一次只接收1个HEX数据(如Code6),每个数据都代表了一个特定意思,这种是最简单的;
(2)进阶一点:(使用包头包尾)接收固定长度数据,比如Led1=1;Led2=0;
(3)更进一步:使用包头包尾接收不固定长度的数据,如##You good!@@,其中##为包头,@@为包尾,主要使用了状态机思想,具体请移步up主江协科技stm32视频。Code7供参考。
// 全局变量,接收数据
unsigned char da=0;
void Uart_Interrupt(void) interrupt 4
{
if(RI)
{
RI=0;
da=SBUF;
}
}
Code6
unsigned char ReceiveData[10];
bit ReceiveDoneFlag = 0;
void Uart_Interrupt(void) interrupt 4
{
static unsigned char stata=0, i=0;
unsigned char da=0;
if(RI)
{
RI=0;
da=SBUF;
if(stata==0)
{
if(da=='#') stata = 1;
else stata = 0;
}
else if(stata==1)
{
if(da=='#') stata=2;
else stata=0;
}
else if(stata==2)
{
if(da=='@') stata=3;
else
{
ReceiveData[i]=da;
i=(i+1)%10;
}
}
else if(stata==3)
{
if(da=='@')
{
stata=0;
//ReceiveData[i]='\0';
i=0;
ReceiveDoneFlag=1;
}
else
{
ReceiveData[i]='@';
i=(i+1)%10;
ReceiveData[i]=da;
i=(i+1)%10;
stata = 2;
}
}
}
}
Code7
作者:世界和平哈哈