当前位置:   article > 正文

stm32学习笔记1——stm32f103电机闭环控制(标准库)_stm32编码电机驱动代码

stm32编码电机驱动代码

一.电机驱动及电机简介

1.TB6612电机驱动基础引脚简介

AIN1和AIN2功能:电机输出端 控制电机转动方向

PWM功能:控制信号输入  控制电机转速 

STBY功能:正常工作\待机状态控制端

一个使能信号端,当 STBY=1时,正常工作,输入PWM信号,电机可正常运行;当 STBY=0 时,电机驱动处于待机状态,输入信号,电机不会运行。(一般接3.3V即可)

E1A E1B:编码器A B相         编码器原理运用 见下方链接

编码器分类及原理和测速应用

ADC:模数转换器  用于获取电池电压

2.MG513电机 霍尔编码器

具体见下方链接

电机学习:直流电机原理、结构、特点

二.STM32f103VET6电机驱动代码简介

1.电机初始化(驱动两个电机)

  1. /*
  2. PE4 --->AIN1 PE2 --->AIN2
  3. PE5 --->BIN1 PE6 --->BIN2
  4. */
  5. void Motor_Init(void) //电机初始化
  6. {
  7. GPIO_InitTypeDef GPIO_InitStructure; //定义结构体GPIO_InitStructure
  8. RCC_APB2PeriphClockCmd(AIN1_GPIO_CLK, ENABLE); // 使能PE端口时钟
  9. //选择io口
  10. GPIO_InitStructure.GPIO_Pin = AIN1_GPIO_PIN| AIN2_GPIO_PIN|BIN1_GPIO_PIN|BIN2_GPIO_PIN;
  11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出,增大电流输出能力
  12. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度
  13. GPIO_Init(GPIOE, &GPIO_InitStructure); //GBIOE初始化
  14. }

电机转动方向控制代码   对应上述tb6612真值表

  1. void Motor_start(int8_t mode) //电机模式选择 正转 反转
  2. {
  3. if(mode==1) //正转
  4. {
  5. GPIO_SetBits(AIN1_GPIO_PORT, AIN1_GPIO_PIN); // 高电平 PE4 --- AIN1 1
  6. GPIO_ResetBits(AIN2_GPIO_PORT, AIN2_GPIO_PIN); // 低电平 PE2 --- AIN2 0
  7. GPIO_SetBits(BIN1_GPIO_PORT, BIN1_GPIO_PIN); // 高电平 PE5 --- BIN1 1
  8. GPIO_ResetBits(BIN2_GPIO_PORT, BIN2_GPIO_PIN); // 低电平 PE6 --- BIN2 0
  9. }
  10. else if(mode==0) //反转
  11. {
  12. GPIO_ResetBits(AIN1_GPIO_PORT, AIN1_GPIO_PIN); // 低电平 PE4 --- AIN1 0
  13. GPIO_SetBits(AIN2_GPIO_PORT, AIN2_GPIO_PIN); // 高电平 PE2 --- AIN2 1
  14. GPIO_ResetBits(BIN1_GPIO_PORT, BIN1_GPIO_PIN); // 低电平 PE5 --- BIN1 0
  15. GPIO_SetBits(BIN2_GPIO_PORT, BIN2_GPIO_PIN); // 高电平 PE6 --- BIN2 1
  16. }
  17. }
  18. void Motor_stop(void) //电机模式 停止
  19. {
  20. GPIO_ResetBits(AIN1_GPIO_PORT, AIN1_GPIO_PIN); // 低电平 PE4 --- AIN1 0
  21. GPIO_ResetBits(AIN2_GPIO_PORT, AIN2_GPIO_PIN); // 低电平 PE2 --- AIN2 0
  22. GPIO_ResetBits(BIN1_GPIO_PORT, BIN1_GPIO_PIN); // 低电平 PE5 --- BIN1 0
  23. GPIO_ResetBits(BIN2_GPIO_PORT, BIN2_GPIO_PIN); // 低电平 PE6 --- BIN2 0
  24. }

motor.h 宏定义

  1. #define AIN1_GPIO_PIN GPIO_Pin_4
  2. #define AIN1_GPIO_PORT GPIOE
  3. #define AIN1_GPIO_CLK RCC_APB2Periph_GPIOE
  4. #define AIN2_GPIO_PIN GPIO_Pin_2
  5. #define AIN2_GPIO_PORT GPIOE
  6. #define AIN2_GPIO_CLK RCC_APB2Periph_GPIOE
  7. #define BIN1_GPIO_PIN GPIO_Pin_5
  8. #define BIN1_GPIO_PORT GPIOE
  9. #define BIN1_GPIO_CLK RCC_APB2Periph_GPIOE
  10. #define BIN2_GPIO_PIN GPIO_Pin_6
  11. #define BIN2_GPIO_PORT GPIOE
  12. #define BIN2_GPIO_CLK RCC_APB2Periph_GPIOE
  13. void Motor_Init(void); //电机初始化
  14. void Motor_start(int8_t mode); //电机模式选择 正转 反转
  15. void Motor_stop(void); //电机模式 停止

2.配置PWM

默认配置系统时钟为72M

  1. //pwm初始化 参数: arr:设为一个时钟频率的最大值 psc: 预分频值
  2. //以PWM_Int(7199,0)为例;
  3. //初始化pwm输出 72000 000/psc+1=72000 000 记一个数时间为1/7200 0000
  4. //每(7199+1)个计数中断一次 7200 0000/7199+1=10000
  5. //0开始的 所以要+1
  6. void PWM_Int(uint16_t arr,uint16_t psc)
  7. {
  8. GPIO_InitTypeDef GPIO_InitStructure; //定义结构体GPIO_InitStructure
  9. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定义结构体TIM_TimeBaseStructure
  10. TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体TIM_OCInitStructure
  11. RCC_APB2PeriphClockCmd(PWMA_GPIO_CLK,ENABLE); //使能PA端口时钟
  12. RCC_APB2PeriphClockCmd(PWMA_TIM_CLK,ENABLE); //使能定时器1
  13. RCC_APB1PeriphClockCmd(PWMB_TIM_CLK,ENABLE); //使能定时器2
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用模式输出
  15. GPIO_InitStructure.GPIO_Pin = PWMA_GPIO_PIN; //PA8
  16. GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; //IO口速度
  17. GPIO_Init(PWMA_GPIO_PORT,&GPIO_InitStructure); //GPIO初始化
  18. //设置自动重装载寄存器的值 决定每多少个数 记一次中断 即决定占空比的周期 CRR计数器决定占空比
  19. TIM_TimeBaseStructure.TIM_Period = arr;
  20. TIM_TimeBaseStructure.TIM_Prescaler = psc; //预分频值 决定计一个数的时间
  21. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割
  22. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
  23. TIM_TimeBaseInit(PWMA_TIM,&TIM_TimeBaseStructure); //配置定时器1
  24. TIM_OCInitStructure.TIM_OCMode= TIM_OCMode_PWM1; //PWM脉冲宽度调制1
  25. TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
  26. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //设置TIM输出极性为高
  27. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  28. TIM_OC1Init(PWMA_TIM,&TIM_OCInitStructure); //定时器1通道1初始化
  29. TIM_CtrlPWMOutputs(PWMA_TIM,ENABLE); //主输出使能
  30. TIM_OC1PreloadConfig(PWMA_TIM,TIM_OCPreload_Enable); //启用TIM1外设的预装载寄存器
  31. TIM_ARRPreloadConfig(PWMA_TIM,ENABLE); //使能自动装载允许位
  32. TIM_Cmd(PWMA_TIM,ENABLE); //启动定时器1
  33. //TIM2
  34. GPIO_InitStructure.GPIO_Pin = PWMB_GPIO_PIN;
  35. GPIO_Init(PWMB_GPIO_PORT,&GPIO_InitStructure); //GPIO初始化
  36. TIM_TimeBaseInit(PWMB_TIM,&TIM_TimeBaseStructure); //配置定时器2
  37. TIM_OC2Init(PWMB_TIM,&TIM_OCInitStructure); //定时器2通道2初始化
  38. TIM_CtrlPWMOutputs(PWMB_TIM,ENABLE); //主输出使能
  39. TIM_OC2PreloadConfig(PWMB_TIM,TIM_OCPreload_Enable); //使能预装载寄存器
  40. TIM_ARRPreloadConfig(PWMB_TIM,ENABLE); //使能自动装载允许位
  41. TIM_Cmd(PWMB_TIM,ENABLE); //启动定时器1
  42. }

设置占空比函数

  1. void Set_PWMA(int PWM) //设置占空比函数 PWM最大不能超过7199
  2. {
  3. TIM_SetCompare1(PWMA_TIM,PWM);//设置TIM1通道1的占空比 = pwm/7200
  4. }
  5. void Set_PWMB(int PWM)
  6. {
  7. TIM_SetCompare2(PWMB_TIM,PWM); //设置占空比函数
  8. }

pwm.h 宏定义

  1. #define PWMA_GPIO_PIN GPIO_Pin_8
  2. #define PWMA_GPIO_PORT GPIOA
  3. #define PWMA_GPIO_CLK RCC_APB2Periph_GPIOA
  4. #define PWMA_TIM TIM1
  5. #define PWMA_TIM_CLK RCC_APB2Periph_TIM1
  6. #define PWMB_GPIO_PIN GPIO_Pin_1
  7. #define PWMB_GPIO_PORT GPIOA
  8. #define PWMB_GPIO_CLK RCC_APB2Periph_GPIOA
  9. #define PWMB_TIM TIM2
  10. #define PWMB_TIM_CLK RCC_APB1Periph_TIM2
  11. void PWM_Int(uint16_t arr,uint16_t psc); //PWM 初始化函数
  12. void Set_PWMA(int PWM); //设置占空比函数
  13. void Set_PWMB(int PWM); //设置占空比函数

3.主函数(开环控制)

  1. #include "stm32f10x.h"
  2. #include "stm32f10x_it.h"
  3. #include "systick.h"
  4. #include "motor.h"
  5. #include "pwm.h"
  6. int main(void)
  7. {
  8. SystemInit(); //配置系统时钟为72M
  9. Motor_Init(); //电机gpio初始化
  10. PWM_Int(7199,0); //电机pwm初始化
  11. Motor_start(0); //控制电机反转
  12. SysTick_Delay_Ms(100); //延时100ms 等待初始化
  13. while(1)
  14. {
  15. Set_PWMA(3600); //设置占空比函数 3600/7200=1/2
  16. Set_PWMB(3600);
  17. }
  18. }

三.STM32f103VET6 霍尔编码器PID闭环控制

1.配置编码器

采用定时器的输入捕获功能进行编码器脉冲的采集。(也可以采用外部中断 见下方链接)

stm32读取编码器的两种方式

配置编码器GPIO函数

  1. void Encoder_GPIO_Config(void) //编码器GPIO初始化 重定义TIM3和TIM4引脚
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure; //定义一个引脚初始化的结构体
  4. RCC_APB2PeriphClockCmd(E1A_GPIO_CLK, ENABLE); //使能GPIOD时钟
  5. RCC_APB1PeriphClockCmd(E1A_TIM_CLK, ENABLE); //使能TIM4时钟
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能AFIO时钟
  7. GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); //重映射TIM4
  8. GPIO_InitStructure.GPIO_Pin = E1A_GPIO_PIN|E1B_GPIO_PIN; //PD13、PD12
  9. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
  10. GPIO_Init(E1A_GPIO_PORT, &GPIO_InitStructure); //根据GPIO_InitStructure的参数初始化
  11. RCC_APB2PeriphClockCmd(E2A_GPIO_CLK, ENABLE); //使能GPIOC时钟
  12. RCC_APB1PeriphClockCmd(E2A_TIM_CLK, ENABLE); //使能TIM3时钟
  13. GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //重映射TIM4
  14. GPIO_InitStructure.GPIO_Pin = E2A_GPIO_PIN|E2B_GPIO_PIN; //PC6、PC7
  15. GPIO_Init(E2A_GPIO_PORT, &GPIO_InitStructure); //根据GPIO_InitStructure的参数初始化
  16. }

将定时器配置为编码器接口模式   配置定时器中断优先级NVIC

  1. //把TIM3,TIM4初始化为编码器接口模式
  2. void Encoder_TIM_Config(void)
  3. {
  4. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定义一个定时器初始化的结构体
  5. TIM_ICInitTypeDef TIM_ICInitStructure; //定义一个定时器编码器模式初始化的结构体
  6. RCC_APB1PeriphClockCmd(E1A_TIM_CLK,ENABLE); //使能E1的TIM4时钟
  7. RCC_APB2PeriphClockCmd(E2A_TIM_CLK,ENABLE); //使能E2的TIM3时钟
  8. //时基配置
  9. TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //清除之前配置
  10. TIM_TimeBaseStructure.TIM_Period = 65535; //设定计数器自动重装值
  11. TIM_TimeBaseStructure.TIM_Prescaler = 0; // 预分频器
  12. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //选择时钟分频:不分频
  13. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  14. //根据TIM_TimeBaseInitStruct的参数 初始化定时器TIM4
  15. TIM_TimeBaseInit(E1A_TIM, &TIM_TimeBaseStructure);
  16. //输入捕获结构体初始化
  17. TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入
  18. TIM_EncoderInterfaceConfig(E1A_TIM, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising,
  19. TIM_ICPolarity_Rising);//使用编码器模式3CH1CH2同时计数,四分频
  20. TIM_ICInitStructure.TIM_ICFilter = 10; //设置滤波器长度
  21. //将TIM_ICInitStructure参数初始化定时器TIM4编码器模式
  22. TIM_ICInit(E1A_TIM, &TIM_ICInitStructure);
  23. TIM_ClearFlag(E1A_TIM, TIM_FLAG_Update); //清除TIM的更新标志位
  24. TIM_ITConfig(E1A_TIM, TIM_IT_Update, ENABLE); //启用定时器中断
  25. TIM_SetCounter(E1A_TIM,0); //定时器计数值清0
  26. TIM_Cmd(E1A_TIM, ENABLE); //使能定时器4
  27. //TIM3
  28. //根据TIM_TimeBaseInitStruct的参数初始化定时器TIM3
  29. TIM_TimeBaseInit(E2A_TIM, &TIM_TimeBaseStructure);
  30. TIM_EncoderInterfaceConfig(E2A_TIM, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising,
  31. TIM_ICPolarity_Rising);//使用编码器模式3CH1CH2同时计数,四分频
  32. TIM_ICInitStructure.TIM_ICFilter = 10; //设置滤波器长度
  33. //TIM_ICInitStructure参数初始化定时器TIM4编码器模式
  34. TIM_ICInit(E2A_TIM, &TIM_ICInitStructure);
  35. TIM_ITConfig(E2A_TIM, TIM_IT_Update, ENABLE); //启用定时器中断
  36. TIM_ClearFlag(E2A_TIM, TIM_FLAG_Update); //清除TIM的更新标志位
  37. TIM_SetCounter(E2A_TIM,0); //定时器计数值清0
  38. TIM_Cmd(E2A_TIM, ENABLE); //使能定时器3
  39. }
  40. static void TIM3_NVIC_Config(void) //TIM3中断设置
  41. {
  42. NVIC_InitTypeDef NVIC_InitStructure;
  43. // 设置中断组为0
  44. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  45. // 设置中断来源
  46. NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn ;
  47. // 设置主优先级为 0
  48. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  49. // 设置抢占优先级为3
  50. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  51. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  52. NVIC_Init(&NVIC_InitStructure);
  53. }
  54. static void TIM4_NVIC_Config(void) //TIM4中断设置
  55. {
  56. NVIC_InitTypeDef NVIC_InitStructure;
  57. // 设置中断组为0
  58. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  59. // 设置中断来源
  60. NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn ;
  61. // 设置主优先级为 0
  62. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  63. // 设置抢占优先级为3
  64. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  65. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  66. NVIC_Init(&NVIC_InitStructure);
  67. }

编码器脉冲数读取函数

  1. void Read_Encoder_L(void)
  2. {
  3. Encoder_L= TIM_GetCounter(TIM4); //获取外部计数 四倍频要除以4
  4. if(Encoder_L>0x8000)Encoder_L=Encoder_L-0xffff; //判断方向
  5. //大于0xffff的一半 即为负数 因为CNT计数器值为int16 最大为0x8000
  6. TIM_SetCounter(TIM4,0); //清除外部计数
  7. }
  8. void Read_Encoder_R(void)
  9. {
  10. Encoder_R= TIM_GetCounter(TIM3); //获取外部计数 四倍频要除以4
  11. if(Encoder_R>0x8000)Encoder_R=Encoder_R-0xffff;
  12. //大于0xffff的一半 即为负数 因为CNT计数器值为int16 最大为0x8000
  13. TIM_SetCounter(TIM3,0); //清除外部计数
  14. }

Encoder.h宏定义

  1. #define E1A_GPIO_PIN GPIO_Pin_13
  2. #define E1A_GPIO_PORT GPIOD
  3. #define E1A_GPIO_CLK RCC_APB2Periph_GPIOD
  4. #define E1A_TIM TIM4
  5. #define E1A_TIM_CLK RCC_APB1Periph_TIM4
  6. #define E1B_GPIO_PIN GPIO_Pin_12
  7. #define E1B_GPIO_PORT GPIOD
  8. #define E1B_GPIO_CLK RCC_APB2Periph_GPIOD
  9. #define E1B_TIM TIM4
  10. #define E1B_TIM_CLK RCC_APB1Periph_TIM4
  11. #define E2A_GPIO_PIN GPIO_Pin_6
  12. #define E2A_GPIO_PORT GPIOC
  13. #define E2A_GPIO_CLK RCC_APB2Periph_GPIOC
  14. #define E2A_TIM TIM3
  15. #define E2A_TIM_CLK RCC_APB1Periph_TIM3
  16. #define E2B_GPIO_PIN GPIO_Pin_7
  17. #define E2B_GPIO_PORT GPIOC
  18. #define E2B_GPIO_CLK RCC_APB2Periph_GPIOC
  19. #define E2B_TIM TIM8
  20. #define E2B_TIM_CLK RCC_APB2Periph_TIM8
  21. void Encoder_Init(void); //初始化编码器
  22. static void TIM3_NVIC_Config(void);
  23. static void TIM4_NVIC_Config(void);
  24. void Encoder_Init(void);

2.增量式PI闭环控制代码

PID位置式和增量式

霍尔增量式编码器左右车轮线速度的计算

可以先了解位置式和增量式PID的概念和线速度计算 上方连接

增量式PI速度环

  1. /增量式PI控制速度环/
  2. //编码器线数13ppr*30(减速比)=390 轮子转一圈有390个脉冲 四倍频要除以4
  3. //速度计算公式:=脉冲数/390/4*0.53407(轮子周长)*0.01(单位时间) 单位m/s
  4. int16_t Left_Goal;
  5. int16_t Left_Current_Error; //当前误差
  6. int16_t Left_Last_Error = 0; //上次误差
  7. int16_t Left_Previous_Error = 0; //上上次误差
  8. float Left_P = 0.2;
  9. float Left_I = 0.80;
  10. float Left_Speed_PID_OUT; //电机脉冲输出 OUT/7200 = 占空比
  11. int16_t Left_Pro_Speed_PID_OUT; //限幅输出
  12. float Left_Speed = 0.00; //左轮转速 m/s
  13. int16_t Left_Speed_Control(float Goal,int16_t max_left,int16_t min_left) //左电机PID控制
  14. {
  15. Left_Goal = (int16_t)(Goal * 29.21); //速度转编码器
  16. Left_Current_Error = Left_Goal - Encoder_L; //计算当前误差
  17. Left_Speed_PID_OUT += ((Left_P * (Left_Current_Error - Left_Last_Error)) +
  18. Left_I * Left_Current_Error);
  19. //更新上次误差和上上次误差
  20. Left_Previous_Error = Left_Last_Error;
  21. Left_Last_Error = Left_Current_Error;
  22. Left_Pro_Speed_PID_OUT =
  23. (int16_t)Range_protect_float(Left_Speed_PID_OUT,max_left,min_left); //限幅保护函数
  24. Set_PWMA(Left_Pro_Speed_PID_OUT);
  25. return Left_Pro_Speed_PID_OUT;
  26. }

3.定时器配置

要让mcu每10ms读取一次编码器脉冲 则需要开启mcu的定时器进行精准定时

定时器配置代码 配置一个1ms的定时器

  1. uint32_t time = 0;
  2. // 中断优先级配置
  3. static void BASIC_TIM_NVIC_Config(void)
  4. {
  5. NVIC_InitTypeDef NVIC_InitStructure;
  6. // 设置中断组为0
  7. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  8. // 设置中断来源
  9. NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;
  10. // 设置主优先级为 0
  11. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  12. // 设置抢占优先级为3
  13. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  14. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  15. NVIC_Init(&NVIC_InitStructure);
  16. }
  17. //定时器周期为7200 0000/71+1/999+1=1000 一秒1000个脉冲 1个脉冲1ms
  18. void BASIC_TIM_Mode_Config(void)
  19. {
  20. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  21. // 开启定时器时钟,即内部时钟CK_INT=72M
  22. BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);
  23. // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
  24. TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period;
  25. // 时钟预分频数为
  26. TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler;
  27. // 初始化定时器
  28. TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);
  29. // 清除计数器中断标志位
  30. TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);
  31. // 开启计数器中断
  32. TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);
  33. // 使能计数器
  34. TIM_Cmd(BASIC_TIM, ENABLE);
  35. }
  36. void BASIC_TIM_Init(void)
  37. {
  38. BASIC_TIM_NVIC_Config(); //中断优先级配置
  39. BASIC_TIM_Mode_Config(); //定时器配置
  40. }

tim.h宏定义

  1. #define BASIC_TIM TIM6
  2. #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd //定义开启外设时钟函数
  3. #define BASIC_TIM_CLK RCC_APB1Periph_TIM6
  4. #define BASIC_TIM_Period 1000-1 //重装载的值
  5. #define BASIC_TIM_Prescaler 71 //时钟预分频数
  6. #define BASIC_TIM_IRQ TIM6_IRQn
  7. #define BASIC_TIM_IRQHandler TIM6_IRQHandler
  8. void BASIC_TIM_Init(void);
  9. extern uint32_t time;

4.中断处理函数

主函数main配置好初始化代码即可  oled显示是另外增加的  下面函数放 it中断处理文件中

  1. void BASIC_TIM_IRQHandler (void)
  2. {
  3. if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) //获取计数
  4. {
  5. time++;
  6. Key_Proc(); //按键扫描
  7. TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update); //清除计数
  8. if(time==10)
  9. {
  10. if(flag==1)
  11. {
  12. Read_Encoder_L(); //读取编码器脉冲数
  13. Left_Speed_Control(1.0,4000,-4000);
  14. OLED_ShowNum(10,0,Encoder_L,4,12);//显示数字
  15. }
  16. if(flag==0)
  17. {
  18. Read_Encoder_L(); //读取编码器脉冲数
  19. Left_Speed_Control(0.5,4000,-4000);
  20. OLED_ShowNum(10,0,Encoder_L,4,12);//显示数字
  21. }
  22. time = 0;
  23. }
  24. }
  25. }

实物图如上

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号