超声波模块与舵机模块

目录

超声波模块HC-SR04:

工作原理:

超声波时序图:

舵机模块:

PWM:

PWM比较换算,控制角度:

舵机控制代码部分:


超声波模块HC-SR04:

 

工作原理

1. 给超声波模块接入电源和地
2. 给脉冲触发引脚(
trig)输入一个长为20us的高电平方波
3. 输入方波后,模块会自动发射840KHZ的声波,与此同时回波引脚echo端的电平会由0变为1;(此时应该
启动定时器计时)
4. 当超声波返回被模块接收到时,回波引脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下
的这个时间即为超声波由发射到返回的总时长。
5. 根据声音在空气中的速度为344/秒,即可计算出所测的距离。

超声波时序图:

 

以上时序图表明你只需要提供一个20us以上脉冲触发信号,该模块内部将发出840KHZ周期电平并检测回
波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号
到收到的回响信号时间间隔可以计算得到距离。
建议测量周期为60ms以上,以防止发射信号对回响信号的影响。
公式:us/58=厘米us/148=英寸;距离=高电平时间*声速(340M/S)/2
(除以58是为了得到实际的距离)
代码部分:
void HC_SR04_init(void)
{
    GPIO_InitTypeDef HC_SR04_GPIO_Init_Structure;
    TIM_TimeBaseInitTypeDef Timer4_Init_Structure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    
    //配置Trig(PB11)初始化结构体
    HC_SR04_GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_Out_PP;
    HC_SR04_GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_50MHz;
    HC_SR04_GPIO_Init_Structure.GPIO_Pin   = GPIO_Pin_11;
    
    GPIO_Init(GPIOB, &HC_SR04_GPIO_Init_Structure);
    
    //配置Echo(PB10)初始化结构体
    HC_SR04_GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
    HC_SR04_GPIO_Init_Structure.GPIO_Pin   = GPIO_Pin_10;
    
    GPIO_Init(GPIOB, &HC_SR04_GPIO_Init_Structure);
    
    Timer4_Init_Structure.TIM_ClockDivision = TIM_CKD_DIV1;           //设置分频系数,通常默认不分频
    Timer4_Init_Structure.TIM_CounterMode   = TIM_CounterMode_Up;     //设置计数模式为向上计数
    Timer4_Init_Structure.TIM_Period        = 1000-1;                  //设置重装载值为1000(计数周期为1毫秒)
    Timer4_Init_Structure.TIM_Prescaler     = 72-1;                   //设置初始化与分频值为72
    
    TIM_TimeBaseInit(TIM4, &Timer4_Init_Structure);
    
    TIM_Cmd(TIM4, DISABLE);                                        //失能定时器4
}
/**
 * 功能:打开定时器4函数
 * 参数:None
 * 返回值:None
 */
void open_timer4(void)
{
    TIM_SetCounter(TIM4, 0);
    HS_count_us=0;
    TIM_Cmd(TIM4, ENABLE);
}
/**
 * 功能:关闭定时器4函数
 * 参数:None
 * 返回值:None
 */
void close_timer4(void)
{
    TIM_Cmd(TIM4, DISABLE);
}
/**
 * 功能:获取Echo引脚电平
 * 参数:None
 * 返回值:Echo_Value:高电平 or 低电平
 */
int Get_HS_Echo_Value(void)
{
    uint16_t Echo_Value;
    Echo_Value = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10);
    return Echo_Value;
}
/**
 * 功能:获取高电平持续时间
 * 参数:None
 * 返回值:HS_Timer高电平持续时间
 */
int Get_HS_Time_Value(void)
{
    uint32_t HS_Timer = 0;
    HS_Timer = HS_count_us*1000;
    HS_Timer += TIM_GetCounter(TIM4);
    TIM4 -> CNT = 0;                 //清除计数器寄存器的值
    delay_ms(50);
    return HS_Timer; 
}
/**
 * 功能:获取距离
 * 参数:None
 * 返回值:length :距离
 */
float Get_HS_Length_Value(void)
{
    uint32_t time = 0;
    uint16_t i;
    float length = 0;
    float sum =0 ;
    for(i=0;i<5;i++)
    {
        HC_SR04_Trig_H();

        delay_us(20);
        HC_SR04_Trig_L();
        while(Get_HS_Echo_Value() == 0);
        open_timer4();
        while(Get_HS_Echo_Value() == 1);
        close_timer4();
        time=Get_HS_Time_Value();
        length = ((float)time/58.0);
        sum = sum + length;
    }
    length=sum/5.0;
    return length;
}

舵机模块:

PWM:

 PWM波,这是什么东西呢?其实就是一种方波,其频率为50Hz,周期就是20ms,
 在每个周期里面,舵机高电平的占空比在0.5ms到2.5ms之间。
 而0.5ms代表的是0度,2.5ms代表的是180度。其他的度数可以直接按照比例换算过去
      0.5ms-----------    0度
      1.0ms-----------    45度
      1.5ms-----------    90度
      2.0ms-----------    135度
      2.5ms-----------    180度

PWM比较换算,控制角度:

一个周期为20ms,pwm配置为模式1,低电平有效,
200 -----  20ms
195 -----  0.5ms,  小于195,低电平,高于195,高电平    (5/200)*20=0.5
190 -----  1ms
185 ------ 1.5ms
180 ------ 2ms
175 ------ 2.5ms

问题:像195,190,......175怎么来的呢?

由于PWM周期为20ms,所以(以舵机会转动 45°为例),占空比就应该为1ms/20ms = 5%,
所以TIM_SetCompare1的 TIMx 捕获比较 1 寄存器值就为200-200*5% = 190,其他的做类比可得出结果。

对于TIM_SetCompare2(TIM3, 175);这个函数:

//TIM_SetCompare2(TIMx,你想要的比较值);

舵机控制代码部分:

void servo_init(void)
{
    GPIO_InitTypeDef GPIO_Init_Structure;                  //定义GPIO初始化结构体
    TIM_TimeBaseInitTypeDef Timer_Init_Structure;          //定义定时器初始化结构体
    TIM_OCInitTypeDef Timer_OC_Init_Structure;             //定义定时器输出PWM结构体
    
    RCC_APB2PeriphClockCmd(SERVO_GPIO_CLK, ENABLE);        //使能Timer3 GPIOB时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   //使能定时器3时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //使能复用时钟
    
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);   //选择部分重映射
    
    //配置GPIO初始化结构体
    GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init_Structure.GPIO_Pin   = SERVO_GPIO_PIN;       //GPIO_Pin_5
    GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_Init(SERVO_GPIO_PORT, &GPIO_Init_Structure);
    
    //配置通用定时器初始化结构体,实现定时20ms
    Timer_Init_Structure.TIM_ClockDivision = TIM_CKD_DIV1;        //设置分频系数,通常采用默认的分频
    Timer_Init_Structure.TIM_CounterMode = TIM_CounterMode_Up;    //设置捕获模式为向上计数(基本定时器仅有向上计数)
    Timer_Init_Structure.TIM_Period = 200-1;                      //设置重装载值(在预分频值为72000下,10000为一秒)
    Timer_Init_Structure.TIM_Prescaler = 7200-1;                  //设置初始化预分频值为7200
//    Timer_Init_Structure.TIM_RepetitionCounter = 0              //重复计数器,仅高级定时器需要设置
    
    TIM_TimeBaseInit(TIM3, &Timer_Init_Structure);
    
    //配置定时器输出PWM结构体
		//在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;比较值不可大于等于重装载值
    Timer_OC_Init_Structure.TIM_OCMode = TIM_OCMode_PWM1;					//定时器模式选择Timer脉冲宽度调制模式 1
    Timer_OC_Init_Structure.TIM_OutputState = TIM_OutputState_Enable;     //比较输出使能
    Timer_OC_Init_Structure.TIM_OCPolarity = TIM_OCPolarity_Low;          //选择有效输出为低电平
    
    TIM_OC2Init(TIM3, &Timer_OC_Init_Structure);
    
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);                     //使能预装载寄存器
    
    TIM_Cmd(TIM3, ENABLE);
}

void Servo_Run(uint16_t angle)
{
    switch(angle)
    {
		case 180 :TIM_SetCompare2(TIM3, 175); break;//对应180度
		case 135 :TIM_SetCompare2(TIM3, 180); break;//对应135度
		case 90  :TIM_SetCompare2(TIM3, 185); break;//对应90度
		case 45  :TIM_SetCompare2(TIM3, 190); break;//对应45度
		case 0   :TIM_SetCompare2(TIM3, 195); break;//对应0度
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值