刚水完校际联赛对自己很不满意,继续学习32的同时,也开始接触一些模块
于是把HC-SR04的代码封装一下,感觉挺好用,虽然代码量不大,但算是一个开始吧
废话不多,直接上代码
.h文件:
#ifndef __HC_SR04_H__
#define __HC_SR04_H__
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#define TIM6_STOP_UP() TIM6_UP_FLAG = 0
#define TIM6_START_UP() TIM6_UP_FLAG = 1
#define TIM6_RESET() TIM6_UP_FLAG = 1;change_TIM6_time(0)
/* 初始化只用调用 HC_SR04_Init(定时器初始化 在HC_SR04_Init已调用)*/
/* 输出控制IO给超过10us的高电平,输入控制IO等待高电平,输入控制接收到高电平的时间就是声波来回走过的时间 */
/******************************************************* HC_SR04部分**************************************************************/
short HC_SR04_Init(GPIO_TypeDef *GPIO_IN,uint32_t IN_GPIO_Pin,GPIO_TypeDef *GPIO_OUT,uint32_t OUT_GPIO_Pin,uint16_t psc,uint16_t arr); //调用此函数初始化HC_SR04和所用定时器
double HC_SR04_get_len(void);//阻塞式获取距离
/********************************************************* 定时器部分 ************************************************************/
void btimer_x_Init(uint16_t psc,uint16_t arr); //定时器初始化 在HC_SR04_Init已调用
void change_TIM6_time(double new_time); //修改定时器时间
double get_TIM6_time(void); //获取定时器时间
#endif
.c文件:
#include "./BSP/HC-SR04/HC-SR04.h"
/******************************************************* HC_SR04部分**************************************************************/
typedef struct HC_SR04_IO{
GPIO_TypeDef *GPIO_IN;
uint32_t IN_GPIO_Pin;
GPIO_TypeDef *GPIO_OUT;
uint32_t OUT_GPIO_Pin;
}HC_SR04_IO;
HC_SR04_IO hc_sr04_io; /* HC_SR04使用的IO口 */
TIM_HandleTypeDef g_btimer_x_handle; /*定时器句柄*/
double TIM_time = 0; /* 记录超声波走过的时间 */
short TIM6_UP_FLAG = 1; /* 超声波时间计数标志 */
short HC_SR04_Init(GPIO_TypeDef *GPIO_IN,uint32_t IN_GPIO_Pin,GPIO_TypeDef *GPIO_OUT,uint32_t OUT_GPIO_Pin,uint16_t psc,uint16_t arr)
{
GPIO_InitTypeDef gpio_init_struct;
hc_sr04_io.GPIO_IN = GPIO_IN;
hc_sr04_io.GPIO_OUT = GPIO_OUT;
hc_sr04_io.IN_GPIO_Pin = IN_GPIO_Pin;
hc_sr04_io.OUT_GPIO_Pin = OUT_GPIO_Pin;
__HAL_RCC_GPIOA_CLK_ENABLE();
gpio_init_struct.Pin = IN_GPIO_Pin; //PA1是输入
gpio_init_struct.Mode = GPIO_MODE_INPUT;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIO_IN,&gpio_init_struct);
HAL_GPIO_WritePin(GPIO_IN,IN_GPIO_Pin,GPIO_PIN_RESET);
gpio_init_struct.Pin = OUT_GPIO_Pin; //PA4是输出
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIO_OUT,&gpio_init_struct);
HAL_GPIO_WritePin(GPIO_OUT,OUT_GPIO_Pin,GPIO_PIN_RESET);
btimer_x_Init(psc,arr);
return 1;
}
double HC_SR04_get_len()
{
//先给10us的高电平
HAL_GPIO_WritePin(hc_sr04_io.GPIO_OUT , hc_sr04_io.OUT_GPIO_Pin , GPIO_PIN_SET);
delay_us(10);
HAL_GPIO_WritePin(hc_sr04_io.GPIO_OUT , hc_sr04_io.OUT_GPIO_Pin , GPIO_PIN_RESET);
/* 阻塞等待:输入端接收到高电平后开始计时,变为低电平结束计时 */
while(HAL_GPIO_ReadPin(hc_sr04_io.GPIO_IN , hc_sr04_io.IN_GPIO_Pin) == GPIO_PIN_RESET);
TIM6_RESET(); //计时器从0开始计数
while(HAL_GPIO_ReadPin(hc_sr04_io.GPIO_IN , hc_sr04_io.IN_GPIO_Pin) == GPIO_PIN_SET);
TIM6_STOP_UP(); //计时器停止计数
return get_TIM6_time()*170/100; //TIM_time为10微秒计数,除以100000。 乘340,除以二算距离(米),乘以1000计算毫米
}
/********************************************************* 定时器部分 ************************************************************/
/* 定时器初始化函数 */
void btimer_x_Init(uint16_t psc,uint16_t arr)
{
g_btimer_x_handle.Instance = TIM6;
g_btimer_x_handle.Init.Prescaler = psc;
g_btimer_x_handle.Init.Period = arr;
HAL_TIM_Base_Init(&g_btimer_x_handle);
HAL_TIM_Base_Start_IT(&g_btimer_x_handle);
}
/* 基础定时器自定义初始化函数 */
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM6){
__HAL_RCC_TIM6_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(2);
HAL_NVIC_SetPriority(TIM6_IRQn,2,2);
HAL_NVIC_EnableIRQ(TIM6_IRQn);
}
}
/* 中断服务函数 */
void TIM6_IRQHandler()
{
/* 定时器公共函数 */
HAL_TIM_IRQHandler(&g_btimer_x_handle);
}
/* 定时器溢出中断回调函数 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance ==TIM6){ //
if(TIM6_UP_FLAG)TIM_time ++;
}
}
/*处理超声波时间函数*/
void change_TIM6_time(double new_time)
{
TIM_time = new_time;
}
double get_TIM6_time(void)
{
return TIM_time;
}
main函数可以写的很简单
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/HC-SR04/HC-SR04.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
usart_init(9600);
HC_SR04_Init(GPIOA,GPIO_PIN_1,GPIOA,GPIO_PIN_4,10-1,72-1);//使用PA1作为HC_SR04接收IO,PA4作为输出控制IO ,10us触发一次中断
while(1)
{
printf("检测到距离为:%f\r\n",HC_SR04_get_len());
delay_ms(50);
}
}
就这么多,最近考试,等月底会继续分享学习过程
如有代码不妥,感谢指点!