基于51单片机的红外测速

将红外模块连接外部中断0,用于记录10秒内转的圈数,定时器0计时10秒,十秒后关闭中断,计算转速(r/min)并显示在数码管上。

电机需要特别改一下,如下:

黑色小块可以吸收红外线,此时红外模块out指示灯不亮,周围白色则反射红外线回去,红外模块接收红外线,out指示灯亮,并且拉低P3^2口 ,发生中断。

材料

1、红外模块

2、51单片机

3、L298N电机驱动模块

4、5V直流电机 

硬件连接

只需要一个直流电机即可,使用motorA直流电机,给L298N供电后,令L298N上IN1或IN2其中一个接Vcc就可以让直流电机转动起来。

红外模块正确供电,out接单片机P3^2口,P3^2是51单片机外部中断口。

 代码

#include <REG52.H>

unsigned char code gsmg_code[17] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};

sbit LSA = P2 ^ 2;//38译码器
sbit LSB = P2 ^ 3;
sbit LSC = P2 ^ 4;

sbit RAY = P3 ^ 2; // 外部中断0引脚

unsigned long cnt  = 0;
unsigned int speed = 0;
//数码管显示函数,n为要显示的数
void smg_display(unsigned int n)
{

    char i, j;
    for (i = 7; i >= 0; i--) {
        switch (i) {
            case 0:
                LSC = 1;
                LSB = 1;
                LSA = 1;
                break; // 7
            case 1:
                LSC = 1;
                LSB = 1;
                LSA = 0;
                break; // 6
            case 2:
                LSC = 1;
                LSB = 0;
                LSA = 1;
                break; // 5
            case 3:
                LSC = 1;
                LSB = 0;
                LSA = 0;
                break; // 4
            case 4:
                LSC = 0;
                LSB = 1;
                LSA = 1;
                break; // 3
            case 5:
                LSC = 0;
                LSB = 1;
                LSA = 0;
                break; // 2
            case 6:
                LSC = 0;
                LSB = 0;
                LSA = 1;
                break; // 1
            case 7:
                LSC = 0;
                LSB = 0;
                LSA = 0;
                break; // 0
        }

        P0 = gsmg_code[n % 10];
        n  = n / 10;
        for (j = 0; j < 2; j++)
            ;
        P0 = 0x00;
    }
}
//外部中断0初始化
void exti0_init()
{
    EA  = 1;
    EX0 = 1;
    IT0 = 1;
}
//定时器0中断初始化
void timer0_init()
{
    TMOD |= 0x01;
    TH0 = 0x3c; // 定时约50ms
    TL0 = 0xc4;
    ET0 = 1;
    EA  = 1;
    TR0 = 1;
}

void main()
{
    exti0_init();
    while (1) {
    }
}

void exti0() interrupt 0
{
    cnt++;
    if (cnt == 1) {
        timer0_init();
    }
}
void timer0() interrupt 1
{
    static unsigned char i;
    TH0 = 0x64; // 计时会有误差,这里是根据实际情况修改过的,没有精确的计算
    TL0 = 0x22;
    i++;                 // i=200时约为10秒
    if (i == 200) {      //
        speed = cnt * 6; // 计算转速
        ET0   = 0;       // 关闭timer0中断允许
        TR0   = 0;       // 关闭定时器0
        while (1) {
            smg_display(speed); /* speed 速度,单位r/min */
        }
    }
}

效果

注意:测量时,红外模块应正好处于面临黑色out指示灯灭,面临周围白边out指示灯亮的位置。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值