ReRain
认证:普通会员
所在专题目录 查看专题
【麦克纳姆轮小车制作】一、HC-05蓝牙配置
【麦克纳姆轮小车制作】二、左右轮PWM可调
【麦克纳姆轮小车制作】三、实现OLED显示(汉字+英文+图片)
【麦克纳姆轮小车制作】四、OLED取模(汉字加图片)
【麦克纳姆轮小车制作】五、实现蓝牙通信
【麦克纳姆轮小车制作】六、实现OLED菜单显示
作者动态 更多
【蓝桥杯单片机】十二、底层练习
2021-04-20 17:46
【蓝桥杯单片机】十一、第十届蓝桥杯省赛失败总结加试题分析
2021-04-11 20:50
【蓝桥杯单片机】十、第九届蓝桥杯国赛之“多功能测量仪表”
2021-04-01 16:36
【蓝桥杯单片机】九、第九届省赛之彩灯控制器
2021-03-30 18:19
【蓝桥杯单片机】八、第八届省赛之电子钟
2021-03-29 18:41

【麦克纳姆轮小车制作】二、左右轮PWM可调

​导读:《麦克纳姆轮小车制作》专栏文章是博主在自学stm32期间所做的学习笔记,秉持着“Learn by doing”的学习理念,博主在学习完stm32的相关基础知识后,便开始了上手实战。在小车的制作过程中,从主控板电路设计、PCB打板制作、车模组装到软件设计皆由博主亲手完成,期间也经历了很多困难,但最终也都一一解决,更重要的是,实践的过程加深了博主对于stm32的理解,也让博主体会到了学习的成就感,受益良多。为了帮助和我一样的初学者,现将当时的学习笔记做了梳理,希望能有所帮助。学海无涯,让我们一起进步吧!!!

一、左右轮PWM波的产生

      我是利用定时器的PWM模式产生的PWM波,具体可参考我的博客: STM32之通用定时器输出PWM波,这里我只贴出代码:

#include "stm32f10x.h"

//freq,PWML,PWMR均在主函数中定义
extern u32 freq;//频率
extern u8 PWML;//左电机PWM
extern u8 PWMR;//右电机PWM

void PWM2_Init(void)//利用TIM2的通道1(左电机)和通道2(右电机)产生PWM波
{
	u32 arr;
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	arr = 1000000 / freq;//计算频率对应的周期值(计数值)
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//强推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//72分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
	TIM_TimeBaseStructure.TIM_Period = arr - 1;//周期值
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;//不分频
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//TIM2定时器
    
	//对通道1和通道2配置为PWM输出模式
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//输出模式配置为PWM2模式
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//低极性
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能输出状态
	TIM_OCInitStructure.TIM_Pulse = (arr-1) * PWML / 100;//占空比
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);//TIM2_CH1
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//输出模式配置为PWM2模式
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//低极性
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能输出状态
	TIM_OCInitStructure.TIM_Pulse = (arr-1) * PWMR / 100;//占空比
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);//TIM2_CH2
	
	TIM_Cmd(TIM2, ENABLE);//使能TIM2
}

二、利用按键调节PWM(可加可减)

1、首先要写一个按键的底层,另外按键扫描函数keyscan()是要放在定时器中断里,每2ms扫描一次的,所以还要写一个定时器定时2ms的函数,然后再写一个定时器中断,这一点和51是一样的,具体可参考:STM32之按键+蜂鸣器STM32之定时器配置,不要忘记在key.h文件中定义你的按键引脚:

#define KEY1 GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);//加
#define KEY2 GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9);//减
#define KEY3 GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15);//转换(判断改变值是PWML还是PWMR)

2、在主函数main.c中写加减PWM的函数:

void AddPWM(u8 *PWM)
{
    if(*PWM < 90)
    {
        *PWM += 5;
    }
    else
    {
        *PWM = 0;
    }
}

void SubPWM(u8 *PWM)
{
    if(*PWM > 0)
    {
        *PWM -= 5;
    }
    else
    {
        *PWM = 90;
    }
}

这里我用了指针,可以简化代码。

3、按键动作函数KeyAction()

void KeyAction(u8 keycode)
{
    if(keycode == 1)//按下按键KEY1
    {
        if(flagPWM == 0)
        { 
            AddPWM(&PWML);
        }
        else
        {
            AddPWM(&PWMR);
        }
        PWM2_Init();//每次按下按键才进行PWM的初始化!!!
    }
    else if(keycode == 2)//按下按键KEY2
    {
        if(flagPWM == 0)
        {
            SubPWM(&PWML);
        }
        else
        { 
            SubPWM(&PWMR);
        }
        PWM2_Init();//每次按下按键才进行PWM的初始化!!!
    }
    else if(keycode == 3)//按下按键KEY3
    {
        flagPWM ^= 1;
    }
}

说明:

关于PWM2_Init();函数: 不能在while(1)中初始化!!!,只能是在每次按下按键时才初始化(就是将改变后的PWM写入初始化函数),否则不能输出准确的PWM波(实际上我用逻辑分析仪观察的结果是根本观测不到PWM波),这一点一定要注意!!!!

4、最后可以在主函数 while(1)里写一个小车前进函数,进行调试,注意在while(1)外写上PWM的初始化函数PWM2_Init();(当然,也可以加一个显示屏,直接把参数显示到显示屏上面,会更加直观,我加的是oled,另外的文章里我会详细写这个东东)

#define LED_ON  PAout(12)=0 //开灯
#define LED_OFF PAout(12)=1 //关灯

int main(void)
{
	GPIO_IN1_IN8();//电机驱动引脚初始化
    GPIO_Led_Init();//led初始化,这是我加的指示灯
    
	KeyInit();
    PWM2_Init();
    TIM3_Int_Init(2000,72);//定时2ms
    LED_OFF;
	
    while (1)
    { 
    	 KeyDriver();
	     motor(M_FOR, M_FOR, M_FOR, M_FOR);//一个前进函数
    }
}

说明:

  • emmm,关于下面的写法不理解的可以看看:STM32变量定义及位带操作,关于位带操作的,一种更方便的直接操作GPIO口的方法,这个跟51比较像。
#define LED_ON  PAout(12)=0 //开灯

一点感受: 最后谈谈我的一点感受吧,当然我是以一个初学者的角度来说的,大一的时候我做过一个51的简易红外寻迹小车,当时代码写的真的很水很水,PWM波输出甚至使用delay延时函数写的,但是最后也算是跑起来了,当时真的是属于没有一点学习方法,调车的时候也是瞎调的,现在想想大一的时候做的好像都是一些无用功。这次调车的时候,我学会了借助一些电子仪器,比如说逻辑分析仪,来直观地看到输出的PWM波,然后再根据出来的波形修改程序,直到找的问题出在哪儿,我会去借助不同的开发板来排除硬件问题,然后我会自己去想需求,根据想出的需求去网上找那一部分的资料,然后自己写出来,当然刚开始比较慢,但是功能实现的时候会很有成就感,等等等等,总之总算有了一些方法,好像也慢慢有了兴趣,很开心,说这么多是想说,大家在学习的时候要注意找方法(最好有一位厉害的前辈带着!!!!入门会贼快!!!),我觉得像我一样的初学者应该还有很多,emmm,可能都要经历一个从无到有,慢慢拥有兴趣的过程叭(毕竟。。。还是感觉电子方面女生的兴趣应该不如男生多,哈哈)

希望大家可以多多点赞、评论、收藏以及加关注哦!!!谢谢大家!!!!

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 204
收藏 204
关注 302
成为作者 赚取收益
全部留言
0/200
  • dy-SgCRSAWd 2021-04-29 21:25
    什么时候更新
    回复
  • dy-lZg1ikQS 2021-04-29 21:05
    讲的真好!
    回复
  • dy-6jaMNnKj 2021-04-29 11:07
    围观学习
    回复
  • dy-uP6R9bIG 2021-04-28 22:22
    对我很有帮助
    回复
  • dy-faUxdNVf 2021-04-28 22:17
    比论文强一万倍
    回复
  • dy-ARsdJtu2 2021-04-28 16:43
    比论文强一万倍
    回复
  • dy-PfBg9fHc 2021-04-28 15:18
    佩服楼主
    回复
  • dy-BntE74dS 2021-04-27 11:39
    比论文强一万倍
    回复
  • dy-AstN3YsZ 2021-04-27 11:26
    请教一下
    回复
  • dy-kWQSvfcY 2021-04-26 11:29
    比论文强一万倍
    回复
  • dy-IRhxrrTG 2021-04-26 11:07
    感谢分享
    回复
  • dy-EWZRbIzj 2021-04-22 11:29
    期待继续
    回复
  • dy-HlVFyepq 2021-04-21 20:58
    大开眼界,真是好文
    回复
  • dy-fEyVNAbF 2021-04-21 15:55
    感谢博主!
    回复
  • dy-cfgdwamL 2021-04-21 13:00
    不亚于看了一篇高质量论文
    回复
  • dy-ayNTwT3L 2021-04-21 12:31
    对我很有帮助
    回复
  • dy-LiDZV1Qr 2021-04-20 18:12
    期待继续
    回复
  • dy-rfrUF2fp 2021-04-20 17:04
    不亚于看了一篇高质量论文
    回复
  • dy-bHww98js 2021-04-19 23:04
    讲的真好!
    回复
  • dy-FPtpScGU 2021-04-19 09:08
    请教一下
    回复