?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
我最近发了一篇文章里面包含了常用的功能函数以及常用的模块底层驱动函数封装库,大家感兴趣的可以收藏一下,需要的时候就不用到处找代码,一篇就够用,我会持续更新。
????????常用模块函数封装库(持续更新中。。。。。。)-CSDN博客?