Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
学习STM32编程——智能小车电机调速模块的应用开发,希望能够帮助你!!!。
关键代码:
timer.c
/** * @brief Timer1 输出比较通道 GPIO 端口的功能配置 * @param None * @retval None */ void TIM1_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE); /* CH1:PE9 | CH2:PE11 | CH3:PE13 | CH4:PE14 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;// 复用功能 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11| \ GPIO_Pin_13|GPIO_Pin_14; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOE,&GPIO_InitStructure); /* PE9|PE11|PE13|PE14 复用为 TIM1 外部通道 GPIO */ GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1); } /** * @brief Timer1 时基和 PWM 输出功能初始化 * @param arr: 自动重载寄存器值, PSC: 预分频器分频系数 * @retval None */ void TIM1_PWM_Init(uint16_t arr, uint16_t psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* SystemCoreClock = */ uint32_t TimerPeriod = 1/(SystemCoreClock/(psc+1))*(arr+1); uint32_t ccr1 = (arr+1) / 2; // 占空比 1/2 = 50% uint32_t ccr2 = (arr+1) / 3; // 占空比 1/3 = 33% uint32_t ccr3 = (arr+1) / 4; // 占空比 1/4 = 25% uint32_t ccr4 = (arr+1) / 5; // 占空比 1/5 = 20% RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); /* 定时器基本初始化 */ TIM_TimeBaseInitStructure.TIM_Period = arr; // 自动重载寄存器值 TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 预分频系数 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 死区控制用 TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;// 递增计数 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;// 重复计数器设置为 0 TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure); /* 定时器输出比较功能初始化 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;// 输出比较模式为 PWM1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OCInitStructure.TIM_Pulse = ccr1; // 通道 1 的 TIMx_CCR1 初值 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(TIM1,&TIM_OCInitStructure); // 通道 1 初始化 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);// 使能预装载寄存器 TIM_OCInitStructure.TIM_Pulse = ccr2; // 通道 2 的 TIMx_CCR2 初值 TIM_OC2Init(TIM1,&TIM_OCInitStructure); // 通道 2 初始化 TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);// 使能预装载寄存器 TIM_OCInitStructure.TIM_Pulse = ccr3; // 通道 3 的 TIMx_CCR3 初值 TIM_OC3Init(TIM1,&TIM_OCInitStructure); // 通道 3 初始化 TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);// 使能预装载寄存器 TIM_OCInitStructure.TIM_Pulse = ccr4; // 通道 4 的 TIMx_CCR4 初值 TIM_OC4Init(TIM1,&TIM_OCInitStructure); // 通道 4 初始化 TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); // 使能预装载寄存器 TIM_ARRPreloadConfig(TIM1,ENABLE); //ARPE 使能 TIM_Cmd(TIM1,ENABLE); // 使能定时器 1 /* 高级控制定时器需要配置 TIMx_BDTR 的第 15 位 _MOE ,才可使能主输出 */ TIM_CtrlPWMOutputs(TIM1,ENABLE); }
motor.c
/** * @brief 小车前进,电机正转控制 * @param speed: 前进速度 (TIMx_CCR 值 ) * @retval None */ void Car_Forward(int16_t speed) { int16_t backSpeed; nSLEEP = 1; if(speed > 0) { if(speed > 100) speed = 100; /* 第一路电机控制 */ TIM_SetCompare1(TIM1, speed); TIM_SetCompare2(TIM1, 0); /* 第二路电机控制 */ TIM_SetCompare3(TIM1, speed); TIM_SetCompare4(TIM1, 0); } else if(speed < 0) { if(speed < -100) speed = -100; backSpeed = -speed; /* 第一路电机控制 */ TIM_SetCompare1(TIM1, backSpeed); TIM_SetCompare2(TIM1, 0); /* 第二路电机控制 */ TIM_SetCompare3(TIM1, backSpeed); TIM_SetCompare4(TIM1, 0); } TIM_CtrlPWMOutputs(TIM1,ENABLE); } /** * @brief 小车后退,电机反转控制 * @param speed: 后退速度 (TIMx_CCR 值 ) * @retval None */ void Car_Backup(int16_t speed) { int16_t backSpeed; nSLEEP = 1; if(speed > 0) { if(speed > 100) speed = 100; /* 第一路电机控制 */ TIM_SetCompare1(TIM1, 0); TIM_SetCompare2(TIM1, speed); /* 第二路电机控制 */ TIM_SetCompare3(TIM1, 0); TIM_SetCompare4(TIM1, speed); } else if(speed < 0) { if(speed < -100) speed = -100; backSpeed = -speed; /* 第一路电机控制 */ TIM_SetCompare1(TIM1, 0); TIM_SetCompare2(TIM1, backSpeed); /* 第二路电机控制 */ TIM_SetCompare3(TIM1, 0); TIM_SetCompare4(TIM1, backSpeed); } TIM_CtrlPWMOutputs(TIM1,ENABLE); } /** * @brief 小车停止控制 * @param None * @retval None */ void Car_Stop(void) { nSLEEP = 1; /* 第一路电机控制 */ TIM_SetCompare1(TIM1, 95); TIM_SetCompare2(TIM1, 95); /* 第二路电机控制 */ TIM_SetCompare3(TIM1, 95); TIM_SetCompare4(TIM1, 95); TIM_CtrlPWMOutputs(TIM1,ENABLE); }
main.c
int main(void) { delay_init(168); // 延时函数初始化 LED_Init(); //LED 端口初始化 Key_Init(); // 按键初始化 EXTIx_Init(); // 外部中断初始化 USART1_Init(); //USART1 初始化 TIM1_GPIO_Config(); // 定时器 1 输出通道 GPIO 初始化 /* 定时器 1 PWM 输出功能初始化 */ TIM1_PWM_Init(100-1, 12-1); printf("System Started!\r\n"); while(1) { Key_Process(); LED1 = ~LED1; delay_ms(50); } return 0; } /** * @brief 按键处理流程 * @param None * @retval None */ static void Key_Process(void) { /* Key1_ 上键按下,电机正转,小车前进 */ if(keyValue == KEY_U_PRESS) { if(Motor_State == MOTOR_STOP) { Car_Forward(70); // 电机正转,小车前进 Motor_State = MOTOR_FORWARD; } else if(Motor_State == MOTOR_FORWARD || \ Motor_State == MOTOR_BACKUP) { Car_Stop(); Motor_State = MOTOR_STOP; } keyValue = 0; } /* Key2_ 下键按下,电机反转,小车后退 */ if(keyValue == KEY_D_PRESS) { if(Motor_State == MOTOR_STOP) { Car_Backup(70); // 电机反转,小车后退 Motor_State = MOTOR_BACKUP; } else if(Motor_State == MOTOR_FORWARD || \ Motor_State == MOTOR_BACKUP) { Car_Stop(); Motor_State = MOTOR_STOP; } keyValue = 0; } /* Key3_ 左键按下,减小占空比 */ if(keyValue == KEY_L_PRESS) { if(Motor_State == MOTOR_FORWARD) { newSpeed -= 2; if(newSpeed < 0) newSpeed = 0; Car_Forward(newSpeed); } else if(Motor_State == MOTOR_BACKUP) { newSpeed -= 2; if(newSpeed < 0) newSpeed = 0; Car_Backup(newSpeed); } keyValue = 0; } /* Key4_ 右键按下,增大占空比 */ if(keyValue == KEY_R_PRESS) { if(Motor_State == MOTOR_FORWARD) { newSpeed += 2; if(newSpeed >= 100) newSpeed = 100; Car_Forward(newSpeed); } else if(Motor_State == MOTOR_BACKUP) { newSpeed += 2; if(newSpeed >= 100) newSpeed = 100; Car_Backup(newSpeed); } keyValue = 0; } }
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章