找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1037|回复: 1
打印 上一主题 下一主题
收起左侧

寄存器写的stm32单片机驱动超声波模块,一直卡在检测回响信号那里

[复制链接]
跳转到指定楼层
楼主
寄存器写的stm32驱动超声波模块,一直就在检测上升沿电平那里出不来。用的串口获得详细数据,
已解决,模块电压问题,应接5V电压,我接成3.3V,32搞长了,忘记当初做51时是5V供电了。
  1. //#include "stm32f10x.h"
  2. #include "led.h"
  3. #include "sys.h"
  4. #include "sysclock.h"
  5. #include "key.h"
  6. #include "exti.h"
  7. #include "time.h"
  8. #include "pwm.h"
  9. #include "usart.h"<div class="blockcode"><blockquote>#include"hc04.h"

  10. u8 msHcCount = 0;//ms计数

  11. void Hr_hc04_Init(void)        
  12. {
  13.         TIM2_Init(1000-1,72-1);//分频系数72,循环1000次1000us
  14.         
  15.         RCC->APB1ENR |= 1<<6; //GPIOE时钟使能
  16.         
  17.         GPIOE->CRL &= 0xfffff00f;//设置位重置 E1、E2
  18.         
  19.         //E1推挽输出
  20.         GPIOE->CRL |= 0x1<<4;
  21.         //E2浮空输入
  22.         GPIOE->CRL |= 0x4<<8;
  23.         
  24.         GPIOE->ODR|=~(1<<1);//E1一开始低电平
  25.         GPIOE->ODR|=~(1<<2);//E2一开始低电平
  26. }


  27. static void OpenTimer()        //打开定时器
  28. {
  29.   //清除计数器
  30.         TIM_SetCounter(TIM2,0);
  31.         msHcCount = 0;
  32.         TIM_Cmd(TIM2,ENABLE);//使能定时器
  33.         USARTx_Send_String(USART1,"定时器开启\r\n");
  34. }

  35. static void CloseTimer()        //关闭定时器
  36. {
  37.        //        /*关闭计数器使能*/
  38.         TIM_Cmd(TIM2,DISABLE);
  39. }

  40. //获取定时器时间
  41. u32 GetEchoTimer(void)
  42. {
  43.    u32 time = 0;
  44.         /*//当回响信号很长是,计数值溢出后重复计数,overCount用中断来保存溢出次数*/
  45.         time = msHcCount*1000;//overCount每++一次,代表overCount毫秒,time微妙
  46.         time += TIM_GetCounter(TIM2);//获取计TIM2数寄存器中的计数值,一边计算回响信号时间
  47.         TIM6->CNT = 0;  //将TIM2计数寄存器的计数值清零
  48.         delay_ms(50);
  49.         USARTx_Send_String(USART1,"获取定时器时间:");
  50.         USARTx_Send_number(USART1,time);
  51.         USARTx_Send_String(USART1,"\r\n");
  52.         return time;

  53. }

  54. /*
  55.                 trig_T = 1;//trig拉高信号,发出高电平
  56. //                GPIOE->ODR |= 1<<1;
  57.                 if((GPIOE->IDR & 0x0002));//echo等待回响
  58.                 {
  59.                         USARTx_Send_String(USART1,"trig_T置高位成功\r\n");
  60.                 }
  61.                 delay_us(20);//持续时间超过10us
  62. //                trig_T = 0;
  63.                 GPIOE->ODR |= ~(1<<1);
  64.                 USARTx_Send_String(USART1,"开启信号已发出456\n");
  65.                 while(!(GPIOE->IDR & 0x0004))//echo等待回响
  66.                 {
  67.                         i++;
  68.                         if(i>=10000)
  69.                         {
  70.                                 USARTx_Send_String(USART1,"回响信号检测失败\n");
  71.                                 break;
  72.                         }
  73.                 }
  74.                 USARTx_Send_String(USART1,"等待结束,计时中789\r\n");
  75.                 delay_ms(50);
  76.                
  77.                
  78. */

  79. float Hcsr04GetLength(void )
  80. {
  81.         /*测5次数据计算一次平均值*/
  82.         float length = 0;
  83.         float t = 0;
  84.         float sum = 0;
  85.         u16          i = 0;
  86.         u16 ttt;
  87.         while(i != 5)
  88.         {
  89.                
  90.                 trig_T = 1;//trig拉高信号,发出高电平
  91. //                GPIOE->ODR |= 1<<1;
  92.                
  93.                 if((GPIOE->IDR & 0x0002));//echo等待回响
  94.                 {
  95.                         USARTx_Send_String(USART1,"trig_T置高位成功\r\n");
  96.                 }
  97.                 delay_us(20);//持续时间超过10us
  98.                
  99. //                trig_T = 0;
  100.                 GPIOE->ODR |= ~(1<<1);
  101.                 USARTx_Send_String(USART1,"开启信号已发出\r\n");
  102.                
  103.                 /*Echo发出信号 等待回响信号*/
  104.                 /*输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;
  105.                 (此时应该启动定时器计时);当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;
  106.                 (此时应该停止定时器计数),定时器记下的这个时间即为
  107.                         超声波由发射到返回的总时长;*/
  108. //                while(echo_R == 0);//echo等待回响
  109.                 while(!(GPIOE->IDR & 0x0004))//echo等待回响
  110.                 {
  111.                         ttt++;
  112.                         if(ttt>=50000)
  113.                         {
  114.                                 USARTx_Send_String(USART1,"回响信号检测失败\r\n");
  115.                                 break;
  116.                         }
  117.                 }
  118.                 USARTx_Send_String(USART1,"等待结束,计时中\r\n");
  119.                 /*开启定时器*/
  120.                 OpenTimer();
  121.                 i = i+1; //每收到一次回响信号+1,收到5次就计算均值
  122. //                while(echo_R == 1);
  123.                 while((GPIOE->IDR & 0x0004))//echo等待回响
  124.                 {
  125.                         ttt++;
  126.                         if(ttt>=50000)
  127.                         {
  128.                                 USARTx_Send_String(USART1,"等待回响失败\r\n");
  129.                                 break;
  130.                         }
  131.                 }
  132.                 /*关闭定时器*/
  133.                 CloseTimer();
  134.                 /*获取Echo高电平时间时间*/
  135.                 t = GetEchoTimer();
  136.                 length = (float)t/58;//单位时cm
  137.                 sum += length;               
  138.         }
  139.         length = sum/5;//五次平均值
  140.         
  141.         return length;
  142. }

  143. void TIM2_IRQHandler(void)
  144. {
  145.         if(TIM2->SR &0X0001)//溢出中断
  146.         {
  147.                 msHcCount++;
  148.                 TIM2->SR &=~(1<<0);//清除中断标志位
  149.         }
  150. }


复制代码
  1. #ifndef __hc04_h
  2. #define __hc04_h

  3. #include "sys.h"
  4. #include "stm32f10x.h"
  5. #include "time.h"
  6. #include "sysclock.h"
  7. #include "usart.h"

  8. #define trig_T  PEout(1)
  9. #define echo_R  PEin(2)

  10. void Hr_hc04_Init(void);
  11. float Hcsr04GetLength(void );


  12. #endif

复制代码
  1. #include "time.h"



  2. //设置 TIMx 计数器寄存器值
  3. void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)
  4. {

  5.   /* Set the Counter Register value */
  6.   TIMx->CNT = Counter;
  7. }



  8. //使能或者失能 TIMx 外设
  9. void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
  10. {
  11.   
  12.   if (NewState != DISABLE)
  13.   {
  14.     /* Enable the TIM Counter */
  15.     TIMx->CR1 |= TIM_CR1_CEN;
  16.   }
  17.   else
  18.   {
  19.     /* Disable the TIM Counter */
  20.     TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));
  21.   }
  22. }



  23. //获取计时次数
  24. uint16_t TIM_GetCounter(TIM_TypeDef* TIMx)
  25. {
  26.   return TIMx->CNT;
  27. }


  28. //自动装载寄存器 (TIMx_ARR)
  29. //预分频器寄存器 (TIMx_PSC)
  30. //AHB不分频;APB2不分频;APB1二分频 APB1=72/2 TIM_CLk=72
  31. void TIM2_Init(u16 arr,u16 psc)
  32. {
  33.         RCC->APB1ENR|=1<<0;        //使能TIM2时钟
  34.         
  35.         TIM2->PSC=psc;        //预分频器寄存器
  36.         TIM2->ARR=arr;        //自动装载寄存器
  37.         
  38.         TIM2->DIER|=1<<0;        //允许更新中断
  39.         TIM2->DIER|=1<<6;        //使能触发中断
  40.         
  41. //        TIM2->CR1|=1<<0;        //使能计数器  //外部函数TIM_Cmd 实现
  42.         
  43.         NVIC_Init(2,1,TIM2_IRQn,2);
  44. }

  45. /*超声波中设置
  46. void TIM2_IRQHandler(void)
  47. {
  48.         if(TIM2->SR &0X0001)//溢出中断
  49.                 LED1=!LED1;
  50.         
  51.         TIM2->SR &=~(1<<0);//清除中断标志位
  52. }

  53. */
复制代码
  1. #ifndef _time_h
  2. #define _time_h
  3. #include "exti.h"
  4. #include "sysclock.h"

  5. void TIM2_Init(u16 arr,u16 psc);
  6. //设置 TIMx 计数器寄存器值
  7. void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
  8. //使能或者失能 TIMx 外设
  9. void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
  10. //获取计时次数
  11. uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

  12. #endif
复制代码


#include "hc04.h"
int main()
{
        int temp=0;
        System_clock(9);
        SysTick_init(72);
        uart_init(72,9600);//时钟频率(Mhz) 波特率
        LED_Init();
//        TIM2_Init(1000-1,72-1);//分频系数72,循环1000次1000us  //放在hc04.c里了
        Hr_hc04_Init();
        delay_ms(50);
        while(1)
  {
                delay_ms(500);
        
                USARTx_Send_String(USART1,"测试距离:123");
                delay_ms(10);
                temp=Hcsr04GetLength();
                delay_ms(10);
                USARTx_Send_number(USART1,temp);
                delay_ms(10);
                USARTx_Send_String(USART1,"cm\r\n");
                delay_ms(10);
                LED4=!LED4;
                delay_ms(10);
  }
}


void SystemInit(void)
{

}




20210226191003352.png (106.98 KB, 下载次数: 58)

20210226191003352.png

新建文件夹.7z

205.5 KB, 下载次数: 2

工程文件

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:997450 发表于 2022-10-22 21:00 | 只看该作者
实锤了,我是蠢货,我给HC-SR04超声波的供电一直是3.3V,怪不得卡在电平检测环节。对于单片机来说,电平就是0和1,我的被卡住的电平检测环节检测的电平就是由我的超声波模块的echo引脚电平,模块给单片机发送信号,由自身供电,本该接5V电压,接了3.3V。供电不足,模块发出的高电平信号可能就上不去,就一直是0而不是1了。这是我的个人理解,也许供电不足模块根本无法工作,压根没开始。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表