基于51单片机的红外测速系统使用STC89C52RC作为系统,利用L298N作为电机驱动器件,使用TM1638驱动数码管继续显示,程序运行,电机转动,对射式红外测量编码盘产生的下降沿,一般而言,在指定时间内获得的下降沿越多,表示电机速度越快。
一、硬件设计
1、TM1638
TM1638,一款由台湾晶豪科技(ESMT)设计的高性能、多功能LED驱动/控制器,专门用于驱动8位共阴极或共阳极的LED数码管显示,以及16个独立的LED或按键。这款芯片以其集成度高、功能全面和易于使用而受到电子工程师和爱好者的青睐。
主要功能与特性:
驱动能力:TM1638能同时驱动8位LED数码管和16个独立的LED或按键,适用于各种显示和输入控制需求。
通信接口:支持串行SPI通信协议,可与微控制器轻松连接,简化了电路设计。
显示控制:提供多种显示模式,包括静态显示和滚动显示,支持亮度调节和显示内容的动态控制。
低功耗设计:工作电压范围为2.7V至5.5V,低功耗特性使得其在电池供电的移动设备中应用广泛。
集成键盘扫描:内置键盘扫描功能,可自动识别16个按键的状态,减轻了主控器的负担,提升了系统的响应速度。
2、编码器测速(对射式红外)
对射式红外传感器,一种基于红外线发射与接收原理的非接触式位置检测技术,广泛应用于自动化控制、安防系统、工业检测以及环境监测等领域。这种传感器通过红外发射器发出红外光束,由对应的接收器接收,当有物体阻挡光束路径时,接收器检测到信号变化,从而实现物体检测或计数
二、软件设计
1、TM1638驱动数码管
#include "nixie.h"sbit TM1638STB = P1^0;
sbit TM1638CLK = P1^1;
sbit TM1638DIO = P1^2;unsigned char Data[]={0x3f,0x30,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};//TM1638写一个字节(只负责送数据到线上)
void TM1638_WByte(ucahr cmd)
{uchar i;for (i = 0; i < 8; i++){TM1638CLK = 0;TM1638DIO = cmd & 0x01;cmd >>= 1;TM1638CLK = 1;}
}void TM1638_clear()
{uchar i;TM1638STB = 1;TM1638STB = 0;TM1638_WByte(0x40);for (i = 0; i < 16; i ++)TM1638_WByte(0x00);//在所有16个地址中写入0x00TM1638STB = 1;TM1638STB = 0;TM1638_WByte(0xc0);//设置显示地址为0x00TM1638STB = 1;
}void nixie_Init()
{TM1638_clear();TM1638STB = 0;TM1638_WByte(0x88);//1000 1000显示开,脉冲宽度为1/16TM1638STB = 1;TM1638STB = 0;TM1638_WByte(0x44);//普通模式,地址固定,写显示数据TM1638STB = 1;}void nixie(uchar pos, uchar num, uchar dot){TM1638STB = 0;TM1638_WByte(0xc0 + pos*2);if(dot==1)TM1638_WByte(Data[num] | 0x80);if(dot==0)TM1638_WByte(Data[num]);TM1638STB = 1;
}
2、编码器测速
编码器测速结合了外部中断和定时器,定时器捕捉指定时间内产生的下降沿,得出速度。
#include <reg52.h>
#include <intrins.h>
#include "delay.h"
#include "Timer0.h"
#include "KEY.h"
#include "nixie.h"sbit Motor = P1^5;typedef unsigned int u16;
typedef unsigned char u8;//变量定义
u16 pulse_count=0;
u16 pulse_res=0;
u8 KeyNum=0, mode=0;
unsigned char Counter,Compare=0;void Timer1_Init(){//TMOD=0x01;TMOD&=0x0f;//1与任何数&为原数,0与任何数|为原数TMOD|=0x10;TF1=0;TR1=1;TL1 = 0x9C; //设置定时初始值TH1 = 0xFF; //设置定时初始值ET1=1;EA=1;PT1=1;
}// 外部中断INT0的中断服务子程序
void ext1_isr() interrupt 2
{pulse_count++;
}void ext1_config()
{// 设置INT1IT1=1; // 设置外部中断1触发方式为下降沿触发EX1=1; // 打开外部中断1的中断允许EA=1; // 打开总中断允许
}void main()
{//利用外部中断捕捉,下降沿,获取流速ext1_config();//定时器初始化Timer0_Init();Timer1_Init();nixie_Init();while(1){KeyNum = KEY();if(KeyNum==1)mode++;mode %= 2;if(mode==0)Compare = 0;if(mode==1)Compare = 25;nixie(0,pulse_res/1000%10,0);nixie(1,pulse_res/100%10,0);nixie(2,pulse_res/10%10,1);nixie(3,pulse_res%10,0);}
}//流速处理逻辑
void Velocity()
{//计算流速pulse_res = (int)(pulse_count/2);//显示流速//脉冲清零pulse_count=0;
}void Timer0_Routine() interrupt 1
{static unsigned int T0Count,T0Count1,T0Count2;TL0 = 0x18; //设置定时初始值TH0 = 0xFC; //设置定时初始值//定时器扫描按键T0Count1++;if(T0Count1>=20){T0Count1=0;Key_Loop(); }//定时计数T0Count++;if(T0Count>=1000){T0Count=0;Velocity();}
}void Timer1_Routine() interrupt 3
{TL1 = 0x9C; //设置定时初始值TH1 = 0xFF; //设置定时初始值324Counter++;Counter%=100;if(Counter<Compare){Motor= 1;}else{Motor = 0;}
}
三、项目演示
程序运行系统默认风扇不转动,如下:
点击运行,风扇开始转动,同时数码管显示速度值,如下:
四、项目总结
通过本次设计,实现了定时器和对射式红外结合编码盘,实现对直流电机的测速,详情参考我的bilibili,如下:
基于51单片机的红外测速系统_哔哩哔哩_bilibili