1.设计要求
利用串口技术,控制数码管、LED、小车的启停
2.设计概述
本实验所用芯片为STC89C52,所用硬件是由华清远见基于STC89C52开发的智能小车,该小车具有流水灯模块、蜂鸣器模块、独立键盘模块、矩阵键盘模块等。本实验使用串口技术远程控制小车,串口传输数据格式为 L/G/C + 指令 + ‘ ;’。如,控制小车数码管显示1314,则通过串口发送‘G1314;’;控制小车启动则通过串口发送‘CY;’控制小车停止则通过串口发送‘CN;’;控制led灯开启则发送‘LY;’;控制LED灯关闭则发送‘LN;’。
3.原理图以及线路连接
J10-EN1接C52-P1.4 //EN1为左电机的使能端,只有当EN1为1时,左电机才能启动
J10-EN2接C52-P1.5 //EN2为右电机的使能端,只有当EN2为1时,右电机才能启动
J10-IN1接C52-P1.2 //IN1控制左电机反转,当IN1为1,IN2为0时,左电机反转
J10-IN2接C52-P1.3 //IN2控制左电机正转,当IN2为1,IN1为0时,左电机正转
J10-IN3接C52-P1.6 //IN3控制右电机正转,当IN3为1,IN4为0时,左电机正转
J10-IN4接C52-P1.7 //IN4控制右电机反转,当IN4为1,IN3为0时,左电机反转
4.软件设计
串口通信设置
1.配置SCON寄存器的SM0和SM1位,使串口以模式1的方式工作。 SM0 = 0,SM1 = 1
2.配置SCON寄存器的REN位,使能串口接收(REN = 1)
3.配置PCON寄存器的SMOD位,使波特率不加倍(SMOD = 0)
4.配置定时器1的相关寄存器,使定时器工作在模式2,且TH1 = TL1 = 0xfd
5.配置IE寄存器,开启串口中断
6.编写串口中断服务函数,在函数中对中断请求标志位TI和RI清零
模式0:同步通信
模式1:异步通信,8位数据位,波特率可变(常用)
模式2:异步通信,9位数据位,波特率固定
模式3:异步通信,9位数据位,波特率可变
波特率通过定时器1配置 当单片机为12T模式且SMOD位为0时
波特率 = 系统时钟/12/32/(256 – TH1)
假设我们要得到9600的波特率 那么
TH1 = 256 – 11059200/12/32/9600 = 256-3=253
然后启动定时器1即可(不用开定时器1中断)
void uartInit()
{
SM0 = 0;
SM1 = 1;//配置串口工作在模式1
REN = 1;//使能接收
PCON &= ~(1<<7);//使SMOD = 0;
ES = 1;//开启串口中断
EA = 1;//开总中断
}
void timer1Init()
{
TMOD = 0x20;//配置定时器1工作在模式2
TH1 = TL1 = 0XFD;//配置波特率为9600
ET1 = 0;//禁止timer1中断
TR1 = 1;//启动定时器1
}
接收信息处理
(数码管相关知识在计数器中有详细解释,小车的fornt函数等在寻迹小车中有详细解释)
串口开始运行后开始逐个字符向C52的SBUF寄存器发送,然后逐个处理数据
字符串的第一个数据设置为模式选择位,即通过向SBUF发送G/L/C选择控制小车的不同功能
在G模式下:G后面的字符串表示要在数码管显示的数字,以;结束字符串,由于数码管数字显示是动态显示,所以需要在主函数中不断显示,否则在没有信息传输时会只显示最后一位数字。
在L/C模式下:L/C后面的字符Y/N表示开/关,以;结束。
void uart1() interrupt 4
{
char temp = 0;
/* 接收到数据后将数据传给temp,将RI置0,等待下一次接收 */
if(RI)
{
temp = SBUF;
RI = 0;
/* 如果模式选择位没有选择,则选择模式,L控制led灯开关;G控制数码管开关;C控制小车开关*/
if(mflag == 0)
{
mflag = temp;
}
else
{
switch(mflag)
{
/* 模式G下,逐个输入数字,以';'结束*/
case 'G':
if(temp != ';')
{
t = t*10+(temp-48); //接收到的是字符,字符数字-48则为数值
}
if(temp == ';')
{
flag = 1;
mflag = 0;
p = t;
t = 0;
}
break;
/* 模式L,输入Y开启LED灯,N关闭LED灯,;结束输入*/
case 'L':
if(temp == 'Y')
P1 = 0x00;
if(temp == 'N')
P1 = 0xFF;
if(temp == ';')
mflag =0;
break;
/* 模式C下,输入Y小车前进,输入N停止,;结束*/
case 'C':
if(temp == 'Y')
fornt();
if(temp == 'N')
stop();
if(temp == ';')
{
mflag = 0;
}
break;
default:break;
}
}
}
if(TI)
{
TI = 0;
txflag = 0;
}
}