700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 编码电机pwm驱动 以及脉冲数读取

编码电机pwm驱动 以及脉冲数读取

时间:2022-01-14 05:01:53

相关推荐

编码电机pwm驱动 以及脉冲数读取

开发板 正点原子 stm32F103ZET6

#define _encoder_H_

#ifndef _encoder_H_#define _encoder_H_#include "stm32f10x.h"#include "stm32f10x_tim.h"#define ENCODER_TIM_PERIOD (u16)(65535) //不可大于65535 因为F103的定时器是16位的。typedef struct bianmadianji {float coderA;float coderB;u8 mode; //正反转状态}G_ENCODER;extern G_ENCODER g_ENCODER;void Encoder_Init_TIM2(void); void Encoder_Init_TIM3(void);float Read_EncoderA(void); //读取编码电机A 单位时间内的脉冲数float Read_EncoderB(void); //读取编码电机B 单位时间内的脉冲数void TIM2_IRQHandler(void); //cnt 计数满,清除void TIM3_IRQHandler(void);#endif

encoder.c

#include "encoder.h"G_ENCODER g_ENCODER={0,0,0};/*************************************************************************** 函数功能:把TIM2初始化为编码器接口模式* 端口配置: PA_15 ; PB_3 * 入口参数:无* 返 回 值:无**************************************************************************/void Encoder_Init_TIM2(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);//使能PA PB端口时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //重映射GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//端口配置 PA15GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//根据设定参数初始化GPIOAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//端口配置 PB3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOBTIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//边沿计数模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器2TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入TIM_ICInitStructure.TIM_ICFilter = 10; //设置滤波器长度TIM_ICInit(TIM2, &TIM_ICInitStructure);//根据 TIM_ICInitStruct 的参数初始化外设TIMxTIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//使能定时器中断TIM_SetCounter(TIM2,0); //计数初值设定TIM_Cmd(TIM2, ENABLE); //使能定时器2}/**************************************************************************函数功能:把TIM3初始化为编码器接口模式端口配置: PA6 PA7入口参数:无返回 值:无**************************************************************************/void Encoder_Init_TIM3(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能定时器3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PA端口时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//端口配置 PA6 PA7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//根据设定参数初始化GPIOATIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//边沿计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化定时器3TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3(TIM_ICPolarity_Rising或者TIM_ICPolarity_Falling效果相同,都是4倍频)TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入TIM_ICInitStructure.TIM_ICFilter = 10; //设置滤波器长度TIM_ICInit(TIM3, &TIM_ICInitStructure);//根据 TIM_ICInitStruct 的参数初始化外设TIMxTIM_ClearFlag(TIM3, TIM_FLAG_Update);//清除TIM的更新标志位TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//使能定时器中断TIM_SetCounter(TIM3,0);//计数初值设定TIM_Cmd(TIM3, ENABLE); //使能定时器}/**************************************************************************函数功能:单位时间读取编码器A计数入口参数:无返回 值:计数值**************************************************************************/float Read_EncoderA(void){g_ENCODER.encoderA= (short)TIM2 -> CNT; //该寄存器储存了 编码器的位置信息 TIM2->CNT=0;//读取之后 编码计数--清零--,不清零请注释掉return g_ENCODER.encoderA;}/**************************************************************************函数功能:单位时间读取编码器B计数入口参数:无返回 值:计数值**************************************************************************/float Read_EncoderB(void){g_ENCODER.encoderB= (short)TIM3 -> CNT; //该寄存器储存了 编码器的位置信息, TIM3->CNT = 0 ; //读取之后 编码计数--清零--,不清零请注释掉return g_ENCODER.encoderB;}/*************************************************************************** 函数功能:TIM2中断服务函数** 入口参数:无** 返 回 值:无**************************************************************************/void TIM2_IRQHandler(void){ if(TIM2->SR& 0X0001)//溢出中断{} TIM2->SR&=~(1<<0);//清除中断标志位}/*************************************************************************** 函数功能:TIM3中断服务函数** 入口参数:无** 返 回 值:无**************************************************************************/void TIM3_IRQHandler(void){ if(TIM3->SR&0X0001)//溢出中断{} TIM3->SR&=~(1<<0);//清除中断标志位}

pwm_motor.h

#ifndef _pwm_motor_H#define _pwm_motor_H#include "sys.h"#include "stdio.h"#include "stm32f10x.h"#include "stm32f10x_tim.h"#include "encoder.h"typedef struct pwm_motor_data{uint16_t CCR1_Val ;uint16_t CCR2_Val ;uint16_t CCR3_Val ;uint16_t CCR4_Val ;float speedA;float speedB;uint16_t arr ; //10ms秒读取一次uint16_t psc ;}G_PWM_MOTOR;extern G_PWM_MOTOR g_PWM_MOTOR;void Timer_5_pwm_init();void MOTOR_encoder( uint16_t ccr1,uint16_t ccr2, uint16_t ccr3, uint16_t ccr4);#endif // !1

pwm_motor.c

#include "pwm_motor.h"#include "sys.h"uint16_t arr_5 = 100; //10ms秒读取一次uint16_t psc_5 = 7200-1;G_PWM_MOTOR g_PWM_MOTOR={ .arr= 100-1,.psc= 7200-1,// 占空比配置 有效占比/高电平占比 n/100 %.CCR1_Val=20, .CCR2_Val=20,.CCR3_Val=20,.CCR4_Val=20};void Timer_5_pwm_init() //arr :自动重装值 psc :时钟预分频数{//1) TIM5 时钟使能。RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);// 时钟使能//2) 初始化定时器参数,设置自动重装值, 分频系数,计数方式等。TIM_TimeBaseInitTypeDef Timer_5_initstruct;Timer_5_initstruct.TIM_ClockDivision=TIM_CKD_DIV1; //时钟分频银子Timer_5_initstruct.TIM_CounterMode=TIM_CounterMode_Up;//计数方式 上下....Timer_5_initstruct.TIM_Period= arr_5;//自动重装载时钟周期Timer_5_initstruct.TIM_Prescaler= psc_5;//时钟分频银子//Timer_5_initstruct.TIM_RepetitionCounterTIM_TimeBaseInit( TIM5 , &Timer_5_initstruct);//3) 设置 TIM5_DIER 允许更新中断。TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);//4) TIM5 中断优先级设置。NVIC_InitTypeDef NVIC_init_struct;NVIC_init_struct.NVIC_IRQChannel= TIM5_IRQn; //中断通道NVIC_init_struct.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级NVIC_init_struct.NVIC_IRQChannelSubPriority=1; //相应NVIC_init_struct.NVIC_IRQChannelCmd=ENABLE;//使能中断通道NVIC_Init(&NVIC_init_struct); //初始化/*--------------------pwm输出结构体初始化-------------------*/TIM_OCInitTypeDef TIM_OCInitStructure;// 配置为PWM模式1TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;// 输出使能TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;// 输出通道电平极性配置TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//pwm输出通道 1TIM_OCInitStructure.TIM_Pulse = R1_Val;TIM_OC1Init(TIM5, &TIM_OCInitStructure);TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);// pwm输出通道 2TIM_OCInitStructure.TIM_Pulse = R2_Val;TIM_OC2Init(TIM5, &TIM_OCInitStructure);TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable);// pwm输出通道 3TIM_OCInitStructure.TIM_Pulse = R3_Val;TIM_OC3Init(TIM5, &TIM_OCInitStructure);TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Enable);// pwm输出通道 4TIM_OCInitStructure.TIM_Pulse = R4_Val;TIM_OC4Init(TIM5, &TIM_OCInitStructure);TIM_OC4PreloadConfig(TIM5, TIM_OCPreload_Enable);//5) TIM5 的使能 启动。TIM_Cmd(TIM5, ENABLE);//使能相应 计时器}void MOTOR_encoder( uint16_t ccr1,uint16_t ccr2, uint16_t ccr3, uint16_t ccr4){TIM_SetCompare1(TIM5, ccr1);TIM_SetCompare2(TIM5, ccr2);TIM_SetCompare3(TIM5, ccr3);TIM_SetCompare4(TIM5, ccr4);}void TIM5_IRQHandler(void){if(RESET!=TIM_GetITStatus(TIM5, TIM_IT_Update)){TIM_ClearITPendingBit(TIM5,TIM_IT_Update);//触发中断后 重新计时 Read_EncoderA(); //更新编码机 读取到的 10ms内的 脉冲数Read_EncoderB();// g_PWM_MOTOR.speedA =//知道了 10ms 的脉冲数,可以计算电机转速// g_PWM_MOTOR.speedB = printf("编码机A脉冲数:%.2f /10ms", g_ENCODER.coderA);printf("编码机B脉冲数:%.2f /10ms", g_ENCODER.coderB);}}

main.c

#include "usart.h"#include "delay.h"#include "lcd.h"#include "led.h"#include "key.h"#include "encoder.h"#include "pwm_motor.h"void init____(void){delay_init();LED_Init(); KEY_Init(); LCD_Init(); uart_init(115200);Timer_5_pwm_init(); //电机pwm发生源初始化Encoder_Init_TIM2(); Encoder_Init_TIM3();}int main(void){//编码器数值的读取 以及串口打印 //在 pwm_motor.c文件内的 TIM5中断函数u8 key_value = 0xff;while(1){key_value=KEY_Scan(0);switch( key_value ){case KEY0_PRES: R1_Val-=20 ; break; //这里 只控制 TIM5 的 通道一输出的 pwm波 占空比 用作测试case KEY1_PRES: R1_Val+=20 ;break;case WKUP_PRES: R1_Val =100 ; break;default : break;}if( R1_Val > 100 || R1_Val <0){R1_Val = 0 ;}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。