STM32超声波模块测距串口输出/通用定时器中断并输出PWM控制舵机/系统定时器延时
生活随笔
收集整理的這篇文章主要介紹了
STM32超声波模块测距串口输出/通用定时器中断并输出PWM控制舵机/系统定时器延时
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
參考:stm32 超聲波模塊 原理 實現(xiàn)測距 +舵機使用
作者:點燈小哥
發(fā)布時間: 2021-03-10 19:37:16
網(wǎng)址:https://blog.csdn.net/weixin_46016743/article/details/114643703
目錄
- 效果展示
- 超聲波傳感器原理
- 超聲波測距編程步驟
- 代碼編寫
效果展示
超聲波傳感器原理
超聲波測距編程步驟
要配置三個結(jié)構(gòu)體
接線:
- Trig:PB11
- Echo:PB10
- PB5:連接舵機
代碼編寫
HC_SR04.h
#ifndef _HC_SR04_H //#ifndef #define #endif 條件編譯 為了防止重復(fù)編譯 #define _HC_SR04_H #include "stm32f10x.h" // Device headervoid HC_SR04(void); void Open_tim4(void); void Close_tim4(void); int GetEcho_time(void); float GetLength(void);//ECHO讀取 #define ECHO_Reci GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_10) //Trig發(fā)送 #define TRIG_Send(a) if(a) \//與下一行連接起來GPIO_SetBits(GPIOB, GPIO_Pin_11); \else \GPIO_ResetBits(GPIOB, GPIO_Pin_11) #endif超聲波HC_SR04.c
#include "stm32f10x.h" // Device header #include "HC_SR04.h" #include "SysTick.h"extern uint16_t mscount = 0; //extern 讓main函數(shù)也能使用這里這個void HC_SR04(void) {GPIO_InitTypeDef GPIO_HC_SR04init; //1.配置GPIO引腳結(jié)構(gòu)體 Trig PB11 Echo PB10TIM_TimeBaseInitTypeDef TIM_HC_SR04init; //2.配置定時器結(jié)構(gòu)體NVIC_InitTypeDef NVIC_HC_SR04init; //3.配置NVIC中斷控制器結(jié)構(gòu)體(TIM4定時器)NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//中斷組1//rcc.hRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//4.開啟GPIOB時鐘(在APB2總線上)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//定時器的時鐘//Trig PB11 發(fā)送GPIO_HC_SR04init.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_HC_SR04init.GPIO_Pin = GPIO_Pin_11; GPIO_HC_SR04init.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init( GPIOB, &GPIO_HC_SR04init );//Echo PB10 接收GPIO_HC_SR04init.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入 只要求高電平 高低電平直接檢測GPIO_HC_SR04init.GPIO_Pin = GPIO_Pin_10;GPIO_Init( GPIOB, &GPIO_HC_SR04init );//定時器4的配置TIM_HC_SR04init.TIM_ClockDivision = TIM_CKD_DIV1;//分頻系數(shù)1 不分頻 還是72MHzTIM_HC_SR04init.TIM_CounterMode = TIM_CounterMode_Up;//向上計數(shù)TIM_HC_SR04init.TIM_Period = 100 - 1 ; //1usTIM_HC_SR04init.TIM_Prescaler = 72 - 1 ; //72M 這兩個相乘7200/72 000 000 = 1usTIM_TimeBaseInit( TIM4, &TIM_HC_SR04init);TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//IT就是中斷 定時器中斷配置 中斷標(biāo)志:TIM_IT_Update是允許溢出/更新標(biāo)志位TIM_Cmd( TIM4, DISABLE ); //定時器先關(guān)閉 等測量距離時再打開 下面給出打開定時器函數(shù)//NVIC中斷控制器(TIM4定時器)NVIC_HC_SR04init.NVIC_IRQChannel = TIM4_IRQn;// 通道 中斷源是定時器4NVIC_HC_SR04init.NVIC_IRQChannelPreemptionPriority = 0;//搶占優(yōu)先級 給的最高的NVIC_HC_SR04init.NVIC_IRQChannelSubPriority = 0;//子優(yōu)先級NVIC_HC_SR04init.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_HC_SR04init); } //打開定時器4 void Open_tim4(void) {TIM_SetCounter( TIM4, 0);//開啟計數(shù)器計數(shù) 計數(shù)值從0開始mscount = 0; //需要計算高電平5次數(shù)值 取平均值 防止一次算的距離不精準(zhǔn)TIM_Cmd( TIM4, ENABLE ); //定時器使能 打開了 }//關(guān)閉定時器4 void Close_tim4(void) {TIM_Cmd( TIM4, DISABLE ); //關(guān)閉 }//定時器TIM4中斷服務(wù)函數(shù) 函數(shù)名不能改動 void TIM4_IRQHandler(void) {if ( TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //判斷是否發(fā)生中斷{TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除中斷的標(biāo)記位mscount++; //記錄發(fā)生的中斷次數(shù) 為了取5次測量計算提高精度//定時器中斷一次就是1us } }//獲取定時器計數(shù)器的值 得到Echo高電平的時間 int GetEcho_time(void) {uint32_t t = 0;t = mscount * 1000; //發(fā)生了多少次中斷 *1000 得到時間ms(一次中斷就是1us)t += TIM_GetCounter(TIM4);//獲取定時器計數(shù)值 {這兩行沒看懂 感覺重復(fù)了?}TIM4->CNT = 0;//代表向上增的寄存器(向上向下計數(shù) 前面章節(jié)有講) 要置零 重裝載ms_delay(50);//系統(tǒng)定時器延時return t; }//獲取超聲波測距距離 float GetLength(void) {int i = 0;uint16_t t = 0;float length = 0;float sum = 0;while(i != 5)//算5次 提高計算精度{TRIG_Send(1);us_delay(20);//硬件模塊要求發(fā)送高電平時間大于10usTRIG_Send(0);//此時超聲波開始工作了while(ECHO_Reci == 0);Open_tim4();i=i+1;while(ECHO_Reci == 1);Close_tim4();t = GetEcho_time();//計算ECHO高電平持續(xù)時間就能換算出距離length =((float) t / 58.0);sum = sum +length; }length = sum / 5.0;return length; }main.c
#include "stm32f10x.h" // Device header #include "usart.h" #include "led.h" #include "tim.h" #include "motor.h" #include "SysTick.h" #include "HC_SR04.h"//記得添加路徑void delay(uint16_t time) {uint16_t i = 0;while(time--){i=12000;while(i--);} }int main(void) {int pwmval = 195;float Length = 0;HC_SR04();Usart_Init();motor_config();while(1){int pwmval = 155;Length = GetLength();printf("%.3f\r\n",Length);//之前重定向print函數(shù) 串口打印輸出距離 串口小助手就能看到打印的距離了ms_delay(500);//再加一個距離判斷 將之前寫的舵機部分加進來即可控制舵機if(Length < 5){for(pwmval = 195; pwmval >= 155;pwmval -=15 )//逐步轉(zhuǎn)到位置{TIM_SetCompare2( TIM3, pwmval); //5. 配置PWM比較值 配合重裝載值生成占空比delay(1000);}}else if (Length > 5){TIM_SetCompare2( TIM3, pwmval-20); //讓舵機回去}} }總結(jié)
以上是生活随笔為你收集整理的STM32超声波模块测距串口输出/通用定时器中断并输出PWM控制舵机/系统定时器延时的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 客户端可以访问_Mysql客
- 下一篇: CodeIgniter框架下载辅助函数的