STM32单片机 关于超声波模块的学习(1)

分享一篇我刚刚弄完的一个超声波模块的学习

超声波模块的介绍:

1.单片机的一个IO口发送高电平的信号给Trig,信号时间要大于10us
2.然后模块的内部会发送方波
3.然后Echo会给单片机的IO口发送高电平,这个高电平持续的时间是超声波模块从碰到物体再返回的时间

模块的连接问题

我使用的是CH340G模块与电脑进行通信
在这里插入图片描述

编程思路:

1、先需要去配置定时器(基本定时器也可以,我用的是TIM2),还有串口的配置,还有延时函数的配置(推荐大家使用systick定时器)因为比较精准
2、基本的配置好了下面就要去写程序了
先随便定义两个IO口,连接Trig的IO口配置要推挽输出,连接Echo的IO口要浮空输入。
3、我看好多大神写的程序都是给Trig一个超过10us的高电平的时候进行了位操作和51很像,是定义在了sys.h这个头文件里。其实这个位操作在keil5中我没有看到有sys.h这个头文件,其实没有咱们也可以用STM32中的库函数去代替
4、给Trig发送高电平可以直接用GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);函数
5、检测Echo传给IO口的高电平时使用
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);函数
这个函数的说明是读取他输入的这个位的值
6、然后给Trig高电平超过10us然后在置低,然后等待Echo连接的IO口为高电平的时候开始打开定时器,开始计数,等待Echo连接的IO口为低电平的时候在关闭定时器,时间的确定就需要去定义一个全局变量msHcCount来记录定时器溢出的次数。定时器时间的计算是在你配置好了重装在计数器的值和时钟的分频以后 定时器记录的总时间=中断溢出次数*(时钟分频+1)/系统时钟*(重装载计数器的值+1)+一个库函数uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);这个库函数是记录的时间是当不满足溢出一次次数的时候剩余的值(因为如果假设你设置的重装载寄存器的值是999,到990的时候如果此时信号高电平停止,那么这个时间你就不知道是多少了,因为他不满足定时器一次的溢出情况,就需要这个函数来把剩余的时间算出来)
时间计算和好了以后,为低电平关闭定时器,然后时间有了你就可以通过公式算出距离了。

程序我下一篇会发

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!以下是一份基于STM32单片机利用超声波模块进行水位检测的C语言代码示例: ```c #include "stm32f10x.h" #include "stdio.h" #define TRIG_PIN GPIO_Pin_0 #define ECHO_PIN GPIO_Pin_1 void delay_us(uint32_t us) { us *= 8; while(us--) { __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } } void TIM2_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = (72 - 1); TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_Cmd(TIM2, ENABLE); } void GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = TRIG_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = ECHO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); } float measureWaterLevel(void) { uint32_t start_time = 0, end_time = 0; float distance = 0; GPIO_SetBits(GPIOA, TRIG_PIN); delay_us(10); GPIO_ResetBits(GPIOA, TRIG_PIN); while(GPIO_ReadInputDataBit(GPIOA, ECHO_PIN) == RESET); start_time = TIM_GetCounter(TIM2); while(GPIO_ReadInputDataBit(GPIOA, ECHO_PIN) == SET); end_time = TIM_GetCounter(TIM2); distance = (end_time - start_time) * 0.017; // 声波速度为340m/s,除以2得到的是往返距离,所以再除以2得到的是单程距离 return distance; } int main(void) { float water_level = 0; TIM2_Init(); GPIO_Init(); while(1) { water_level = measureWaterLevel(); printf("Water Level: %.2f cm\n", water_level); delay_us(1000000); // 每隔1秒进行一次水位检测 } } ``` 这段代码使用了STM32的定时器和GPIO模块,通过超声波模块测量水位。请根据自己的硬件连接情况进行相应的引脚配置和修改。同时,需要在工程中添加对应的库文件和头文件。 注意,这只是一个简单的示例代码,实际应用中可能需要根据具体的超声波模块和硬件环境进行相应的调试和优化。希望对你有所帮助!如果有任何疑问,请随时向我提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值