• STM32避障小车HC-SR04超声波模块程序卡死问题


            能找到这的肯定是找了好久没找到问题的,代码就不介绍了,直接说问题。

            单独使用HC-SR04测距没问题,但涉及到测距控制小车移动就会卡死(能找到这的应该都知道),经过我的测试,卡在了等待接收超声波返回信号这行代码,只需要再增加一个计时变量(和超声波计时变量同步计时),放在中断里++,然后这个变量放在等待接收超声波信号这行代码中if时间大于等待时间就break;这个等待时间可以自己设置。

            举个例子,下面是我的代码,我增加了个T用来计时,10us进一次中断,我的主程序中,小车距离障碍物大于200mm就前行,如果T设置成T*10/1000=38ms的话,卡死的时候就要卡38ms,小车就认为距离前方障碍物4米,如果前方有障碍物就会撞上去,所以我T设置成1995(小车认为距离前方障碍物210mm),小车就会快点的脱离卡死,并且210mm大于200mm,小车还是前进。简单说这句话的逻辑就是:如果T=1995,超声波没有返回 ,认为前方无障碍物,退出等待信号循环,小车前进(我代码有写手动翻转电平)。我就是这样防止卡死,当然这个防卡死时间我这个不一定是最合适的,大家根据自己的实际情况自己配置,希望对大家有所帮助。能力有限,有不足之处还望谅解。

    1. #include "stm32f10x.h" // Device header
    2. #include "Delay.h"
    3. #include "Timer1.h"
    4. #define Trig GPIO_Pin_0 //HC-SR04模块的Trig脚接GPIOA1
    5. #define Echo GPIO_Pin_1 //HC-SR04模块的Echo脚接GPIOA2
    6. uint64_t Time=0,T=0; //用来计时
    7. uint64_t Time_end=0; //接收保存计时,用来对比
    8. void HC_SR04_Init(void) //超声波检测
    9. {
    10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    11. GPIO_InitTypeDef GPIO_InitStructure;
    12. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
    13. GPIO_InitStructure.GPIO_Pin=Trig;
    14. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    15. GPIO_Init(GPIOA,&GPIO_InitStructure);
    16. GPIO_WriteBit(GPIOA,Trig,Bit_RESET); //先将端口拉低防止干扰
    17. Delay_us(15);
    18. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD; //下拉输出
    19. GPIO_InitStructure.GPIO_Pin=Echo;
    20. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    21. GPIO_Init(GPIOA,&GPIO_InitStructure);
    22. Timer1_Init(); //开启定时器中断
    23. }
    24. uint16_t HC_SR04_Time(void) //计算距离
    25. {
    26. uint32_t distance_mm=0; //距离
    27. GPIO_WriteBit(GPIOA,Trig,Bit_SET); //给至少10us高电平启动模块
    28. Delay_us(50);
    29. GPIO_WriteBit(GPIOA,Trig,Bit_RESET); //输出低电平
    30. TIM_Cmd(TIM2,ENABLE); //开启TIM2定时器
    31. while(GPIO_ReadInputDataBit(GPIOA,Echo)==0)
    32. {
    33. Time=0; //低电平未开始time为0
    34. if(T>1995)
    35. {
    36. break;
    37. }
    38. }
    39. GPIO_WriteBit(GPIOA,Echo,Bit_SET); //输出高电平
    40. while(GPIO_ReadInputDataBit(GPIOA,Echo)==1){Time_end=Time;} //高电平开始计时time增加赋值给Time_end
    41. TIM_Cmd(TIM2,DISABLE); //关闭TIM2定时器
    42. TIM_SetCounter(TIM2,0); //计数器清零
    43. T=0; //防卡死计时清零
    44. if(Time_end/100<38)
    45. {
    46. distance_mm=(Time_end*346)/200; //距离计算,声音在25℃空气中传播速度为346mm/ms
    47. }
    48. return distance_mm;
    49. }
    50. void TIM2_IRQHandler(void) //TIM2中断函数
    51. {
    52. if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
    53. {
    54. Time++;
    55. T++;
    56. }
    57. TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    58. }

  • 相关阅读:
    嵌入式Linux应用开发-基础知识-第十九章驱动程序基石②
    javax.net.ssl.SSLHandshakeException: Chain validation failed
    让 GPT-4 来修复 Golang “数据竞争”问题 - 每天5分钟玩转 GPT 编程系列(6)
    数据挖掘导论学习笔记1(第1 、2章)
    【PCB学习笔记】绘制智能车四层板 --- DRC检查,拼版设计及资料输出
    Apache 网站服务基础
    SpringBoot底层注解总结
    用户 ‘IIS APPPOOL\‘ 登录失败—3种解决方法
    【PCL库+ubuntu+C++】1. 点云界的hello world!
    qt listwidget获取当前选中项
  • 原文地址:https://blog.csdn.net/2301_79076804/article/details/132634134