赞
踩
不积跬步,无以至千里;不积小流,无以成江海。
大家好,我是闲鹤,公众号 xxh_zone,十多年开发、架构经验,先后在华为、迅雷服役过,也在高校从事教学3年;目前已创业了7年多,主要从事物联网/车联网相关领域和业务。
喜欢交友、骑行、写毛笔字、弹吉他、折腾硬件和写代码。
ps:
如对以下内容有疑问或者咨询,可进行留言 或 添加我的微信公众号留言
演示视频
https://www.bilibili.com/video/BV1Ai421e7sv/?vd_source=f1d43113e0df5436df9402483a18e193
电路图:
代码层封装成了4部分:
Motor_Init
、Motor_Start
、Motor_Stop
、Motor_Forward
、Motor_Reverse
、Motor_Accelerate
函数整体代码结构图:
PWM.c
#include "stm32f10x.h" // Device header void PWM_Init(void) { // 时基 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStruct.TIM_Period = 100 - 1; TIM_TimeBaseStruct.TIM_Prescaler = 36 - 1; TIM_TimeBaseStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct); // OC TIM_OCInitTypeDef TIM_OCInitStruct; TIM_OCStructInit(&TIM_OCInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse = 0; TIM_OC1Init(TIM2, &TIM_OCInitStruct); // 输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); TIM_Cmd(TIM2, ENABLE); } void PWM_SetCompare(uint8_t compare) { TIM_SetCompare1(TIM2, compare); }
Motor.c
#include "Motor.h" #include "PWM.h" #define IN1 GPIO_Pin_10 #define IN2 GPIO_Pin_11 void Motor_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = IN1 | IN2; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); PWM_Init(); } /** 启动 **/ void Motor_Start(void) { Motor_Forward(); Motor_Accelerate(30); } /* 停止 */ void Motor_Stop(void) { GPIO_ResetBits(GPIOA, IN1); GPIO_ResetBits(GPIOA, IN2); } /** 正转 前进 **/ void Motor_Forward(void) { GPIO_SetBits(GPIOA, IN1); GPIO_ResetBits(GPIOA, IN2); } /** 反转 后退 **/ void Motor_Reverse(void) { GPIO_SetBits(GPIOA, IN2); GPIO_ResetBits(GPIOA, IN1); } /** 加速 **/ void Motor_Accelerate(uint8_t speed) { PWM_SetCompare(speed); }
MotorControl.c
#include "stm32f10x.h" // Device header #include "MotorControl.h" #include "Delay.h" #include "Motor.h" /* 提供 1. 启动按键 B12 2. 停止按键 B13 3. 加速按键 B14 4. 减速按键 B15 5. 倒车按键 B11 */ #define MC_KEY_GPIO GPIOB #define MC_START_KEY_PIN GPIO_Pin_11 #define MC_START_KEY_GPIO GPIOB #define MC_STOP_KEY_PIN GPIO_Pin_10 #define MC_STOP_KEY_GPIO GPIOB #define MC_ACC_KEY_PIN GPIO_Pin_0 #define MC_ACC_KEY_GPIO GPIOB #define MC_DEC_KEY_PIN GPIO_Pin_6 #define MC_DEC_KEY_GPIO GPIOA #define MC_BACK_KEY_PIN GPIO_Pin_3 #define MC_BACK_KEY_GPIO GPIOA int8_t speed = 0; uint8_t is_running = 0; void MC_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 低电平有效 GPIO_InitStruct.GPIO_Pin = MC_START_KEY_PIN | MC_STOP_KEY_PIN | MC_ACC_KEY_PIN | MC_DEC_KEY_PIN | MC_BACK_KEY_PIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_Init(GPIOA, &GPIO_InitStruct); Motor_Init(); } /** 启动 **/ void MC_Start(void) { if(GPIO_ReadInputDataBit(MC_START_KEY_GPIO, MC_START_KEY_PIN) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(MC_START_KEY_GPIO, MC_START_KEY_PIN) == 0); Delay_ms(20); speed = 30; is_running = 1; Motor_Forward(); Motor_Accelerate(speed); } } /** 停止 **/ void MC_Stop(void) { if(GPIO_ReadInputDataBit(MC_STOP_KEY_GPIO, MC_STOP_KEY_PIN) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(MC_STOP_KEY_GPIO, MC_STOP_KEY_PIN) == 0); Delay_ms(20); speed = 0; is_running = 0; Motor_Stop(); } } /** 加速 **/ void MC_ACC(void) { if(is_running == 0) return; if(GPIO_ReadInputDataBit(MC_ACC_KEY_GPIO, MC_ACC_KEY_PIN) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(MC_ACC_KEY_GPIO, MC_ACC_KEY_PIN) == 0); Delay_ms(20); speed += 20; if(speed >= 100) speed = 100; Motor_Accelerate(speed); } } /** 减速 **/ void MC_DEC(void) { if(is_running == 0) return; if(GPIO_ReadInputDataBit(MC_DEC_KEY_GPIO, MC_DEC_KEY_PIN) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(MC_DEC_KEY_GPIO, MC_DEC_KEY_PIN) == 0); Delay_ms(20); speed -= 20; if(speed <= 0) speed = 0; Motor_Accelerate(speed); } } /** 倒车 **/ void MC_Back(void) { if(GPIO_ReadInputDataBit(MC_BACK_KEY_GPIO, MC_BACK_KEY_PIN) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(MC_BACK_KEY_GPIO, MC_BACK_KEY_PIN) == 0); Delay_ms(20); is_running = 1; Motor_Reverse(); } } /** 准备就绪 **/ void MC_Ready(void) { MC_Start(); MC_Stop(); MC_ACC(); MC_DEC(); MC_Back(); }
main.c
#include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include <stdio.h> #include "MotorControl.h" char loginfo[100] = {0}; extern uint8_t speed; extern uint8_t is_running; void Log(uint8_t Line, uint8_t Column) { OLED_ShowString(Line, Column, loginfo); } int main() { OLED_Init(); MC_Init(); while(1) { MC_Ready(); sprintf(loginfo, "Run: %s ", (is_running == 1 ? "Y" : "N")); Log(1, 1); sprintf(loginfo, "Speed: %d ", speed); Log(2, 1); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。