目录
前言
一、定时器部分和按键部分
二、PWM调速
三、电机驱动部分
三、编码器接口部分(测速)
四.主函数
总结
推荐STM32学习课程:
[6-8] 编码器接口测速_哔哩哔哩_bilibili[6-8] 编码器接口测速是STM32入门教程-2022持续更新中的第20集视频,该合集共计30集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bilibili.com/video/BV1th411z7sn/” />STM32F103C8T6延时函数和OLED显示屏代码_HX091624的博客-CSDN博客
前言
电机编码器是安装在电机上的旋转编码器,它通过跟踪电机轴的速度和/或位置来提供闭环反馈信号。监视的参数由应用的类型确定,可以包括速度,距离,RPM,位置等。利用编码器或其他传感器控制的特定参数的应用称为闭环反馈或闭环控制系统
一、定时器部分和按键部分
#include "stm32f10x.h"// Device header//定时中断->1svoid Timer_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_InternalClockConfig(TIM2);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2, ENABLE);}/*void TIM2_IRQHandler(void){if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}}*/
#include "stm32f10x.h"void Key_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);}uint8_t Key_GetNum(void){uint8_t KeyNum = 0;if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0){Delay_ms(20);while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);Delay_ms(20);KeyNum = 1;}return KeyNum;}
二、PWM调速
#include "stm32f10x.h" //定时器3->PWM调速周期20MS计一个数->1USvoid PWM_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//电动机PWM输出 PA6 PA7GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//舵机PWM输出PB0GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);TIM_InternalClockConfig(TIM3);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;//ARRTIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);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; //CCRTIM_OC1Init(TIM3, &TIM_OCInitStructure); //PWM输出引脚TIM_OC2Init(TIM3, &TIM_OCInitStructure);TIM_OC3Init(TIM3, &TIM_OCInitStructure);TIM_Cmd(TIM3, ENABLE);}//左右电机输出比较void PWM_SetCompare1(uint16_t Compare){TIM_SetCompare1(TIM3, Compare);}void PWM_SetCompare2(uint16_t Compare){TIM_SetCompare2(TIM3, Compare);}//舵机输出比较void PWM_SetCompare3(uint16_t Compare){TIM_SetCompare3(TIM3, Compare);}
三、电机驱动部分
电机:电机如何驱动在我之前的文章有写,这里就不再解释了。
#include "stm32f10x.h" #include "PWM.h"//左右电机初始化void Motor_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//电机控制模拟输入端GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//控制左电机->PA0 PA1 控制右电机->PA4 PA5GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1|GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);PWM_Init();}//右边电机向前void Right_moto_go(void){//正转GPIO_SetBits(GPIOA, GPIO_Pin_4);GPIO_ResetBits(GPIOA, GPIO_Pin_5);}//右边电机向后void Right_moto_back(void){//反转GPIO_ResetBits(GPIOA, GPIO_Pin_4);GPIO_SetBits(GPIOA, GPIO_Pin_5);}//右边电机停止void Right_moto_Stop(void){//停车GPIO_ResetBits(GPIOA, GPIO_Pin_4);GPIO_ResetBits(GPIOA, GPIO_Pin_5);}//左边电机向前void Left_moto_go(void){//正转GPIO_SetBits(GPIOA, GPIO_Pin_0);GPIO_ResetBits(GPIOA, GPIO_Pin_1);}//左边电机向后void Left_moto_back(void){//反转GPIO_ResetBits(GPIOA, GPIO_Pin_0);GPIO_SetBits(GPIOA, GPIO_Pin_1);}//左边电机停止void Left_moto_Stop(void){//停车GPIO_ResetBits(GPIOA, GPIO_Pin_0);GPIO_ResetBits(GPIOA, GPIO_Pin_1);}
#include "stm32f10x.h"#include "Motor.h"#include "PWM.h"//小车调速函数void Speed_Control(uint16_t Compare){Compare*=200; //100->20000PWM_SetCompare1(Compare); //调速PWM_SetCompare2(Compare);}//小车前进函数void run(uint16_t Compare){Speed_Control(Compare);Left_moto_go();//左电机往前Right_moto_go(); //右电机往前}//小车后退函数void backrun(uint16_t Compare){Speed_Control(Compare);Left_moto_back();//左电机往后Right_moto_back(); //右电机往后}//小车停车函数void stop(void) { Left_moto_Stop();//左电机停止Right_moto_Stop(); //右电机停止}
三、编码器接口部分(测速)
编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度。
#include "stm32f10x.h"// Device header//测速void Encoder_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//TIM1的CH1和CH2GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;//ARRTIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);//在TI1和TI2上计数TIM_ICInitTypeDef TIM_ICInitStructure;TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICFilter = 0xF;TIM_ICInit(TIM1, &TIM_ICInitStructure);TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;TIM_ICInitStructure.TIM_ICFilter = 0xF;TIM_ICInit(TIM1, &TIM_ICInitStructure);//定时器编码器接口配置//通道不反相TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);TIM_Cmd(TIM1, ENABLE);}int16_t Encoder_Get(void){int16_t Temp;Temp = TIM_GetCounter(TIM1);TIM_SetCounter(TIM1, 0);return Temp;}
四.主函数
#include "stm32f10x.h"#include "Key.h"#include "OLED.h"#include "Timer.h"#include "Motor.h"#include "MotorRun.h"#include "Encoder.h"int16_t Speed;int8_t KeyNum;int main(void){Key_Init();OLED_Init();Timer_Init();Motor_Init();Encoder_Init();OLED_ShowString(1, 1, "Speed:");while (1){KeyNum=Key_GetNum();//电机旋转if(KeyNum==1){run(50);}OLED_ShowSignedNum(1, 7, Speed, 5); //显示速度}}void TIM2_IRQHandler(void){if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){//每隔一段时间获取速度Speed = Encoder_Get();TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}}
总结
注意:两个输入引脚借用了输入捕获的通道1和通道2,而接通道3和通道4是没有用的。
以上就是编码器电机的代码,欢迎大家留言评论,遇到问题都可以在评论区留言。