• 小车测速并通过串口发送速度数据


    小车测速并通过串口发送速度数据

    测速原理:

    小车车轮的直径是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++;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.添加定时器2 Timer2.c

    因为定时器1用作串口波特率发生器,定时器0用作PWM调速了,所以只能用定时器2作计时功能

    #include 
    
    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;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    3.Motor.c的引脚改一下

    原本rightA接到了P3_2口,而P3_2口是外部中断0,要接测速模块,所以rightA改为P3_7口;

    sbit rightA = P3^7;
    
    • 1

    4.main函数

    主函数中根据发送标志位调用串口发送函数进行速度发送

    注意:这里要记住sprintf的用法,这个函数非常好用,后面OLED显示小车速度也是用的这个函数

    #include 		//函数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;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    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:串口发送函数,串口中断处理函数,接收串口指令让小车启动,包括快速、中速、慢速模式选择

    在这里插入图片描述

  • 相关阅读:
    【C语言初阶(NEW)】五、操作符详解(二)|隐式类型转换|算术转换|操作符的属性
    GCC编译器
    PHP —— 一份前端开发工程师够用的知识点(框架篇)
    今天,该让 python 上个热门
    面向对象特性之继承
    Canvas变形
    计算属性computed、过滤器定义Vue.filter()
    MySQL主从复制与读写分离
    Java 类加载机制与双亲委派
    【数据结构】—堆排序以及TOP-K问题究极详解(含C语言实现)
  • 原文地址:https://blog.csdn.net/weixin_46251230/article/details/126404755