脉冲很正点
//stm32驱动步进电机 串口输出控制旋转角度 光电开关检测位置 开机自动归零
#include "pwm.h"
#include "led.h"
#include "usart.h"
//TIM1 PWM部分初始化
//高级定时器
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
#if 0
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);// ①使能 tim1 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB, ENABLE); //①使能 GPIO 外设时钟使能
//设置该引脚为复用输出功能,输出 TIM1 CH1 的 PWM 脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//设置该引脚为复用输出功能,输出 TIM1 CH2 的 PWM 脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);//高级
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为 TIMx 时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //②初始化 TIMx
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
TIM_UpdateRequestConfig(TIM1,TIM_UpdateSource_Regular); /********* 设置只有计数溢出作为更新中断 ********/
TIM_SelectOnePulseMode(TIM1,TIM_OPMode_Single);/******* 单脉冲模式 **********/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //脉宽调制模式 2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //③初始化外设 TIMx
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //③初始化外设 TIMx
// CH1的PWM脉冲波形
TIM_CtrlPWMOutputs(TIM1,ENABLE); //⑤MOE 主输出使能
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1 预装载使能
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH2 预装载使能
// CH1的PWM脉冲波形
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能 TIMx 在 ARR 上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //④使能 TIM1
}
#endif
//TIM2 PWM部分初始化
//PWM输出初始化 PA0(TIM2_CH1)
//arr:自动重装值
//psc:时钟预分频数
void TIM2_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB , ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE); //Timer2部分重映射 TIM2_CH1->PA0 没有映射
//设置该引脚为复用输出功能,输出TIM2 CH1的PWM脉冲波形 GPIOA.0 重映射的端口remap 没有映射
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM2_CH1 TIM_CH2 TIM_CH3 TIM_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
//初始化TIM2
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM2 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高TIM_OCPolarity_High 接高电平极性为高 接低电平输出极性为低TIM_OCPolarity_Low
TIM_OC1Init(TIM2, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM2 CH1 TIM_OC1PreloadConfig
TIM_OC2Init(TIM2, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM2 CH2 TIM_OC1PreloadConfig
TIM_OC3Init(TIM2, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM2 CH3 TIM_OC1PreloadConfig
TIM_OC4Init(TIM2, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM2 CH4 TIM_OC1PreloadConfig
// CH1的PWM脉冲波形
#if 0
TIM_CtrlPWMOutputs(TIM2,ENABLE); //⑤MOE 主输出使能 非高级定时器可省略
#endif
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR1上的预装载寄存器 TIM2 CH1
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR1上的预装载寄存器 TIM2 CH2
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR1上的预装载寄存器 TIM2 CH3
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR1上的预装载寄存器 TIM2 CH4
// CH1的PWM脉冲波形
TIM_ARRPreloadConfig(TIM2, ENABLE); //使能 TIMx 在 ARR 上的预装载寄存器 非高级定时器可省略
TIM_Cmd(TIM2, ENABLE); //使能TIM2
}
//TIM3 PWM部分初始化
//PWM输出初始化 PA6(TIM3_CH1) PA7(TIM3_CH2) PB0(TIM3_CH3) PB1(TIM3_CH4)
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
// GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5 PC7
//设置该引脚为复用输出功能,输出TIM3 CH3的PWM脉冲波形 GPIOB.0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM_CH3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//设置该引脚为复用输出功能,输出TIM3 CH4的PWM脉冲波形 GPIOB.1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//设置该引脚为直接输出功能,输出TIM3 CH1的PWM脉冲波形 GPIOA.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
//设置该引脚输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOA.7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 3
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC1 TIM3 CH1的PWM脉冲波形 GPIOA.6
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2 TIM3 CH2的PWM脉冲波形 GPIOA.7
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2 TIM3 CH2的PWM脉冲波形 GPIOB.0
TIM_OC4Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2 TIM3 CH2的PWM脉冲波形 GPIOB.1
// CH1的PWM脉冲波形
#if 0
TIM_CtrlPWMOutputs(TIM2,ENABLE); //⑤MOE 主输出使能 非高级定时器可省略
#endif
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的预装载寄存器 TIM3 CH1的PWM脉冲波形 GPIOA.6
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器 TIM3 CH2的PWM脉冲波形 GPIOA.7
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器 TIM3 CH2的PWM脉冲波形 GPIOB.0
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器 TIM3 CH2的PWM脉冲波形 GPIOB.1
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
//TIM4 PWM部分初始化
//PWM输出初始化 PB6(TIM4_CH1) PB7(TIM4_CH2) PB8(TIM4_CH3)
//arr:自动重装值
//psc:时钟预分频数
void TIM4_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4时钟
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟 有复用
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM4, ENABLE); //Timer4部分重映射 TIM4_CH1->PB6 没有映射
//设置该引脚为复用输出功能,输出TIM4 CH1的PWM脉冲波形 GPIOB.6 PB.7 PB.8 没有映射 重映射的端口remap
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8; //TIM_CH1 TIM_CH2 TIM_CH3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO PB.6 PB.7 PB.8
//初始化TIM4
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为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的时间基数单位
//初始化TIM4 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高TIM_OCPolarity_High 接高电平极性为高 接低电平输出极性为低TIM_OCPolarity_Low
TIM_OC1Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 CH1 TIM_OC1PreloadConfig
TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 CH1 TIM_OC1PreloadConfig
TIM_OC3Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 CH3 TIM_OC1PreloadConfig
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR1上的预装载寄存器 TIM4 CH1
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR3上的预装载寄存器 TIM4 CH2
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR3上的预装载寄存器 TIM4 CH3
// CH1的PWM脉冲波形
// TIM_CtrlPWMOutputs(TIM4,ENABLE); //⑤MOE 主输出使能 非高级定时器可省略 通用定时器 2 3 4 5
// TIM_ARRPreloadConfig(TIM4, ENABLE); //使能 TIMx 在 ARR 上的预装载寄存器 非高级定时器可省略
TIM_Cmd(TIM4, ENABLE); //使能TIM4
}
//TIM5 PWM部分初始化
//PWM输出初始化 PA1(TIM5_CH2) PA2(TIM5_CH3)
//arr:自动重装值
//psc:时钟预分频数
void TIM5_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能定时器4时钟
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟 有复用
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM4, ENABLE); //Timer4部分重映射 TIM4_CH1->PB6 没有映射
//设置该引脚为复用输出功能,输出TIM5 CH2的PWM脉冲波形 GPIOB.6 PB.8 没有映射 重映射的端口remap
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; //TIM5_CH2 PA1 TIM5_CH3 PA2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO PA1
//初始化TIM5
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM4 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高TIM_OCPolarity_High 接高电平极性为高 接低电平输出极性为低TIM_OCPolarity_Low
//TIM_OC1Init(TIM5, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM5 CH1 TIM_OC1PreloadConfig
TIM_OC2Init(TIM5, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM5 CH2 TIM_OC1PreloadConfig
TIM_OC3Init(TIM5, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM5 CH3 TIM_OC1PreloadConfig
TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable); //使能TIM5在CCR1上的预装载寄存器 TIM5 CH2
TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Enable); //使能TIM5在CCR3上的预装载寄存器 TIM5 CH3
// CH2的PWM脉冲波形
#if 0
TIM_CtrlPWMOutputs(TIM5,ENABLE); //⑤MOE 主输出使能 非高级定时器可省略 通用定时器 2 3 4 5
TIM_ARRPreloadConfig(TIM5, ENABLE); //使能 TIMx 在 ARR 上的预装载寄存器 非高级定时器可省略
#endif
TIM_Cmd(TIM5, ENABLE); //使能TIM4
}
#include "moto.h"
#include "delay.h"
#include "pwm.h"
#include "USART.h"
#include "wdg.h"
#include "key.h"
#include "string.h"
//电机驱动函数初始化
//初始化使能端EN
//初始化方向端DIR
int16_t maic=0;
void moto_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //使能PA,PB端口时钟
//电机使能 GPIOC 0 2 4 14
/***************** EN *******************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_4|GPIO_Pin_14; //D1->_EN-->PC.0 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC.0
GPIO_SetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_4|GPIO_Pin_14); //PC.0 2 4 10 输出高
//电机方向控制
//GPIOC 1 3 5 15
/***************** DIR *******************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_15;//D1->DIR-->转动方向端口配置, 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC
// //电机脉冲控制
// /***************** STEP *******************/
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//D1->DIR-->转动方向端口配置, 推挽输出
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
// GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOC
}
/***************电机1****************/
void PWM_DIANJICOROTATION1()//顺时针
{
crc16_data1[0]|=(1<<0);
crc16_data1[1]=0x01;
GPIO_ResetBits( D1_EN,D1_GPIO_EN);//使能
GPIO_SetBits(D1_DIR,D1_GPIO_DIR);//正反转 顺时针
TIM_SetCompare1(TIM2,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP1()//逆时针时针
{
crc16_data1[0]|=(1<<0);
crc16_data1[1]=0x02;
GPIO_ResetBits( D1_EN,D1_GPIO_EN);//使能
GPIO_ResetBits(D1_DIR,D1_GPIO_DIR);//正反转 逆时针
TIM_SetCompare1(TIM2,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机2****************/
void PWM_DIANJICOROTATION2()//顺时针
{
crc16_data2[0]|=(1<<1);
crc16_data2[1]=0x01;
//TIM3_PWM_Init(499,300); // 电机脉冲频率
GPIO_ResetBits( D2_EN,D2_GPIO_EN);//使能
GPIO_SetBits(D2_DIR,D2_GPIO_DIR);//正反转 顺时针
TIM_SetCompare1(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP2()//逆时针
{
crc16_data2[0]|=(1<<1);
crc16_data2[1]=0x02;
//TIM3_PWM_Init(499,110); // 电机脉冲频率
GPIO_ResetBits( D2_EN,D2_GPIO_EN);//使能
GPIO_ResetBits(D2_DIR,D2_GPIO_DIR);//正反转 逆时针
TIM_SetCompare1(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机3****************/
void PWM_DIANJICOROTATION3()//顺时针
{
crc16_data3[0]=0x03;
crc16_data3[1]=0x01;
//TIM4_PWM_Init(499,110); // 电机脉冲频率
GPIO_ResetBits( D3_EN,D3_GPIO_EN);//使能
GPIO_SetBits(D3_DIR,D3_GPIO_DIR);//正反转 顺时针
TIM_SetCompare1(TIM4,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP3()//逆时针
{
crc16_data3[0]=(0x03);
crc16_data3[1]=0x02;
// TIM4_PWM_Init(499,300); // 电机脉冲频率
GPIO_ResetBits( D3_EN,D3_GPIO_EN);//使能
GPIO_ResetBits(D3_DIR,D3_GPIO_DIR);//正反转 逆时针时针
TIM_SetCompare1(TIM4,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机4****************/
void PWM_DIANJICOROTATION4() // 顺时针
{
crc16_data4[0]|=(1<<2);
crc16_data4[1]=0x01;
//TIM5_PWM_Init(499,110);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_SetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺时针
TIM_SetCompare2(TIM5,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP4()//逆时针
{
crc16_data4[0]|=(1<<2);
#if 1
crc16_data4[1]=0x02;//输出当前正反转信息
#endif
//TIM5_PWM_Init(499,256);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_ResetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺
TIM_SetCompare2(TIM5,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机5****************/
void PWM_DIANJICOROTATION5() // 顺时针
{
crc16_data5[0]=(0x05);
crc16_data5[1]=0x01;
//TIM5_PWM_Init(499,110);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_SetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺时针
TIM_SetCompare2(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP5()//逆时针
{
crc16_data5[0]=(0x05);
#if 1
crc16_data5[1]=0x02;//输出当前正反转信息
#endif
//TIM5_PWM_Init(499,256);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_ResetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺
TIM_SetCompare2(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机6****************/
void PWM_DIANJICOROTATION6() // 顺时针
{
crc16_data6[0]=0x02;
crc16_data6[0]|=(1<<2);
crc16_data6[1]=0x01;
//TIM5_PWM_Init(499,110);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_SetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺时针
TIM_SetCompare3(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP6()//逆时针
{
crc16_data6[0]=0x02;
crc16_data6[0]|=(1<<2);
#if 1
crc16_data6[1]=0x02;//输出当前正反转信息
#endif
//TIM5_PWM_Init(499,256);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_ResetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺
TIM_SetCompare3(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机7****************/
void PWM_DIANJICOROTATION7() // 顺时针
{
crc16_data7[0]=0x02;
crc16_data7[0]|=(1<<2)|0x01;
crc16_data7[1]=0x01;
//TIM5_PWM_Init(499,110);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_SetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺时针
TIM_SetCompare4(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP7()//逆时针
{
crc16_data7[0]=0x02;
crc16_data7[0]|=(1<<2)|0x01;
#if 1
crc16_data7[1]=0x02;//输出当前正反转信息
#endif
//TIM5_PWM_Init(499,256);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_ResetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺
TIM_SetCompare4(TIM3,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机8****************/
void PWM_DIANJICOROTATION8() // 顺时针
{
crc16_data8[0]|=(1<<3);
crc16_data8[1]=0x01;
//TIM5_PWM_Init(499,110);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_SetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺时针
TIM_SetCompare2(TIM4,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP8()//逆时针
{
crc16_data8[0]|=(1<<3);
#if 1
crc16_data8[1]=0x02;//输出当前正反转信息
#endif
//TIM5_PWM_Init(499,256);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_ResetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺
TIM_SetCompare2(TIM4,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机9****************/
void PWM_DIANJICOROTATION9() // 顺时针
{
crc16_data9[0]|=(1<<3);
crc16_data9[0]|=0x01;
crc16_data9[1]=0x01;
//TIM5_PWM_Init(499,110);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_SetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺时针
TIM_SetCompare3(TIM4,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP9()//逆时针
{
crc16_data9[0]|=(1<<3);
crc16_data9[0]|=0x01;
#if 1
crc16_data8[1]=0x02;//输出当前正反转信息
#endif
//TIM5_PWM_Init(499,256);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_ResetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺
TIM_SetCompare3(TIM4,10); //占空比定义函数 PA1 TIM2_CH2
}
/***************电机10****************/
void PWM_DIANJICOROTATION10() // 顺时针
{
crc16_data10[0]|=(1<<3);
crc16_data10[0]|=0x02;
crc16_data10[1]=0x01;
//TIM5_PWM_Init(499,110);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_SetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺时针
TIM_SetCompare3(TIM5,10); //占空比定义函数 PA1 TIM2_CH2
}
void PWM_DIANJIFILP10()//逆时针
{
crc16_data10[0]|=(1<<3);
crc16_data10[0]|=0x02;
#if 1
crc16_data10[1]=0x02;//输出当前正反转信息
#endif
//TIM5_PWM_Init(499,256);
GPIO_ResetBits( D4_EN,D4_GPIO_EN);//使能
GPIO_ResetBits(D4_DIR,D4_GPIO_DIR);//正反转 顺
TIM_SetCompare3(TIM5,10); //占空比定义函数 PA1 TIM2_CH2
}
void jisuanjiaodu()
{
if(maic==1000)
{
// TIM_Cmd(TIM3, DISABLE); //使能TIM2
GPIO_SetBits( D2_EN,D2_GPIO_EN);//使能
// maic=0;
}
}
/************************************************
实验0:电机QUD 直接输出脉冲
************************************************/
/* GPI0_STEP GPI0_DIR GPIO_motornum STEP 引脚 ,GPIO_direction用于选择电机方向引脚,dir:0为逆1为顺,k为速度 最大为1000*/
void motor(GPIO_TypeDef* GPIOx_step,GPIO_TypeDef* GPIOx_dir, uint16_t GPIO_motornum, uint16_t GPIO_direction, unsigned int dir, unsigned int speed)
{
unsigned int i, steps;
steps = 200;
switch(dir)
{
case 1 : GPIO_SetBits(GPIOx_dir,GPIO_direction); break;
case 0 : GPIO_ResetBits(GPIOx_dir,GPIO_direction); break;
default : break;
}
for(i = 0;i < steps; i++)
{
GPIO_SetBits(GPIOx_step,GPIO_motornum);
delay_us(1); //周期1.3ms
GPIO_ResetBits(GPIOx_step,GPIO_motornum);
delay_us(1034-speed);//修改频率 周期数
}
}
void STOP()
{
if(checkdata[0]==0xAA)//急停
{
if(checkdata[1]==0X00)
{
Bit1 =2;
Bit2 =2;
Bit3 =2;
Bit4 =2;
GPIO_SetBits( D1_EN,D1_GPIO_EN);
GPIO_SetBits( D2_EN,D2_GPIO_EN);
GPIO_SetBits( D3_EN,D3_GPIO_EN);
GPIO_SetBits( D4_EN,D4_GPIO_EN);
}
}
}
void huiling()
{
if(checkdata[0]==0xAA)//回零点
{
if(checkdata[1]==0XBB)
{
SoftReset();//复位操作
}
}
}
#include "stm32f10x.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
#include "pwm.h"
#include "moto.h"
#include "exti.h"
#include "stdio.h"
#include "string.h"
#include "usart.h"
#include "guangdiankey.h"
//////////////////////////////////////////////////////////////////////////////////
//限位开关 修改为光电开关检测 两个光电同时进入圆盘的背面开始回初始位置
//////////////////////////////////////////////////////////////////////////////////
//
//添加调零按钮 进行校准零点
//
//按键初始化函数
void KEY_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTC,PORTE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//KEY0-KEY4 限位开关
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 检测低电平
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC 6,7,8 ,9
}
//按键处理函数
//返回按键值
//0,没有任何按键按下
//1,KEY1按下
//2,KEY2按下
//3,KEY3按下
//4,KEY4按下
u8 KEY_Scan(u8 mode)
{
if(KEY1==0)return KEY1_PRES;
else if(KEY2==0)return KEY2_PRES;
else if(KEY3==0)return KEY3_PRES;
else if(KEY4==0)return KEY4_PRES;
else return 0;// 无按键按下
}
/*************接光电开端当限位****************/
int flag1=0;//步骤标志位
int flag2=0;
int flag3=0;
int flag4=0;
int flag5=0;
int flag6=0;
int flag7=0;
int flag8=0;
int flag9=0;
int flag10=0;
void xianwei_huiling()
{
/****************检测1***********************/
//检测当两个限位都被遮挡是到达了零位点
if(flag1==0)//步骤1
{
PWM_DIANJICOROTATION1();// 顺时针
if((KEY1==0)&&(guangdiankaiguan1==1)) //步骤2 都检测到了遮挡 限位的光电黑色引脚遮挡为1 测速的光电白色引脚有遮挡为1黑色为0 无遮挡白色为0黑色为1(指示灯亮)
{
delay_ms(100);
if((KEY1==0)&&(guangdiankaiguan1==1)) //
{
flag1=1;//标志只进入一次
D1_COUNT=0;
}
}
}
/***********光电开关检测到了*************/
//进行旋转180回到初始位置
if(flag1==1)//标志只进入一次
{
//GPIO_ResetBits( GPIOC,GPIO_Pin_6);//给光电开关置0 下次不再进入步骤2
PWM_DIANJIFILP1();//2逆时针 回零点
if(D1_COUNT==47)//pb5
{
D1_COUNT=0;
GPIO_SetBits( D1_EN,D1_GPIO_EN);
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
flag1=2;
crc16_data1[1]=0x03;
}
}
/****************检测2***********************/
//检测当两个限位都被遮挡是到达了零位点
if(flag2==0)//步骤1
{
PWM_DIANJICOROTATION2();// 顺时针
if((KEY2==0)&&(guangdiankaiguan2==1)) //步骤2 都检测到了遮挡 限位的光电黑色引脚遮挡为1 白色为0 测速的光电白色引脚有遮挡为1黑色为0 无遮挡白色为0黑色为1(指示灯亮)
{
delay_ms(100);
if((KEY2==0)&&(guangdiankaiguan2==1)) //
{
flag2=1;//标志只进入一次
D2_COUNT=0;
}
}
}
/***********光电开关检测到了*************/
//进行旋转180回到初始位置
if(flag2==1)//标志只进入一次
{
//GPIO_ResetBits( GPIOC,GPIO_Pin_6);//给光电开关置0 下次不再进入步骤2
PWM_DIANJIFILP2();//2逆时针 回零点
if(D2_COUNT==47)//pb5
{
D2_COUNT=0;
GPIO_SetBits( D2_EN,D2_GPIO_EN);
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
flag2=2;
crc16_data2[1]=0x03;
}
}
/****************检测3***********************/
//检测当两个限位都被遮挡是到达了零位点
if(flag3==0)//步骤1
{
PWM_DIANJICOROTATION3();// 顺时针
if((KEY3==0)&&(guangdiankaiguan3==1)) //步骤2 都检测到了遮挡 限位的光电黑色引脚遮挡为1 测速的光电白色引脚有遮挡为1黑色为0 无遮挡白色为0黑色为1(指示灯亮)
{
delay_ms(100);
if((KEY3==0)&&(guangdiankaiguan3==1)) //
{
flag3=1;//标志只进入一次
D3_COUNT=0;
}
}
}
/***********光电开关检测到了*************/
//进行旋转180回到初始位置
if(flag3==1)//标志只进入一次
{
//GPIO_ResetBits( GPIOC,GPIO_Pin_6);//给光电开关置0 下次不再进入步骤2
PWM_DIANJIFILP3();//2逆时针 回零点
if(D3_COUNT==47)//pb5
{
D3_COUNT=0;
GPIO_SetBits( D3_EN,D3_GPIO_EN);
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
flag3=2;
crc16_data3[1]=0x03;
}
}
/****************检测4***********************/
//检测当两个限位都被遮挡是到达了零位点
if(flag4==0)//步骤1
{
PWM_DIANJICOROTATION4();// 顺时针
if((KEY4==0)&&(guangdiankaiguan4==1)) //步骤2 都检测到了遮挡 限位的光电黑色引脚遮挡为1 测速的光电白色引脚有遮挡为1黑色为0 无遮挡白色为0黑色为1(指示灯亮)
{
delay_ms(100);
if((KEY4==0)&&(guangdiankaiguan4==1)) //
{
flag4=1;//标志只进入一次
D4_COUNT=0;
}
}
}
/***********光电开关检测到了*************/
//进行旋转180回到初始位置
if(flag4==1)//标志只进入一次
{
//GPIO_ResetBits( GPIOC,GPIO_Pin_6);//给光电开关置0 下次不再进入步骤2
PWM_DIANJIFILP4();//2逆时针 回零点
if(D4_COUNT==47)//pb5
{
D4_COUNT=0;
GPIO_SetBits( D4_EN,D4_GPIO_EN);
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
flag4=2;
crc16_data4[1]=0x03;
}
}
}
/*************
限位开关在最左边
开机初始化先进行回零点的操作
旋转到最左边 检测到限位开关 然后向右旋转90度到达初始位置
**************/
int Bit1 =0;
int Bit2 =0;
int Bit3 =0;
int Bit4 =0;
int Bit4_1=0;
void go_zero()
{
/**********1**************/
if((KEY1==1)&&(Bit1==0))//上电初始化开始
{
//第一步 上电电机先向左转
PWM_DIANJICOROTATION1();//回零点 找限位
}else if(KEY1==0) //检测到光电开关为0
{
Bit1=1;//标志只进入一次
D1_COUNT=0;
PWM_DIANJIFILP1();//电机1逆时针
}
/********
限位开关在复位之后不再进入
if((KEY1==1)&&Bit1==0)//上电初始化开始
{
//第一步 上电电机先向左转
PWM_DIANJICOROTATION1();//回零点 找限位
}else if((KEY1==0)&&(Bit1==0))
{
Bit1=1;//标志只进入一次
D1_COUNT=0;
}
if(Bit1==1)//标志只进入一次
{ PWM_DIANJIFILP1();//电机1逆时针 回零点一直转
if(D1_COUNT==26)//PB5 直到旋转90°为止
{
D1_COUNT=0;//清零停止
GPIO_SetBits( D1_EN,D1_GPIO_EN);
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
Bit1=2;
crc16_data1[1]=0x03;//发送归零成功数据
}
}
********/
/*************2***********/
if((KEY2==1)&&Bit2==0)
{
PWM_DIANJICOROTATION2();// 顺时针
}else if(KEY2==0) //
{
Bit2=1;//标志只进入一次
D2_COUNT=0;
PWM_DIANJIFILP2();//2逆时针 回零点
}
/************3************/
if((KEY3==1)&&Bit3==0)
{
PWM_DIANJICOROTATION3();//回零点 顺时针
}else if(KEY3==0)
{
Bit3=1;//标志只进入一次
D3_COUNT=0;
PWM_DIANJIFILP3();//3逆时针
}
/************4************/
if((KEY4==1)&&Bit4==0)
{
PWM_DIANJICOROTATION4();//回零点 顺时针
}else if(KEY4==0)
{
Bit4=1;//标志只进入一次
D4_COUNT=0;
PWM_DIANJIFILP4();//4逆时针
}
if(Bit1==1)//标志只进入一次
{ if(D1_COUNT==48)//到达起点位置
{
D1_COUNT=0;
GPIO_SetBits( D1_EN,D1_GPIO_EN);
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
Bit1=2;
crc16_data1[1]=0x03;
}
}
else if(Bit2==1)//标志只进入一次
{ if(D2_COUNT==48)//pb5
{
D2_COUNT=0;
GPIO_SetBits( D2_EN,D2_GPIO_EN);
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
Bit2=2;
crc16_data2[1]=0x03;
}
}
else if(Bit3==1)//标志只进入一次
{ if(D3_COUNT==48)//pb5
{
D3_COUNT=0;
GPIO_SetBits( D3_EN,D3_GPIO_EN);
Bit3=2;
//memset(checkdata,0x00,sizeof(checkdata)); //数组清零
crc16_data3[1]=0x03;
}
}
else if(Bit4==1)//标志只进入一次
{ if(D4_COUNT==48)//pb5
{
D4_COUNT=0;
GPIO_SetBits( D4_EN,D4_GPIO_EN);
// memset(checkdata,0x00,sizeof(checkdata)); //数组清零
Bit4=2;
crc16_data4[1]=0x03;
}
}
}