目录
1、简介
2、传感器介绍
2.1 引脚介绍
2.2 时序图介绍
3、 需求与接线
3.1 任务需求
3.2 接线
4、Cubemax配置
4.1 SYS配置
4.2 RCC配置
4.3 时钟树配置
4.4 GPIO初始化
4.5 定时器配置
4.6 生成代码
5、 keil端代码编写
5.1 微妙函数封装
5.2 超声波驱动封装
5.2.1 引脚宏定义
5.2.2 按时序图进行封装
5.2.3 封装函数
5.3 任务实现
1、简介
在单片机开发中,最开始是直接使用厂家提供的驱动,有时候厂家不提供或者好用时候还会网上复制被人的驱动,但是有的并没有资源可用,此时就需要自己按照说明书/使用手册进行驱动的封装,本文就是从最简单的超声波超声波传感器开始进行练习驱动的封装。
2、传感器介绍
2.1 引脚介绍
VCC、GND 电源引脚(DC5V)。
Trig 接高电平会发出信号。
Echo 由低电平转到高电平,开始发送波。由高电平转到低电平,表示波返回。
2.2 时序图介绍
流程:
首先给Trig10us的高电平信号,进行信号触发,当信号触发后,Echo会从低电平跳转到高电平开始发出超声波,当遇到障碍物,超声波会返回,此时Echo由高电平转到低电平,表示波返回。
距离计算:
高电平持续的时间就是超声波发出的时间,因此在波发出的时候就需要启动定时器计算时间t。因为超声波遇到障碍物返回,所以计算距离应该将t/2处理,得到单程的时间。
Distance = v * t /2。
v = 340m/s
3、 需求与接线
3.1 任务需求
当距离小于10cm,LED灯被点亮,大于10cm时LED灯处于熄灭状态。
3.2 接线
LED ---- PB0
Trig ---- PB6
Echo --- PB7
4、Cubemax配置
4.1 SYS配置
4.2 RCC配置
4.3 时钟树配置
直接在红框内输入下方数值,回车确定即可自动对时钟树进行配置。
4.4 GPIO初始化
4.5 定时器配置
定时器只用作计数,不用做定时,如下图所示:
计算:
T = (arr+1)/TCK= (71+1)/(72000000)//1M等于1000000hz= 1us
因此按照如上配置,计数一次代表1us。
4.6 生成代码
5、 keil端代码编写
5.1 微妙函数封装
需要一个10us延时进行信号触发,但是HAL库并不具备微妙级函数,因此需要在主函数上方进行微秒级函数封装,封装函数如下所示:
void TIM2_Delay_us(uint16_t n)
{__HAL_TIM_ENABLE(&htim2);//使能定时器__HAL_TIM_SetCounter(&htim2,0);while(__HAL_TIM_GET_COUNTER(&htim2) <(n-1));__HAL_TIM_DISABLE(&htim2);//关闭定时器
}
5.2 超声波驱动封装
5.2.1 引脚宏定义
为了便于函数的整理,首先在main.h中进行宏定义,如下所示:
#define Trig_up HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET)
#define Trig_Down HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET)
#define Trig HAL_GPIO_ReadPin(Trig_GPIO_Port,Trig_Pin)
#define Echo_up HAL_GPIO_WritePin(Echo_GPIO_Port,Echo_Pin,GPIO_PIN_SET)
#define Echo_Down HAL_GPIO_WritePin(Echo_GPIO_Port,Echo_Pin,GPIO_PIN_RESET)
#define Echo HAL_GPIO_ReadPin(Echo_GPIO_Port,Echo_Pin)
#define LED_up HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET)
#define LED_Down HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET)
#define LED HAL_GPIO_ReadPin(LED_GPIO_Port,LED_Pin)
5.2.2 按时序图进行封装
观察时序图,首先需要Trig一个大于10us高电平进行信号触发,如下代码所示:
Trig_up;
TIM2_Delay_us(20);
Trig_Down;
Echo由低电平转到高电平,表示波已发出,当波发出去时候进行定时器的启动,如下所示:
while(Echo==0);
HAL_TIM_Base_Start(&htim2);//开启定时器
Echo由高电平转到低电平,超声波遇到障碍物返回,关闭定时器,如下所示:
while(Echo==1);
HAL_TIM_Base_Stop(&htim2);//关闭定时器
接着进行时间与距离的计算,如下所示:
*cnt = __HAL_TIM_GET_COUNTER(&htim2);//计数一次是1us *dis = 340*(*cnt)/2*0.000001*100;//1us = 0.000001s 1m = 100cm
5.2.3 封装函数
void HCSR(int *cnt,float *dis)
{//Trig大于10us高电平Trig_up;TIM2_Delay_us(20);Trig_Down;//Echo由低电平转到高电平,开始发送超声波while(Echo==0);HAL_TIM_Base_Start(&htim2);//开启定时器//Echo由高电平转到低电平,超声波遇到障碍物返回while(Echo==1);HAL_TIM_Base_Stop(&htim2);//关闭定时器//计算时间*cnt = __HAL_TIM_GET_COUNTER(&htim2);//计数一次是1us //距离计算*dis = 340*(*cnt)/2*0.000001*100;//1us = 0.000001s 1m = 100cm}
5.3 任务实现
最后在主函数的while中进行逻辑代码的实现,如下所示:
while (1){int cnt = 0;float dis = 0;HCSR(&cnt,&dis);if(dis<5){LED_up;}else{LED_Down;}HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}