STM32F103之实验2控制1个电机并采用编码器读取电机转速(代码)

在实验1的电机驱动基础上,这里补充编码器测速的程序部分

#include "encoder.h"
#include "led.h"
///TIM4 编码器输入,TIM4_CH1作A相,TIM4_CH2作B相GPIO_Pin_6|GPIO_Pin_7;

TIM_ICInitTypeDef  TIM_ICInitStructure;
void TIM4_Encoder_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef  GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);// 使能定时器时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //io口使能使用到的捕获编码器AB相借,
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入  
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

 GPIO_Init(GPIOB, &GPIO_InitStructure);  
 //推挽输出 ,IO口速度为50MHz
 //初始化TIM4的时机单元
    TIM_TimeBaseStructure.TIM_Period = 899; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =0; //设置用来作为TIMx时钟频率除数的预分频值  不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 //配置对应寄存器为编码器接口模式以及配置相关的输入捕获配置
  //THE MODE OF ENCODER 
     TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);  
//TIM_ICPolarity_Rising上升沿捕获 
     TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 
  TIM_ICInitStructure.TIM_ICFilter = 0x01;//IC1F=0000 配置输入滤波器 不滤波
  TIM_ICInit(TIM4, &TIM_ICInitStructure);
// Enable the TIM4 Update Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

 
   TIM_ClearFlag(TIM4, TIM_FLAG_Update);
   TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);   
   TIM_SetCounter(TIM4,0);
   TIM_Cmd(TIM4, ENABLE);  //使能TIM4 
  }
u8  TIM4CH1_CAPTURE_STA=0; //输入捕获状态    
u16 TIM4CH1_CAPTURE_VAL; //输入捕获值
 //定时器4中断服务程序  
void TIM4_IRQHandler(void)

  if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{  
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)

{    
if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM4CH1_CAPTURE_VAL=0XFFFF;
}else TIM4CH1_CAPTURE_STA++;
}  
}

    TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除中断标志位
 }
}
float HF_Get_Encode_TIM4(void)
{
    float cnt;
    cnt  = (float)((uint16_t)0x7fff) - (float)((uint16_t)(TIM4->CNT)) ;
    TIM4->CNT = 0x7fff;
    return cnt;

}

主函数如下:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pwm.h"
#include "usart.h"
#include "encoder.h"


 int main(void)
 {
  int cnt;
      delay_init();     //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
myusart_init(9600); //串口初始化为9600  
    LED_Init();//初始化与LED连接的硬件接口 
TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz . 电机的频率不得小于10K
TIM4_Encoder_Init(9999,72-1);//1s
// HF_Encoder_Init(TIM4,0);
    while(1)
{
   
TIM_SetCompare1(TIM1,600);
   GPIO_ResetBits(GPIOD,GPIO_Pin_2); 
     delay_ms(100);
 GPIO_SetBits(GPIOD,GPIO_Pin_2); 
 delay_ms(100);

     cnt=(int)TIM_GetCounter(TIM4); 
 
printf("Position = %d\n\r", cnt);
   
 printf("陈xx最漂亮\r\n");  
  }
}  


猜你喜欢

转载自blog.csdn.net/qq_31530791/article/details/80659439