
一STM32CubeMx的工程配置创建STM32工程首先勾选SYS里面的Debug选择Serial Wire否则下一次将无法烧录关闭SWD烧录接口会出现无法烧录的情况。之后配置RCC时钟选择高速的外部晶振。首先在直接红框1内配置输入72点击回车之后选择OKSTM32CubeMx会自动帮你把时钟修改为72Mhz可以在时钟树的右侧看到此时挂载在APB和APPB2上的时钟频率都是72Mhz我们本次采用定时器2设置时钟源为内部时钟使用通道一设置为输入捕获直接模式这个可以去读取Echo反馈引脚的时间状态下面会讲解。同时设置PSC频率为72-1也就是技术每次加一经过1us。开启定时器2的全局中断。在右侧可以看到定时器2的通道一对应PA0引脚。也就是Echo引脚接入PA0下面会讲解。之后需要设置Trig引脚我们选择PA5作为触发引脚设置其为推挽输出模式。另外我们起了个别的名字叫做Trig后面使用可以方便一点。按照下面配置生成信息Copy only the necessary library files 勾选该选项可以只生成需要的文件可以加快编译速度以及减少文件体积。勾选Generate peripheral initialization as a pair of.c/.h files per peripheral 可以去把每种文件都独立生成.C和.h文件点击Open Project可以直接打开Keil二Hal库代码的编写下面是超声波模块,以及其引脚的标注注意Echo和Trig引脚观察超声波模块的时序图发现触发信号是10us的高电平也就是给Trig引脚10us的高电平之后模块内部会自动触发信号回响信号高电平持续的时间就是距离对应的时间也就是需要读取Echo引脚高电平的持续时间。标况下声速是340m/s读取的时间是发射到接受一来一回也就是实际距离的两倍。首先我们定义两个标志位以及写出读取函数的初始化函数在初始化函数中再次确认计数值为0然后设置输入捕获是高电平捕获之后在开启输入捕获的中断。也就是说 PA0读取到高电平时候会进入中断我们记录时间。uint8_t echo_flag 0; // 捕获标志位uint16_t rising_cnt 0, falling_cnt 0; // 上升沿、下降沿数值void distance_init(){__HAL_TIM_SET_COUNTER(htim2, 0);// 开始捕获__HAL_TIM_SET_CAPTUREPOLARITY(htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);HAL_TIM_IC_Start_IT(htim2, TIM_CHANNEL_1);}之后我们书写输入捕获终中断回调函数第一次进来是上升沿我们记录此时的时间之后再设置为下降沿捕获当下降沿捕获后再次进入中断我们可以读取下降沿的此时时间。void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){if (htim htim2 htim-Channel HAL_TIM_ACTIVE_CHANNEL_1){if (!echo_flag) // 捕获到上升沿{rising_cnt HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);echo_flag 1;__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);}// 捕获到下降沿else{falling_cnt HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);echo_flag 0;__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);}}}在上面我们已经获得了高电平持续的时间我们就可以编写距离读取的函数了我们先给触发引脚高电平在经过一个11us的延时之后进入低电平再次确保我们的计数值是0防止溢出然后就可以用高电平的时间计算时钟。uint16_t distance_read(){uint16_t distance;HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET);delay_us(11);HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET);__HAL_TIM_SET_COUNTER(htim2, 0);distance (falling_cnt - rising_cnt) * 0.017;return distance;}该方法可以就阻塞11us不需要一直等待测距结束测距记录时间在中断中实现。使用时候我们定义一个距离数值如下。uint16_t distance;之后在While(1)前面初始化时候调用初始化函数如下。distance_init();最后在while(1)里面一直调用距离读取函数distance就是我们读取到的距离distancedistance_read();至此教程结束感谢大家观看欢迎大家评论留言。有求必应