admin管理员组文章数量:1558896
本次实验是用HAL库编写定时器捕获程序,来获得距离值,并通过串口助手显示距离值。移植的是原子的实验九输入捕获实验的程序
实验前准备:
- 阿波罗STM3F429开发板
- HC-SR04超声波模块
- 串口调试助手
- 四根杜邦线
关于HC-SR04超声波测距模块,需要注意看它的时序图,如下:
可知使用该模块我们需要给至少10us的触发信号,在本实验中我给了20us的触发信号:
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//打开PB6
delay_us(20);//向PB6输入一个长为20us的高电平方波
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);//关闭PB6
而模块内部发出信号是传感器自动回应的,不需要代码去实现。
输出回响信号是通过对输入捕获实现,在向上计数模式下,通过计算高电平的时间,即捕获一次上升沿,清零计数器的值后再捕获一次下降沿的值,根据定时器的计数频率,就可以算出两次捕获的时间,从而得到高电平脉宽,也就得到了距离。(详细请看正点原子STM32F429开发指南-HAL库版本_V1.1——实验九输入捕获实验)
接线如下:
HC-SR04 STM32
VCC -> VCC
Trig -> PB6
Echo -> PA0
GND -> GND
下面贴出我觉得需要注意的地方的代码:
//定时器5初始化
void ultrasound_init()
{
TIM5_Handler.Instance=TIM5;//定时器5
TIM5_Handler.Init.Prescaler=90-1;//预分屏系数
TIM5_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数
TIM5_Handler.Init.Period=0xFFFFFFFF;//自动装载值
TIM5_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; //时钟分频因子
HAL_TIM_IC_Init(&TIM5_Handler);
TIM5_CH1Config.ICPolarity=TIM_ICPOLARITY_RISING;//上升沿捕获
TIM5_CH1Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//映射到TI1上
TIM5_CH1Config.ICPrescaler=TIM_ICPSC_DIV1;//配置输入分频,不分频
TIM5_CH1Config.ICFilter=0;//配置输入滤波器,不滤波
HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH1Config,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_1); //开启TIM5的捕获通道1,并且开启捕获中断
__HAL_TIM_ENABLE_IT(&TIM5_Handler,TIM_IT_UPDATE); //使能更新中断
}
//定时器5回调函数
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM5)
{
__HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA时钟
__HAL_RCC_TIM5_CLK_ENABLE();//使能TIM5时钟
GPIO_Initure.Pin=GPIO_PIN_0;//Pin0
GPIO_Initure.Mode=GPIO_MODE_AF_PP;//复用推挽输出
GPIO_Initure.Speed=GPIO_SPEED_HIGH;//高速
GPIO_Initure.Pull=GPIO_PULLDOWN;//下拉
GPIO_Initure.Alternate=GPIO_AF2_TIM5;//PA0 复用为 TIM5 通道 1
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
HAL_NVIC_SetPriority(TIM5_IRQn,2,0); //设置中断优先级,抢占 2,子优先级 0
HAL_NVIC_EnableIRQ(TIM5_IRQn); //开启 ITM5 中断通道
}
__HAL_RCC_GPIOB_CLK_ENABLE(); //使能PB时钟
GPIO_InitStructure.Pin= GPIO_PIN_6;
GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP;//推挽输出
GPIO_InitStructure.Pull=GPIO_PULLUP;//上拉
GPIO_InitStructure.Speed=GPIO_SPEED_HIGH;//高速
HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
}
一开始调试的时候我得到的距离是0,后来对比了一下别人的代码,发现我GPIOA的管脚模式选择错了,应该要选择GPIO_MODE_AF_PP(复用推完输出),第二个是 HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_1); 开启中断函数弄错了,不知怎么就少写了_IT,导致后面检查才发现没开启中断。实在是太大意了。
接下来是主函数的测距实现:
int main(void)
{
long time=0;
float Distance;
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
LED_Init(); //初始化LED
ultrasound_init(); //以1MHZ的频率计数
while (1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//打开PB6
delay_us(20);//向PB6输入一个长为20us的高电平方波
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);//关闭PB6
//delay_us(20);
if(TIM5CH1_CAPTURE_STA&0X80) //成功捕获到了一次高电平
{
time=TIM5CH1_CAPTURE_STA&0X3F;
time*=0XFFFFFFFF; //溢出时间总和
time+=TIM5CH1_CAPTURE_VAL; //得到总的高电平时间
Distance=time*340/20000;
printf("the distance is %.2f cm\r\n",Distance);
delay_ms(1000);
TIM5CH1_CAPTURE_STA=0; //开启下一次捕获
}
}
}
Distance=time*340/20000;声音在空气中传播的大约速度为340m/s,而且是一个回传,所以得到的距离还需要除以2才是最后的实际距离。(计算的Distance单位是cm)
详细解释看mc.six的帖子
实验测出距离如下:
版权声明:本文标题:STM32F429使用HC-SR04输出距离到串口助手 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1727405441a1113320.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论