当前位置:   article > 正文

【平衡小车】学习日志(二)_pbout(3)=1;详细说明

pbout(3)=1;详细说明

转接板原理图


PWM

  • PWM1——PA8
  • PWM2——PA11
1、完成驱动文件导入操作和编写驱动程序基本代码(参考之前文章)
//将【PWM】配置文件放在【Hardware】文件夹里
2、在 PWM.c编写PWM初始化函数 PWM_Init_TIM1
/***************************************
PWMA——PA11——TIM1_CH4
PWMB——PA8——TIM1_CH1
***************************************/
/***************************************
初始化定时器TIM1的两路输出PWM(通道1和通道4)
TIM1是【高级定时器】
参数1:指定用于划分TIM时钟的预分频器值    范围[0,65535]
参数2:指定要在下一次更新事件时加载到ARR自动重新加载寄存器中的周期值  范围[0,65535]
***************************************/
void PWM_Init_TIM1(uint16_t PSC,uint16_t ARR)
{
//第一步:开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    
//第二步:选择时基单元的时钟(在stm32f10x_tim.h文件中查找函数)
    TIM_InternalClockConfig(TIM1);//选择内部时钟驱动时基单元
    
//第三步:配置时基单元(在stm32f10x_tim.h文件中查找函数)
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//指定计数器模式(此处选择向上计数)
    TIM_TimeBaseInitStructure.TIM_Period = ARR;//指定要在下一次更新事件时加载到ARR自动重新加载寄存器中的周期值  ARR取值[0,65535]
    TIM_TimeBaseInitStructure.TIM_Prescaler = PSC;//指定用于划分TIM时钟的预分频器值    PSC取值[0,65535]
    TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);//初始化时基单元
//第四步:同时初始化两个输出比较单元(通道1和通道4)
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);//给结构体赋默认初始值,以防意外
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//设置输出比较的模式
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
    TIM_OCInitStructure.TIM_Pulse = 0;//设置CCR的值
    TIM_OC1Init(TIM1,&TIM_OCInitStructure);
    TIM_OC4Init(TIM1,&TIM_OCInitStructure);
    
//配置为TIM1的OC1和OC4通道输出PWM波形
//波形需要借用GPIO口进行输出————TIM1的OC1的通道借用了PA8,OC4的通道借用了PA11
//第五步:初始化GPIO口
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
//第六步:开启TIM1主输出函数
    //TIM1是高级定时器,有专用的启动函数
    TIM_CtrlPWMOutputs(TIM1,ENABLE);
    
    //OC1和OC4的预装载寄存器使能
    TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);
    //TIM1在ARR上预装载寄存器使能    
    TIM_ARRPreloadConfig(TIM1,ENABLE);
    
    
//第七步:启动定时器(在stm32f10x_tim.h文件中查找函数)
    TIM_Cmd(TIM1,ENABLE);
    
    
//至此PWM波形就能通过PA8和PA11输出了
//通过PWM的频率、占空比、分辨率计算公式可以得到ARR、PSC、CCR值
//EX:当PSC=720-1    ARR=100-1    CCR=50时
//————得到输出频率为1KHz,占空比为50%,分辨率为1%的PWM波形
}
3、在 PWM.h中声明PWM初始化函数 PWM_Init_TIM1
void PWM_Init_TIM1(uint16_t PSC,uint16_t ARR);
4、在sys.h中 #incl ude " PWM .h"
#include "PWM.h"

Motor

  • 电机1——PB12/PB13
  • 电机2——PB14/PB15
1、完成驱动文件导入操作和编写驱动程序基本代码(参考之前文章)
//将【Motor】配置文件放在【Hardware】文件夹里
2、在 Motor.c编写直流电机初始化函数 Motor_Init
/***************************************
电机1——PB12/PB13
电机2——PB14/PB15
***************************************/
/***************************************
初始化两个直流电机Motor的输出
***************************************/
void Motor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    AIN1=0,AIN2=0;
    BIN1=0,BIN1=0;
}
3、在 Motor.c编写限幅函数 Limit
void Limit(int *MotorA,int *MotorB)
{
    if(*MotorA > PWM_MAX)
    {
        *MotorA = PWM_MAX;
    }
    if(*MotorA < PWM_MIN)
    {
        *MotorA = PWM_MIN;
    }
    if(*MotorB > PWM_MAX)
    {
        *MotorB = PWM_MAX;
    }
    if(*MotorB < PWM_MIN)
    {
        *MotorB = PWM_MIN;
    }
}
4、在 Motor.c编写直流电机装载PWM函数 Motor_Load
/***************************************
直流电机装载PWM函数
参数1:左电机Motor1的PWMA(PA11——TIM1_CH4)
参数2:右电机Motor2的PWMB(PA8——TIM1_CH1)
左电机Motor1——PB12/PB13
右电机Motor2——PB14/PB15
***************************************/
void Motor_Load(int Motor1,int Motor2)
{
    //左电机正转
    if(Motor1 >= 0)
    {
        AIN1=0;
        AIN2=1;
        TIM_SetCompare4(TIM1,ABS(Motor1));
    }
    //左电机反转
    else
    {
        AIN1=1;
        AIN2=0;
        TIM_SetCompare4(TIM1,ABS(Motor1));
    }
    
    //右电机正转
    if(Motor2 >= 0)
    {
        BIN1=1;
        BIN2=0;
        TIM_SetCompare1(TIM1,ABS(Motor2));
    }
    //右电机反转
    else
    {
        BIN1=0;
        BIN2=1;
        TIM_SetCompare1(TIM1,ABS(Motor2));
    }
}
5、在 Motor.c编写绝对值函数 Motor_Load
/***************************************
绝对值函数
经过直立环和速度环以及转向环计算出来的PWM有可能为负值
而赋给定时器PWM寄存器只能是正值。故需要对PWM进行绝对值处理
***************************************/
int ABS(int a)
{            
      int temp;
        if(a<0)  temp=-a;  
      else temp=a;
      return temp;
}
6、在 Motor.h中直流电机初始化函数 Motor_Init和限幅函数 Limit和直流电机装载PWM函数 Motor_Load 绝对值函数 Motor_Load
void Motor_Init(void);
void Motor_Load(int Motor1,int Motor2);
int ABS(int a);
extern int PWM_MAX;
extern int PWM_MIN;
extern int Motor1,Motor2;
//宏定义位带函数
#define AIN1    PBout(12)
#define AIN2    PBout(13)
#define BIN1    PBout(14)
#define BIN2    PBout(15)
7、在sys.h中 #includ e "Motor .h"
#include "Motor.h"
8、【 Motor】结合【PWM】可实现两个直流电机工作
主程序:
#include "sys.h"
int main(void)
{
    PWM_Init_TIM1(72-1,100-1);//初始化PWM 10KHZ,用于驱动电机
    Motor_Init();
    
    while(1)
    {
    Motor_Load(30,30);
}
实现功能:上电后初始化PWM为10KHZ驱动电机和初始化直流电机,之后将PWM装载到两个电机使其转动

Motor】+【PWM】+【Encoder】+【OLED】+【TIMER】可实现两个直流电机工作并通过OLED显示编码器测得速度
主程序:
int Motor1,Motor2;
int Encoder_Left,Encoder_Right;
int main(void)
{
    PWM_Init_TIM1(72-1,100-1);
    OLED_Init();
    Motor_Init();
    Encoder_TIM2_Init();
    Encoder_TIM3_Init();
    TIM4_Init();
    Motor_Load(20,20);
    while(1)
    {
    OLED_ShowString(1,1,"Speed_L:");
    OLED_ShowSignedNum(1,9,Encoder_Left,2);    
    OLED_ShowString(3,1,"Speed_R:");
    OLED_ShowSignedNum(3,9,Encoder_Right,2);
    }
}
实现功能:上电后初始化PWM为10KHZ驱动电机和初始化直流电机,之后将PWM装载到两个电机使其转动,通过外部中断设定闸门时间,使用编码器输入捕获测得电机速度,并在OLED显示左轮和右轮的速度(带符号值)
注意:电机正反转和位置都是相对的,可自行设置

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/393782
推荐阅读
相关标签
  

闽ICP备14008679号