1. 测速模块
用途:广泛用于电机转速检测,脉冲计数 , 位置限位等。
有遮挡,输出高电平;无遮挡,输出低电平
接线
VCC 接电源正极 3.3-5V
GND 接电源负极
DO TTL 开关信号输出
AO 此模块不起作用
2. 测试原理和单位换算
轮子走一圈,经过一个周长, C = 2x3.14x 半径 = 3.14 x 直径( 6.5cm )
对应的码盘也转了一圈,码盘有 20 个格子,每经过一个格子,会遮挡(高电平)和不遮挡(低电平), 那么一个脉冲就是走了 3.14 * 6.5 cm /20 = 1.0205CM
定时器可以设计成一秒,统计脉冲数,一个脉冲就是 1cm
假设一秒有 80 脉冲,那么就是 80cm/s
3. 定时器和中断实现测速
编程实现
main.c
#include "system.h"
//sbit D1 = P3^5;
//sbit D2 = P3^6;
//sbit D3 = P3^7;
sbit speed_do = P3^2; /* 外部中断0引脚 */
u16 speed_cnt;
extern u8 send_signal;
extern u16 speed;
char real_speed[24]; /* 建立一个数组来存储速度 */
void Ex0_init(void)
{
EX0 = 1;
EA = 1; /* 串口那已经开启 */
IT0 = 1; /* 下降沿触发 */
}
void main(void)
{
Timer0_Init();
Uart1_Init();
Ex0_init(); /* 外部中断的下降沿触发 */
while(1)
{
if(send_signal)
{
sprintf(real_speed,"speed:%d cm/s",speed); /* 整型数(97)变成字符的(97) */
Send_String(real_speed);
send_signal = 0; /* 清0send_signal,下次由定时器1s后的中断处理中再置一 */
}
}
}
void Speed_Handle(void) interrupt 0
{
speed_cnt++; /* 码盘转动了一个格子 */
}
timer0.c
#include "system.h"
sfr AUXR = 0x8E;
u8 cnt = 0;
extern u16 speed_cnt;
u16 speed;
u8 send_signal = 0;
void Timer0_Init(void) //500微秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01;
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
void Timer0_Isr(void) interrupt 1
{
cnt++;
TL0 = 0x33;
TH0 = 0xFE;
if(cnt == 2000) /*爆表2000次,经过了1s */
{
send_signal = 1; /* 发送信号 */
speed = speed_cnt;
speed_cnt = 0; /* 1秒后拿到speedCnt个格子,就能算出这1s的速度,格子清零 */
cnt = 0;/* 当100次表示1s,重新让cnt从0开始,计算下一次的1s
计算小车的速度,也就是拿到speedCnt的值 */
}
}
uart.c
#include "system.h"
#define SIZE 12
sfr AUXR = 0x8E;
u8 buffer[SIZE];
/* 发送一个字符 */
void Send_Byte(s8 byte)
{
SBUF = byte;
while(!TI);
TI = 0;
}
/* 发送一串字符串 */
void Send_String(char* string)
{
while(*string != '\0')
{
Send_Byte(*string);
string++;
}
}
void Uart1_Init(void) //[email protected]
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器时钟12T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES = 1; //使能串口1中断
//EA = 1;
}
void Uart1_Isr(void) interrupt 4
{
static u8 i = 0;
u8 sbuf;
if (RI) //检测串口1接收中断
{
RI = 0; //清除串口1接收中断请求位
sbuf = SBUF;
if(sbuf == 'M')
{
i = 0;
}
buffer[i++] = sbuf;
if(buffer[0] == 'M')
{
switch(buffer[1])
{
/* M0控制小车前进 */
case '0':
Goto_Forward();
break;
/* M1控制小车后退 */
case '1':
Goto_Back();
break;
/* M2控制小车左转 */
case '2':
Goto_TurnLeft();
break;
/* M3控制小车右转 */
case '3':
Goto_TurnRight();
break;
/* 其它为停止 */
default:
Goto_Stop();
break;
}
}
if(i == 12)
{
i = 0;
memset(buffer,'\0',SIZE);
}
}
}