代码如下,亲测可以,起始角度固定了,才能可以精确正反转角度哈,代码有注释
代码如下(示例):
#ifndef __REG52_H
#define __REG52_H
#include "sys.h"
//IN1-PB6
#define IN1_GPIO_PORT GPIOB
#define IN1_GPIO_CLK RCC_AHB1Periph_GPIOB
#define IN1_GPIO_PIN GPIO_Pin_6
//IN2-PB7
#define IN2_GPIO_PORT GPIOB
#define IN2_GPIO_CLK RCC_AHB1Periph_GPIOB
#define IN2_GPIO_PIN GPIO_Pin_7
//IN3-PB10
#define IN3_GPIO_PORT GPIOB
#define IN3_GPIO_CLK RCC_AHB1Periph_GPIOB
#define IN3_GPIO_PIN GPIO_Pin_10
//IN1-PB11
#define IN4_GPIO_PORT GPIOB
#define IN4_GPIO_CLK RCC_AHB1Periph_GPIOB
#define IN4_GPIO_PIN GPIO_Pin_11
#define digitalHi(p,i) {p->BSRRL=i;}
#define digitalLi(p,i) {p->BSRRH=i;}
#define IN1_HIGH digitalHi(IN1_GPIO_PORT,IN1_GPIO_PIN)
#define IN1_LOW digitalLi(IN1_GPIO_PORT,IN1_GPIO_PIN)
#define IN2_HIGH digitalHi(IN2_GPIO_PORT,IN2_GPIO_PIN)
#define IN2_LOW digitalLi(IN2_GPIO_PORT,IN2_GPIO_PIN)
#define IN3_HIGH digitalHi(IN3_GPIO_PORT,IN3_GPIO_PIN)
#define IN3_LOW digitalLi(IN3_GPIO_PORT,IN3_GPIO_PIN)
#define IN4_HIGH digitalHi(IN4_GPIO_PORT,IN4_GPIO_PIN)
#define IN4_LOW digitalLi(IN4_GPIO_PORT,IN4_GPIO_PIN)
/*
*单相绕组通电
*/
#define Coil_A {IN1_HIGH;IN2_LOW;IN3_LOW;IN4_LOW;}
#define Coil_B {IN1_LOW;IN2_HIGH;IN3_LOW;IN4_LOW;}
#define Coil_C {IN1_LOW;IN2_LOW;IN3_HIGH;IN4_LOW;}
#define Coil_D {IN1_LOW;IN2_LOW;IN3_LOW;IN4_HIGH;}
#define Stop {IN1_LOW;IN2_LOW;IN3_LOW;IN4_LOW;}
/*
*双相绕组通电
*/
#define Coil_1 {IN1_HIGH;IN2_LOW;IN3_LOW;IN4_HIGH;}
#define Coil_2 {IN1_HIGH;IN2_HIGH;IN3_LOW;IN4_LOW;}
#define Coil_3 {IN1_LOW;IN2_HIGH;IN3_HIGH;IN4_LOW;}
#define Coil_4 {IN1_LOW;IN2_LOW;IN3_HIGH;IN4_HIGH;}
/*
*正反转表格
*/
//uint16_t F_Rotating[4] = {0x0840 , 0x00c0, 0x0480, 0x0c00};
//uint16_t B_Rotating[4] = {0x0c00 , 0x0480, 0x00c0 ,0x0840};
#define Clockwise 1
#define UnClockwise 0
#define One_cir 4096
void GPIO_STEP_CONFIG(void);
#endif
#include "reg52.h"
/*
*一圈 == 4086个脉冲
*一个脉冲 == 0.08810573°
*45°=512个脉冲 90°=1024个脉冲
*/
void GPIO_STEP_CONFIG(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = IN1_GPIO_PIN|IN2_GPIO_PIN|IN3_GPIO_PIN|IN4_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
2.步进电机驱动程序
代码如下(示例):
//定时器4初始化
void Timer4_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM4,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*
*28BYJ-48
*步进电机驱动程序
*/
struct step
{
uint16_t angle;//记录旋转结束后角度
}stepper;
#define CLIP_ROT(V,MIN,MAX) ( ( V>MAX?MIN:(V<MIN?MAX:V) ) )
uint16_t Rotating[8] = {0x0040, 0x00c0, 0x0080, 0x0480, 0x0400, 0x0c00, 0x0800, 0x0840};//配置的引脚不同,旋转序列也不同欧
extern uint8_t rotate_dir_flg;
extern uint16_t pulse_number;
extern uint16_t angle_circle;
extern float Current_Position ;
int Rot = 0;
float cir_finish = 0;//步进电机旋转结束
void rotate_angle_dir(uint16_t angle,uint16_t circle,uint16_t dir)
{
if(cir_finish == 0)//旋转已经结束
{
cir_finish = 1;
if(dir == UnClockwise) //如果是反转
rotate_dir_flg = UnClockwise;
else if(dir == Clockwise) //如果是正转
rotate_dir_flg = Clockwise;
angle = CLIP_ROT(angle,0.0,360);//限制形参旋转角度范围
angle_circle = One_cir*circle + One_cir*angle/360;//由角度换算成,需要输出的脉冲个数
TIM_Cmd(TIM4,ENABLE);
}
}
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
cir_finish = 1;//进行旋转中
if(rotate_dir_flg == Clockwise)
{
Rot++;
Current_Position = (stepper.angle + ((pulse_number + 1) * 360/One_cir))%360;
}
else if(rotate_dir_flg == UnClockwise)
{
Rot--;
Current_Position =(stepper.angle + 360 - ((pulse_number + 1) * 360/One_cir))%360;//上次旋转角度 + 现在要旋转角度 = 计算当前位置
}
Rot = CLIP_ROT(Rot,0,7);
GPIOB->BSRRL = Rotating[Rot];
GPIOB->BSRRH = 0x0cc0 - Rotating[Rot];
if(++pulse_number > angle_circle-1) //单片机按Rotating[Rot]输出的脉冲个数已到
{
TIM_Cmd(TIM4,DISABLE);//关闭定时器4
Stop;//四个引脚输出低电平,避免不用时发热
pulse_number = 0;//脉冲计数数清零
cir_finish = 0;//旋转结束
stepper.angle = Current_Position;//记录当前旋转角度
}
LED0 = !LED0;
}
}
主函数如下:
uint8_t rotate_dir_flg = Clockwise;
uint16_t pulse_number = 0;
uint16_t angle_circle;
float Current_Position = 0.0;
uint8_t buf[50];
#define CLIP_ww(V,MIN,MAX) ( ( V>MAX?MIN:(V<MIN?MAX:V) ) )
int main(void)
{
delay_init(168);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
Timer4_Init(840-1,100-1);
LED_Init();
LCD_Init();
KEY_Init();
GPIO_STEP_CONFIG();
POINT_COLOR = RED;
while(1)
{
delay_ms(150);
if(KEY_Scan(0) ==KEY0)
{
rotate_angle_dir(90,0,UnClockwise);
}
else if(KEY_Scan(0) ==KEY1)
{
rotate_angle_dir(90,0,Clockwise);
}
sprintf((char *)buf,"curent angle: %.0f \r\n",Current_Position);
LCD_ShowString(20,200,200,16,16,buf);//显示当前角度
}
}
总结
额,不知道写啥,主要是方便自己后面需要代码了,程序找不到了,嘻嘻