嵌入式实训——day4

今天同样做三个实验  1、L298电机驱动实验   2、红外光电实验   3、超声波模块

一、L298电机驱动

L298N是ST公司的产品,内部包含4通道逻辑驱动电路,是一种电机的专用驱动器,即内含两个H桥的高电压大电流双全桥式驱动器,接收标准TTL逻辑电平信号,可驱动46V、2A以下的电

  实验原理:

OUT1、 OUT2 和 OUT3、 OUT4 之间分别接 2 个电动机。

IN1、 IN2、 IN3、 IN4 引脚从单片机接输入控制电平,控制电机的正反转。

ENA, ENB (控制速度)接控制使能端,控制电机的停转。

左侧电机方向

 

右侧电机方向

 

 

 

 

 

 

 

 

 

pa2

pb9

pa1

pc9

小车状态

(左侧占空比)Pa0

Pa3(右侧占空比)

0

1

0

1

前行

相等

相等

1

0

1

0

后退

相等

相等

1

0

0

1

左转

 

 

0

1

1

0

右转

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pa2

pb9

pa1

pc9

 

0

1

0

1

左右两侧前行

1

0

1

0

左右两侧后退

 

 

 

 

微左转?

 

 

 

 

微右转?

 

 

 

 

左转?

 

 

 

 

右转?

  对于电机的调速,我们采用 PWM 调速的方法。其原理就是开关管在一个周期内的导通时间是 t,周期为 T,则电机两端的平均电压 U=Vcc*(t/T)=a*Vcc。其中, a=t/T(占空比), Vcc 是电源电压。电机的转速与电机两端的电压成比例,而电机两端的电压与控制波形的占空比成正比例,占空比越大,电机转的越快。

参考代码:

将控制器的 PA2、 PB9、 PA1、 PC9 口分别连接到 298 的 IN1~IN4 上,

将拥有 PWM 的 PA0、 PA3连接到 298 的 ENA、 ENB,

通过改变 PA2、 PB9、 PA1、 PC9 口上的高低电平变化以控制小车的前进方向,
通过改变 PA0、 PA3 口上的高低电平的占空比以控制电机的转速

将 PA2、 PB9、 PA1、 PC9 口配置为 Output, PA0、 PA3 配置为 PWM 输出。
 

Counter Settings:
• 预分频器, NUCLEOF072RB 的工作频率默认为 8MHz,经 800 分频之后的工作频率为 10Khz。
• 计数模式,向下还是向下计数
• 计数周期:0~999,这样一个计数周期下来,时间刚好是 100 毫秒。

通过修改各通道的 Pulse 值修改各通道输出 PWM 占空比

参考代码(占空比修改)

使用 HAL 库中的__HAL_TIM_SetCompare 修改脉冲宽度来修改占空比,函数原型描述如下

 

 


 

 

//正常轮占空比

#define full_speed 200

//停止轮

#define null_speed 0

/*矫正时 ,低速轮占空比*/

#define correct_speed 100

 

#define MOTOR_A_CON1_GPIO GPIOA

#define MOTOR_A_CON1_PIN GPIO_PIN_2

          

#define MOTOR_A_CON2_GPIO GPIOB

#define MOTOR_A_CON2_PIN GPIO_PIN_9

          

#define MOTOR_A_EN_GPIO GPIOA

#define MOTOR_A_EN_PIN GPIO_PIN_0

 

          

#define MOTOR_B_CON1_GPIO GPIOA

#define MOTOR_B_CON1_PIN GPIO_PIN_1

          

#define MOTOR_B_CON2_GPIO GPIOC

#define MOTOR_B_CON2_PIN GPIO_PIN_9

          

#define MOTOR_B_EN_GPIO GPIOA

#define MOTOR_B_EN_PIN GPIO_PIN_3

 

         HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

         HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);

 

void Change_Pulse(uint16_t left,uint16_t right)

{

__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, left);

  __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4, right);

}

//-----------------------------------------------

void Correct_Left(void)

 {

         Change_Pulse(correct_speed,full_speed);

    HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);

         HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);

 }

//------------------------------------------------

 void Correct_Right(void)

 {

         Change_Pulse(full_speed,correct_speed);

  HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);

         HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);

 }

//-----------------------------------------------------

void Straight(void)  

{

         Change_Pulse(full_speed,full_speed);

         HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);

         HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);

}

//-----------------------------------------------------

void Stop(void)        

{

         Change_Pulse(null_speed,null_speed);

         HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);

         HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_RESET);

}

二、红外光电实验

实验原理:

由原理图可看出,我们接线方法为中间接输出,两边分别对应电源和地。

发射到黑色,被吸收, 所以检测不到, 表现为红外管变暗,   这时输出高电平,  

传感器灯

传感器io输出

亮,有障碍物

我们通过查询方式来判断相应光电开关的状态改变,在循迹中,适当延时处理,就可以调整行驶方向。

软件配置:

   引脚:从左至右 PC7   PC6   PB12   PB15  PB14

   模块:从左至右 P18   P27   P26   P9    P8

参考代码:

#define Left1_GPIO GPIOC     //×ó²à̽ͷ

#define Left1_PIN GPIO_PIN_7

 

#define Left2_GPIO GPIOC     //×ó²à̽ͷ

#define Left2_PIN GPIO_PIN_6     

 

#define Middle_GPIO  GPIOB       //¾àÀë̽²â

#define Middle_PIN  GPIO_PIN_12

 

#define Right1_GPIO GPIOB   //ÓÒ²à̽ͷ

#define Right1_PIN GPIO_PIN_15

 

#define Right2_GPIO GPIOB     //ÓÒ²à̽ͷ

#define Right2_PIN GPIO_PIN_14

 

#define Left1 HAL_GPIO_ReadPin(Left1_GPIO,Left1_PIN)

#define Left2 HAL_GPIO_ReadPin(Left2_GPIO,Left2_PIN)   

#define Middle HAL_GPIO_ReadPin(Middle_GPIO,Middle_PIN)

#define Right1 HAL_GPIO_ReadPin(Right1_GPIO,Right1_PIN)

#define Right2 HAL_GPIO_ReadPin(Right2_GPIO,Right2_PIN)     

 

 

禁止超声波1秒的定时器

//              HAL_UART_Receive_IT(&huart1,RxData, 6);

 

                          if(Left1 == GPIO_PIN_RESET)

                          {

                                  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);//Red
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);

                          }

                          else if(Left2 == GPIO_PIN_RESET)

                          {

                                  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);//Green
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);

       }

                          else if(Middle == GPIO_PIN_RESET)

                          {

                                  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//Blue
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);

       }

                          else if(Right1 == GPIO_PIN_RESET)

                          {

                                  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);//Yellow
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);

       }

                          else if(Right2 == GPIO_PIN_RESET)

                          {     

          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//White
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
                     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);

       }

三、超声波模块

  实验原理:该模块共有4个引脚Vcc,Trig,Echo,GND

  在模块上电以后,给Trig管脚一个持续20us以上的高电平,该模块可以开始工作。这时,该模块会自动从这一个“大喇叭”发送8个40KHZ的方波,并将Echo管脚拉高,然后自动检测是否有信号返回。如果返回,Echo管脚便拉低,那么Echo高电平持续的时间就是超声波从发送到接收的时间。我们要做的就是开启超声波模块,然后再通过Echo知道超声波从发送到接收的时间就可以。

软件配置:

在例程中我们通过查询方式来判断相应光电开关的状态改变,在循迹中,适当延时处理,就

参考代码:可考以调

定时器中断服务函数,主要是控制采样频率和保证Trig发出一个20us的高电平

HAL_TIM_Base_Start_IT(&htim6);

 

 

int ultrasonic = 0;    //超声波是否工作,0代表没有工作

int ultrasonic_time;

unsigned char b[4]={0};

#define Echo_GPIO GPIOC

#define Echo_PIN GPIO_PIN_2

 

#define Trig_GPIO GPIOC

#define Trig_PIN GPIO_PIN_3

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

    if(htim==&htim6)

    {

        HAL_TIM_Base_Stop_IT(&htim6);

        ultrasonic=0;   //超声波模块还未工作

        HAL_GPIO_WritePin(Trig_GPIO, Trig_PIN, GPIO_PIN_SET);

               HAL_TIM_Base_Start_IT(&htim7);

    }

    else if(htim==&htim7)

{

    HAL_GPIO_WritePin(Trig_GPIO,Trig_PIN, GPIO_PIN_RESET);

        ultrasonic=1;   //此时trig有了一个20us的电平,超声波模块开始工作

        HAL_TIM_Base_Stop_IT(&htim7);

        HAL_TIM_Base_Start_IT(&htim6);

 

    }

}

 

 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);     

    if(GPIO_Pin==GPIO_PIN_2)

    {

    

        if(HAL_GPIO_ReadPin(Echo_GPIO, Echo_PIN))

        {

            ultrasonic_time=__HAL_TIM_GET_COUNTER(&htim6);

        }

        else if(ultrasonic==1)

        {

                   ultrasonic=0;

           ultrasonic_time=__HAL_TIM_GET_COUNTER(&htim6)-ultrasonic_time;

            ultrasonic_time=ultrasonic_time*170/100;           //转换成距离cm

 

ultrasonic_time=ultrasonic_time%1000;            b[0]=ultrasonic_time/100+'0';

            ultrasonic_time=ultrasonic_time%100;

            b[1]=ultrasonic_time/10+'0';

            b[2]=ultrasonic_time%10+'0';

            ultrasonic_time=0; 

          HAL_UART_Transmit(&huart1,b,3,10);

        }      

    }

}

参考代码

 

整行驶方向。参考代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值