• 《SLAM机器人基础教程》第三章 单片机与STM32:PWM电机转动实验


    3.11节 PWM电机转动实验

    本节介绍使用STM32的TIM定时器输出PWM控制电机转动。

    a.实验准备:码盘电机,USB转串口模块,ST-Llink下载器,CHEAPX机器人控制板

    b.实验目的:STM32实现PWM输出

    c.相关知识点:

    PWM由STM32的定时器产生,通过设置计数频率实现PWM频率设置,设置最大计数值ARR和CCR调节PWM占空比

    d.编程及运行

    (1)初始化

    void initMoter(void)
    {
        //LFT MOTOR PE13 PE14
        //RGT MOTOR PE9  PE11
        GPIO_InitTypeDef GPIO_InitStruct;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
        TIM_OCInitTypeDef  TIM_OCInitStruct;
        
        //Config Clock 配置时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_TIM1|RCC_APB2Periph_GPIOE, ENABLE);
        
        GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);    //映射管脚
    
        //配置GPIO
        GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_9|GPIO_Pin_11;    
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//推挽输出     
        GPIO_Init(GPIOE, &GPIO_InitStruct);         //传入结构体GPIO_InitStruct,配置GPIO
        
        GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_9|GPIO_Pin_11); //管脚电平置高,保证电机处于停止状态         
        
        //TIM1 PE13 CH3,PE14 CH4
        //TIM1 PE9  CH1,PE11 CH2
        TIM_TimeBaseStruct.TIM_ClockDivision = 0;      //时钟分割,不分割,即为该定制器时钟最大值72M
        TIM_TimeBaseStruct.TIM_Prescaler = Motor_PSC-1;//预分频值,
        TIM_TimeBaseStruct.TIM_Period    = Motor_ARR-1;//最大计数值 
        TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
        TIM_TimeBaseStruct.TIM_RepetitionCounter=0; //重复计数器
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);//传入结构TIM_TimeBaseStruct,配置TIM1
        
        TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2;//TIM脉冲宽度调制模式2:CNT值小于比较器TIM_Period设定值时输出有效低电平,否者高电平
        TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;    //开启 OC正相输出到对应引脚
        TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; //关闭 OC反相输出到对应引脚
        TIM_OCInitStruct.TIM_Pulse = 0; //重置计数器的值,保证电机处于停止状态        
        TIM_OCInitStruct.TIM_OCPolarity   = TIM_OCPolarity_High; //输出极性:高电平
      TIM_OCInitStruct.TIM_OCIdleState  = TIM_OCIdleState_Set; //空闲状态下的TIM输出比较的引脚电平
        TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Set;//空闲状态下的TIM互补输出比较的引脚电平
      TIM_OC1Init(TIM1, &TIM_OCInitStruct);//传入结构TIM_OCInitStruct,配置TIM1 OC1通道
        TIM_OC2Init(TIM1, &TIM_OCInitStruct);//传入结构TIM_OCInitStruct,配置TIM1 OC2通道
        TIM_OC3Init(TIM1, &TIM_OCInitStruct);//传入结构TIM_OCInitStruct,配置TIM1 OC3通道
        
        TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2;//TIM脉冲宽度调制模式2:CNT值小于比较器TIM_Period设定值时输出有效低电平,否者高电平
        TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//开启 OC正相输出到对应引脚
        TIM_OCInitStruct.TIM_Pulse = 0;                           //重置计数器的值,保证电机处于停止状态        
        TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;    //输出极性:高电平
      TIM_OC4Init(TIM1, &TIM_OCInitStruct);                     //传入结构TIM_OCInitStruct,配置TIM1 OC4通道
        
        TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);//开启OC1重装载,写入CCR1立即生效
        TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);//开启OC2重装载,写入CCR2立即生效
        TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);//开启OC3重装载,写入CCR3立即生效
        TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);//开启OC4重装载,写入CCR4立即生效
        
        
      TIM_CtrlPWMOutputs(TIM1, ENABLE);  //使能PWM输出
        TIM_ARRPreloadConfig(TIM1, ENABLE);//开启自动装载
        TIM_Cmd(TIM1, ENABLE);             //开启TIM1
    
    //  TIM1->CCR3=10000;TIM1->CCR4=10000;
    //    TIM1->CCR1=10000;TIM1->CCR2=10000;
        
    }

    (2)更新函数

    //参数:左电机速度,左电机方向,右电机速度,右电机方向
    //速度值范围[4000,30000],值过小电机可能会不转
    //方向:参照小车朝向,0往后转,1向前转
    void moterControl(u16 lv,u8 ldir, u16 rv,u8 rdir)
    {
    
        //限最大值,防止小车过快
        if(lv>30000)lv=30000;
        if(rv>30000)rv=30000;
        
        //驱动器通过两路PWM控制,分别连接IN1、IN2。IN1低电平,IN2高电平时正传;IN1高电平,IN2低电平时反传。高电平的占空比决定电机转速。
        if(ldir>0)
        {
          TIM1->CCR4=0;TIM1->CCR3=lv;//电机反转,参照小车朝向是向前转
        }
        else
      {
          TIM1->CCR3=0;TIM1->CCR4=lv;//电机正转,参照小车朝向是向后转
        }
    
    
        if(rdir>0)
        {
          TIM1->CCR1=0;TIM1->CCR2=rv;//电机正转,参照小车朝向是向前转
        }
        else
        {
          TIM1->CCR2=0;TIM1->CCR1=rv;//电机反转,参照小车朝向是向后转
        }
    
    }

    (3)主函数

    //PWM电机转动实验
    int main(void)
    {
        
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //PriorityGroupConfig NVIC中断分组设置 组2(2位抢占优先级,2位响应优先级)
        initDebugSerial(500000);//初始化调试串口USART1,波特率500000
        initSysTick();//初始化滴答定时器和TIM4定时器
        showVersion();//显示版本
        
        initMoter();  //初始化电机
        
        //参数:左电机速度,左电机方向,右电机速度,右电机方向
        //速度值范围[4000,30000],值过小电机可能会不转
        //方向:参照小车朝向,0往后转,1向前转
        moterControl(10000,1,10000,1); 
        delay_ms(300);
    //moterControl(0,1,0,1);//停止
        
    }

    (4)实验结果:电机转动0.3秒后停止

  • 相关阅读:
    【零售业集成系列】消费积分的会计处理到SAP系统实现
    SAP S4 ECC EPIC 'Month 00 not Plausible'. upload bank receipt error msg
    [OHIF-Viewers]医疗数字阅片-医学影像-Module: Panel-自定义面板-中-es6-Object.defineProperty()定义属性
    [OHIF-Viewers]医疗数字阅片-医学影像-Module: Panel-自定义面板-上
    [Chrome 83]谷歌浏览器升级后对表单控件和焦点元素黑框取消掉方法,磕碜啦啦的难看死了-chrome://flags/#form-controls-refresh
    [OHIF-Viewers]医疗数字阅片-医学影像-REACT向事件处理程序传递参数-.bind-传递函数给组件
    [OHIF-Viewers]医疗数字阅片-医学影像-es6解构赋值-const{}=-let{}=
    [OHIF-Viewers]医疗数字阅片-医学影像-Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。_.throttle(func, [wait=0], [options={}])实例解析防抖动(Debouncing)和节流阀(Throttling)
    [OHIF-Viewers]医疗数字阅片-医学影像-数字胶片直接下载,不再弹窗进行设置
    [OHIF-Viewers]医疗数字阅片-医学影像-ViewportDownloadForm.js
  • 原文地址:https://www.cnblogs.com/Baron-Lu/p/13378760.html
Copyright © 2020-2023  润新知