本帖最后由 yin_wu_qing 于 2022-2-27 23:34 编辑
步进电机应用变得越来越广泛,常见有ATM机、喷绘机、刻字机、写真机、喷涂设备、医疗仪器及设备、计算机外设及海量存储设备、精密仪器、工业控制系统、办公自动化、机器人等领域。因此,今天来简单介绍一下,如何使用GD32L233C-START快速驱动五线四相步进电机。
步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点。使得在速度、位置等控制领域用步进电机来控制变的非常的简单。此次采用的是28BYJ48 5V步进电机,ULN2003驱动模块。
ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。ULN2003的每一对达林顿都串联一个2.7K的基极电阻,在5V的工作电压下它能与TTL和CMOS电路直接相连,可以直接处理原始需要标准逻辑缓冲器来处理的数据。ULN2003工作电压高,工作电流大,灌电流可达500mA,并且能够在关态时承受50V的电压,输出还可以在高负载电流并行运行。ULN2003采用DIP—16或SOP—16塑料封装。
步进电机模块的参考电路原理图如下:
根据步进电机模块实物上的丝印,很容易掌握与GD32L233C-START开发板的电路连线,由于开发板支持arduino接口,有5V供电接口。输入的四相引脚通过杜邦线与开发板上的PB6~PB9引脚相连接。在原OLED驱动工程项目中添加电机驱动代码。部分参考代码如下:
#include "28byz48.h"
#include "systick.h"
#include "gd32l23x_gpio.h"
#define uint unsigned int
//步进电机正反转数组1
uint16_t phasecw[4] ={0x0200,0x0100,0x0080,0x0040};// D-C-B-A
uint16_t phaseccw[4]={0x0040,0x0080,0x0100,0x0200};// A-B-C-D.
void Motorcw(uint speed)
{
uint8_t i=0;
for(i=0;i<4;i++)
{
gpio_port_write(GPIOB,phasecw);
delay_1ms(speed);
}
}
void Motorccw(int speed)
{
uint8_t i;
for(i=0;i<4;i++)
{
gpio_port_write(GPIOB,phaseccw);
delay_1ms(speed);
}
}
void MotorStop(void)
{
gpio_bit_set(GPIOB,0x0000);
}
//由于 *一个脉冲* *输出轴* 转0.08789度(电机实转0.08789*64=5.625度),即步进角为5.625度。
//则转完A-B-C-D为 *8个脉冲* ,即0.08789*8=0.70312度。若称A-B-C-D为一个周期,则j为需要的转完angle角度所需的周期数。
void Motorcw_angle(int angle,int speed)
{
int i,j;
j=(int)(angle/0.70312);
for(i=0;i<j;i++)
{
Motorcw(speed);
}
}
void Motorccw_angle(int angle,int speed)
{
int i,j;
j=(int)(angle/0.70312);
for(i=0;i<j;i++)
{
Motorccw(speed);
}
}
#include "gd32l23x.h"
#include "systick.h"
#include "oled.h"
#include "bmp.h"
#include "28byz48.h"
#define Time 100
#define oled_ms 600
int main(void)
{
systick_config();
/* enable the LED GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
/* configure LED GPIO pin */
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7 | GPIO_PIN_8);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8);
gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6 | GPIO_PIN_7);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9); //初始化步进电机
/* reset LED GPIO pin */
gpio_bit_reset(GPIOA, GPIO_PIN_7 | GPIO_PIN_8);
gpio_bit_reset(GPIOC, GPIO_PIN_6 | GPIO_PIN_7);
u8 t;
LED_Init();
OLED_Init();
OLED_Clear();
t=' ';
delay_1ms(oled_ms);
while(1)
{
/* turn on LED1, turn off LED4 */
gpio_bit_set(GPIOA, GPIO_PIN_7);
gpio_bit_reset(GPIOC, GPIO_PIN_7);
delay_1ms(Time);
/* turn on LED2, turn off LED1 */
gpio_bit_set(GPIOA, GPIO_PIN_8);
gpio_bit_reset(GPIOA, GPIO_PIN_7);
delay_1ms(Time);
/* turn on LED3, turn off LED2 */
gpio_bit_set(GPIOC, GPIO_PIN_6);
gpio_bit_reset(GPIOA, GPIO_PIN_8);
delay_1ms(Time);
/* turn on LED4, turn off LED3 */
gpio_bit_set(GPIOC, GPIO_PIN_7);
gpio_bit_reset(GPIOC, GPIO_PIN_6);
delay_1ms(Time);
/* turn on LED4, turn off LED3 */
gpio_bit_set(GPIOC, GPIO_PIN_7);
gpio_bit_reset(GPIOC, GPIO_PIN_6);
delay_1ms(Time);
/* turn on LED3, turn off LED4 */
gpio_bit_set(GPIOC, GPIO_PIN_6);
gpio_bit_reset(GPIOC, GPIO_PIN_7);
delay_1ms(Time);
/* turn on LED2, turn off LED3 */
gpio_bit_set(GPIOA, GPIO_PIN_8);
gpio_bit_reset(GPIOC, GPIO_PIN_6);
delay_1ms(Time);
/* turn on LED1, turn off LED2 */
gpio_bit_set(GPIOA, GPIO_PIN_7);
gpio_bit_reset(GPIOA, GPIO_PIN_8);
delay_1ms(Time);
OLED_Clear();
OLED_ShowCHinese(10,0,14);//北
OLED_ShowCHinese(18+10,0,15);//京
OLED_ShowCHinese(36+10,0,16);//兆
OLED_ShowCHinese(54+10,0,17);//易
OLED_ShowCHinese(72+10,0,18);//创
OLED_ShowCHinese(90+10,0,19);//新
OLED_ShowString(6,3,"GD32L233C-START",16);
delay_1ms(oled_ms);
OLED_Clear();
Motorcw_angle(20,6);
delay_1ms(Time);
delay_1ms(Time);
OLED_ShowString(9,0,"WelcomeEEWorld",16);
OLED_ShowString(6,3,"GD32L233C-START",16);
OLED_ShowChar(48,6,t,16);//显示ASCII字符
t++;
if(t>'~')t=' ';
OLED_ShowNum(103,6,t,3,16);//显示ASCII字符的码值
delay_1ms(oled_ms);
delay_1ms(oled_ms);
OLED_Clear();
OLED_DrawBMP(0,0,128,8,BMP1);
delay_1ms(oled_ms);
OLED_DrawBMP(0,0,128,8,BMP1);
delay_1ms(oled_ms);
Motorccw_angle(20,6);
delay_1ms(Time);
delay_1ms(Time);
}
}
编译完成后下载到开发板中,执行的效果如下:
此次只是简单地驱动了步进电机的正反转,但从代码中来分析,程序执行OLED屏驱动时,没有显示另外一段图片效果,而且完成一轮步进电机的正反转后,板上的LED灯可再次循环被点亮,OLED屏却不再显示,其中原由可有坛友知晓,欢迎留言讨论。
|