小车测速并通过串口发送速度数据
测速原理:
小车车轮的直径是6.5cm,所以周长是:3.14*6.5cm = 20.41cm,底部的测速码盘有20个格子,每经过一个格子,就会从遮挡(高电平)到不遮挡(低电平),轮子转一圈,码盘也转一圈,测速模块由高电平变为低电平的次数就是20次,而每一个格子的所经过的距离是:20.41cm/20 = 1.0205cm,约等于1cm,所以用定时器计时1秒,然后看经过了多少个格子,即得出1秒内小车走了多少距离,就是小车的速度
拿之前有串口通信和定时器0PWM调速的程序来进一步修改
1.添加外部中断Int0.c
当码盘转起来时,测速模块指示灯一直闪,输出引脚不断循环输出高电平和低电平,P3_7口收到外部中断信号时,程序进入中断处理函数,让InitSpeed++,然后在定时器2中断处理函数中对InitSpeed进行处理
unsigned int InitSpeed = 0;
/**
* @brief 外部中断0初始化
* @param 无
* @retval无
*/
void Int0_Init()
{
IT0 = 1; //下降沿触发
EX0 = 1; //允许外部中断
EA = 1; //打开总中断
}
//中断处理函数
void Int0_Rountine() interrupt 0
{
InitSpeed++;
}
2.添加定时器2 Timer2.c
因为定时器1用作串口波特率发生器,定时器0用作PWM调速了,所以只能用定时器2作计时功能
#include <REGX52.H>
unsigned int count2;
unsigned int ResultSpeed;
extern unsigned int InitSpeed;
unsigned char signal; //串口发送的标志位
/**
* @brief 定时器2初始化
* @param 无
* @retval无
*/
void Timer2Init(void) //50毫秒@11.0592MHz
{
T2MOD = 0; //初始化模式寄存器
T2CON = 0; //初始化控制寄存器
TL2 = 0x00; //设置定时初值
TH2 = 0x4C; //设置定时初值
RCAP2L = 0x00; //设置定时重载值
RCAP2H = 0x4C; //设置定时重载值
TR2 = 1; //定时器2开始计时
ET2 = 1; //开启定时器2中断
EA = 1;
}
//定时器2中断处理
void Timer2_Rountine() interrupt 5
{
count2++;
TF2 = 0; //定时器2溢出标志,软件清零
if(count2 == 20) //50ms*20 = 1000ms = 1 s,定义出1秒
{
signal = 1; //标志位置1时,main函数那边才通过串口发送数据
/*将InitSpeed赋给变量ResultSpeed,串口发送ResultSpeed,避免串口还没来得及发送
InitSpeed就被清零,造成数据异常*/
ResultSpeed = InitSpeed;
InitSpeed = 0; //外部中断变量清零,继续下一秒测速
count2 = 0;
}
}
3.Motor.c的引脚改一下
原本rightA接到了P3_2口,而P3_2口是外部中断0,要接测速模块,所以rightA改为P3_7口;
sbit rightA = P3^7;
4.main函数
主函数中根据发送标志位调用串口发送函数进行速度发送
注意:这里要记住sprintf的用法,这个函数非常好用,后面OLED显示小车速度也是用的这个函数
#include <Stdio.h> //函数sprintf的头文件
extern unsigned int ResultSpeed;
extern unsigned char signal; //发送标志,当定时器2将其改为1时串口发送数据
char recspeed[24];
void main()
{
Timer0Init();
Timer2Init();
Int0_Init();
UartInit();
while(1)
{
//定时器2那边如果将标志位改为1,则进行数组格式组装并发送
if(signal == 1)
{
//sprintf方法将ResultSpeed按格式组建好后放到数组recspeed中去
sprintf(recspeed,"speed:%d cm/s\r\n",ResultSpeed);
Usart_SendString(recspeed); //再通过串口发送
signal = 0;
}
}
}
5.当硬件上接好了蓝牙模块,也可以将速度的数据发送到手机蓝牙助手上
6.最后程序文件如下
main.c:主函数,定时器0、定时器2、外部中断和串口的初始化函数调用,while循环内根据标志位发送速度到串口
Motor.c:小车前进、后退、左转、右转和停止的函数
Delay.c:延时函数
Timer0.c:定时器0初始化函数,中断处理函数中是前进的PWM调速
Timer2.c:定时器2初始化函数,中断处理函数是定时1秒对外部中断的变量进行处理后清零
Init0.c:外部中断0初始化函数,下降沿中断处理函数让变量不断+1
Uart.c:串口发送函数,串口中断处理函数,接收串口指令让小车启动,包括快速、中速、慢速模式选择