CUBEMX中使用DMA + TIM,生成可调个数以及频率的脉冲,并应用于收发一体式超声波

直接进入正题:

CUBEMX配置(本次使用的的是V5.4.0,附上链接 https://www.st.com/stm32cubemx),时基使用的是sysTick。

高速时钟使用的是外部8M晶振,配置如下:

 

脉冲产生的用的是定时器1的通道2,配置如下:

 

 

 

DMA的配置如下,因为DMA是默认开中断的,所以DMA的中断不用管。

 

 

本次超声波的接收用的是GPIO外部中断,ECHO下面的6个GPIO用于驱动1.44的TFT_LCD,配置如下:

 

配置完毕,开始生成代码,我用的是VSCODE,所以用带makefile的的代码,配置如下:

 

 

下面展示代码,DMA发送完成后会进入DMA中断,TIM开始向上计数,在计数完成后会进入中断,两个中断函数的处理如下:

如果不太清楚脉冲个数的问题,请参考:https://blog.csdn.net/lkmmmqfn2222/article/details/103280839

void DMA2_Stream2_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
  TIM_CCxChannelCmd(&htim1,TIM_CHANNEL_2,TIM_CCx_DISABLE);
  /* USER CODE END DMA2_Stream2_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_tim1_ch2);
  /* USER CODE BEGIN DMA2_Stream2_IRQn 1 */

  /* USER CODE END DMA2_Stream2_IRQn 1 */
}


void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef* htim){
  if(htim == &htim1){
    TIM_CCxChannelCmd(&htim1,TIM_CHANNEL_2,TIM_CCx_DISABLE);
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_8);//used for debug
    myUltrasonic.trigFlag = 1;
    myUltrasonic.timCnt0 = __HAL_TIM_GET_COUNTER(&htim1);
    HAL_NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
  }
}


 

下面贴出超声波部分的代码:

#ifndef _TEST_H
#define _TEST_H
#include "main.h"
#include "tim.h"

#define ACC_STEP_NUM 16

typedef struct {
    uint8_t num;            //number of ultrasonic sensors
    uint8_t sensorType;     //0:一体式 1:分立式
    uint8_t trigFlag;       //sensor drivered flag 0:no trig 1:trig
    uint8_t trigEndFlag;
    uint32_t timCnt0;       //
    uint32_t timCnt1;       //
    float   distance;       //
    float   distanceTemp;   //
    float preDistance;      //
}ULTRASONIC,*pULTRASONIC;

void ledTest(void);
void pwmTest(void);
void itoa(uint32_t n,uint8_t s[]);
void reverseCString(uint8_t* ch);
#endif



#include "test.h"
#include "leddrv.h"
#include "string.h"

uint16_t accStep[ACC_STEP_NUM] ;
ULTRASONIC myUltrasonic;

uint8_t testD[] = {"152"};

void ledTest(void){
    uint8_t testA[] = {"*Cairne Studio*"};
    uint8_t testB[] = {"UltrasonicModule"};
    uint8_t testC[] = {"Distance is:"};
    Lcd_Clear(GRAY0);
    Gui_DrawFont_GBK16(0, 16, GRAY2, WHITE,(uint8_t*) &testA);
    Gui_DrawFont_GBK16(0,40,GRAY1,GRAY0,(uint8_t*)&testB);
    Gui_DrawFont_GBK16(0,64,GRAY2,GRAY0,(uint8_t*)&testC);
    LCD_BLK_SET;
}

void pwmTest(void){
    myUltrasonic.trigEndFlag = 0;
    myUltrasonic.trigFlag = 0;  
    for(int i = 1; i < ACC_STEP_NUM ; i++){
        accStep[i] = accStep[i-1] + 11;
    }
    HAL_TIM_OC_Start_DMA(&htim1,TIM_CHANNEL_2,(uint32_t*)accStep,ACC_STEP_NUM);
}


// void ultralsonicTest(pULTRASONIC mySensor){

// }

void ultrasonicInit(pULTRASONIC mySensor){
    mySensor->distance = 0;
    mySensor->num = 1;
}


void reverseCString(uint8_t* ch){
    uint8_t size = strlen(ch);
    uint8_t head = 0;
    uint8_t tail = size - 1;
    while(head < tail){
        uint8_t temp = ch[head];
        ch[head++] = ch[tail];
        ch[tail--] = temp;
    }
}
void itoa(uint32_t n,uint8_t s[]){
    int i,  sign;
    // uint8_t s[] = {};
    if((sign = n) < 0){
        n = -n;
    }
    i = 0;
    do{
        s[i++] = n%10 + '0';
    }while((n /= 10) > 0);
    if(sign < 0){
        s[i++] = '-';
    }
    s[i] = '\0';
    // reverseCString(&s);
    // sout = s;
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
  if(GPIO_Pin == GPIO_PIN_11){
    uint32_t temCnt = __HAL_TIM_GetCounter(&htim1);
    if(temCnt < myUltrasonic.timCnt0){
      if(1500 <= (65535 - myUltrasonic.timCnt0 + temCnt)){
        myUltrasonic.timCnt1 = __HAL_TIM_GetCounter(&htim1);
        myUltrasonic.distance = (65535 - (myUltrasonic.timCnt0 - myUltrasonic.timCnt1))*0.17;
        if(myUltrasonic.distanceTemp >= 2600){
          myUltrasonic.distanceTemp = 2600;
        }
        else if(myUltrasonic.distanceTemp <= 100){
          myUltrasonic.distanceTemp = 100;
        }
        myUltrasonic.distance = myUltrasonic.distanceTemp;
        myUltrasonic.preDistance = myUltrasonic.distance;
        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_14);
        HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
      }
    }
    else{
      if(((temCnt - myUltrasonic.timCnt0) <= 20000)&& ((temCnt - myUltrasonic.timCnt0) >= 1500)){
        myUltrasonic.timCnt1 = __HAL_TIM_GetCounter(&htim1);
        myUltrasonic.distanceTemp = (myUltrasonic.timCnt1 - myUltrasonic.timCnt0)*0.17;
        if(myUltrasonic.distanceTemp >= 2600){
          myUltrasonic.distanceTemp = 2600;
        }
        else if(myUltrasonic.distanceTemp <= 100){
          myUltrasonic.distanceTemp = 100;
        }
        myUltrasonic.distance = myUltrasonic.distanceTemp;
        myUltrasonic.preDistance = myUltrasonic.distance;
        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_14);
        HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
      }
      else{
        myUltrasonic.distance =  myUltrasonic.preDistance;
      }
    }
  }
}

 

最终实现原理解释如下:

下图所示的A部分为驱动发射波形,因为是收发一体,所以会有一些死区,B部分为回波接到的波形(本模块在测试平面可以到3m+,人体腿部可以到接近2m,因为这个小模块的原理PCB以及代码都是本人设计,需要交流的请联系我chastefriendship@126.com),C为脉冲发送完成中断标志位,D为接收到第一个回波的中断标志位。

完整代码链接(带显示),链接://download.csdn.net/download/lkmmmqfn2222/12014550

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值