当前位置: 首页 > backend >正文

14.测速小车(测速模块)

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)    //9600bps@11.0592MHz
{
    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);
        }
    }
}

http://www.xdnf.cn/news/8967.html

相关文章:

  • Linux连接服务器全攻略:从基础到进阶
  • AI时代新词-生成对抗网络(GAN)
  • 最新Spring Security实战教程(十六)微服务间安全通信 - JWT令牌传递与校验机制
  • CMake指令:set()
  • 行为型:策略模式
  • Flink流处理基础概论
  • 20250526惠普HP锐14 AMD锐龙 14英寸轻薄笔记本电脑(八核R7-7730U)的显卡驱动下载
  • 记录 | Android TextView 中的滚动方向
  • 基于Python flask 的豆瓣电影top250数据评分可视化
  • 数据结构与算法学习笔记(Acwing 提高课)----动态规划·区间DP
  • 【C++指南】string(四):编码
  • 单细胞数据分析(五):三种整合单细胞数据(Harmony、fastMNN、SCTransform)的完整流程
  • 学员投稿:华为,ov等手机主流大厂桌面未读计数角标更新接口汇总
  • 解析Java String.getBytes()编码与new String()解码的字符集转换机制
  • 深入解析Kafka JVM堆内存:优化策略与监控实践
  • 深入理解JavaScript设计模式之原型模式
  • SpringBoot(四)--- Mybatis、PageHelper、事务
  • 【LLM】LLM源码阅读与分析工具DeepWiki项目
  • C++ 中的引用参数(Reference Parameter)‌
  • 数据结构第2章绪论 (竟成)
  • JavaWeb:SpringBoot Bean管理
  • 豆瓣电视剧数据工程实践:从爬虫到智能存储的技术演进(含完整代码)
  • 墨水屏 函数Paint_SetScale的详解
  • 【公式】MathType,axmath公式批量统一大小
  • MMDetection3D最全源码安装教程
  • Python打卡训练营day31-文件拆分
  • 【深度学习-Day 17】神经网络的心脏:反向传播算法全解析
  • 【工具变量】上市公司企业未来主业业绩数据集(2000-2023年)
  • 内存管理(第五、六章)
  • RV1126的RGA模块讲解