CS100A.c
#include "CS100A.h"
TIM_HandleTypeDef TimHandle;
uint16_t CS100A_count=0; //定时器中断中累加计数
float CS100A_distance=0; //计算超声波测得的距离,单位为cm
float err=15/15.98; //调整误差系数,由于各种原因会出现误差,这个用于调整误差系数,若不需要调整则设置为1
/*
//下面是main函数里面的代码初始化部分
//超声波引脚初始化
CS100A_INIT();
//超声波定时器计数初始化
CS100A_START();
//下面是main函数while(1)里面的超声波获取代码部分
printf("%f",CS100A_GET()); //串口打印超声波测距
HAL_Delay(500);
*/
/*
简易的us级别的延迟函数
我的芯片时钟是48Mhz
一个时钟周期是1/48M=0.020833us,一个机器周期包含12个时钟周期,所以一个机器周期是12*0.020833=0.25us
所以这里i++运行一次是0.25us,1us大概是运行4次
*/
void delay_us(uint16_t num)
{
for(uint16_t j=0;j<num;j++)
{
for(uint16_t i=0;i<4;i++){}//根据不同的芯片周期修改i的数值
}
}
//超声波模块的引脚初始化函数
void CS100A_INIT(void)
{
GPIO_InitTypeDef Trig = {.Pin = CS100A_Trig_PIN,.Mode = CS100A_Trig_MODE,};
CS100A_Trig_CLK;
HAL_GPIO_Init(CS100A_Trig, &Trig);
HAL_GPIO_WritePin(CS100A_Trig, CS100A_Trig_PIN,CS100A_Trig_ST);
GPIO_InitTypeDef Echo = {.Pin = CS100A_Echo_PIN,.Mode = CS100A_Echo_MODE,};
CS100A_Echo_CLK;;
HAL_GPIO_Init(CS100A_Echo, &Echo);
}
/*
给超声波模块发送开始信号
将Trig引脚拉高至少10us
*/
void CS100A_START(void)
{
CS100A_Trig_SET; //将Trig引脚拉高
delay_us(20); //延迟大概20us
CS100A_Trig_RST; //将Trig引脚拉低
}
/*
超声波Echo引脚读取高电平时间的定时器计数初始化
这里放的是合宙AIR001芯片的初始化部分
自行根据自己的芯片修改
我配置的定时器中断周期是10us
*/
void CS100A_TIM_INIT(void)
{
TimHandle.Instance = TIM1; /* 选择TIM1 */
TimHandle.Init.Period = 32 - 1; /* 自动重装载值 */
TimHandle.Init.Prescaler = 10 - 1; /* 预分频为1-1 */
TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; /* 时钟不分频 */
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; /* 向上计数 */
TimHandle.Init.RepetitionCounter = 1 - 1; /* 不重复计数 */
TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; /* 自动重装载寄存器没有缓冲 */
/* TIM1初始化 */
if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
{
while(1);
}
}
//更新中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
CS100A_count++;
}
//超声波获取数据
float CS100A_GET(void)
{
CS100A_START(); //给超声波模块发送开始信号
while(CS100A_Erig_READ==0); //等待高电平信号
/* TIM1使能启动,并使能中断 */
HAL_TIM_Base_Start_IT(&TimHandle);
while(CS100A_Erig_READ==1); //等待低电平信号
/* TIM1使能关闭,并关闭中断 */
HAL_TIM_Base_Stop_IT(&TimHandle);
CS100A_distance=CS100A_count*TIM_tim*0.034/2*err;
CS100A_count=0; //清除计数
return CS100A_distance;
}
CS100A.h
#ifndef _CS100A_H
#define _CS100A_H
#include "main.h"
//定义定时器中断时间,单位是us,这里定义的是100us
#define TIM_tim 10
//定义Trig引脚为推挽输出,初始化为低电平
#define CS100A_Trig GPIOA
#define CS100A_Trig_PIN GPIO_PIN_5
#define CS100A_Trig_CLK __HAL_RCC_GPIOA_CLK_ENABLE();
#define CS100A_Trig_MODE GPIO_MODE_OUTPUT_PP
#define CS100A_Trig_ST 0
//定义Echo引脚为浮空输入
#define CS100A_Echo GPIOA
#define CS100A_Echo_PIN GPIO_PIN_7
#define CS100A_Echo_CLK __HAL_RCC_GPIOA_CLK_ENABLE();
#define CS100A_Echo_MODE GPIO_MODE_INPUT
//设置Trig引脚为高电平
#define CS100A_Trig_SET HAL_GPIO_WritePin(CS100A_Trig, CS100A_Trig_PIN,1)
//设置Trig引脚为低电平
#define CS100A_Trig_RST HAL_GPIO_WritePin(CS100A_Trig, CS100A_Trig_PIN,0)
//读取Erig引脚的电平状态
#define CS100A_Erig_READ HAL_GPIO_ReadPin(CS100A_Echo,CS100A_Echo_PIN)
void delay_us(uint16_t num);
void CS100A_INIT(void);
void CS100A_START(void);
void CS100A_TIM_INIT(void);
float CS100A_GET(void);
#endif
我最近建了一个嵌入式的QQ交流群,感兴趣的可以进群了解一下,我会在群里分享一些常用的代码封装,以及一些项目的源码。QQ群讨论也是完全开放,只要不打广告大家可以就嵌入式尽情的沟通和交流,大家对文章中的内容有疑问也可以在群中提出,有空会尽我所能给大家一些帮助。QQ群号:643408467