ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RISC-V MCU开发实战(四) :步进电机

2021-10-29 13:31:53  阅读:191  来源: 互联网

标签:函数 Pin 电机 RISC 步进 驱动 GPIO MCU


软件平台: MounRiver Studio(MRS),硬件平台: CH32V103开发板、ULN2003步进电机驱动板、28BYJ-48步进电机,使用GPIO进行步进电机控制。

1. ULN2003和28BYJ-48简介

ULN2003是高耐压、大电流复合晶体管阵列,由七个硅NPN 复合晶体管组成,每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据。

ULN2003是大电流驱动阵列,多用于单片机、智能仪表、PLC、数字量输出卡等控制电路中。可直接驱动继电器等负载。

输入5VTTL电平,输出可达500mA/50V。

ULN2003是高耐压、大电流达林顿系列,由七个硅NPN达林顿管组成。 该电路的特点如下: ULN2003的每一对达林顿都串联一个2.7K的基极电阻,在5V的工作电压下它能与TTL和CMOS电路 直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据。

关于步进电机,此处所用电机型号为28BYJ-48(步进电机),减速比为1:64,步进脚为5.625/64度,如果需要转动转动一圈,那么需要 360/5.625*64=4096 个脉冲信号。

步进电机是一种将电脉冲转化为角位移的执行设备。步进电机驱动信号为脉冲信号,当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(即步进角)。

我们可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时我们可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的

 

2.硬件连接

CH32V103开发板与ULN2003步进电机驱动板的连接方式如下:

PB6连接驱动板的IN1引脚

PB7连接驱动板的IN2引脚

PB8连接驱动板的IN3引脚

PB9连接驱动板的IN4引脚

 

3.MRS中开发流程

1)首先新建一个CH32V103C8T6 的工程,这个要与对应芯片对应

 

 

上图最下方红框中是对选中芯片的资源的简单介绍,方便查询

 

2) 新建完工程之后,我们打开main.c文件,可以看到主函数只是一些初始化和串口打印,我们自己的主函数逻辑可以添加在打印下面就可以了;

3) 新建一个hardware的文件夹,右键工程new->folder,填写文件名,点击finish即可,我们可以以同样的方式在hardware目录下再新建SD目录,SPI目录,条理清晰。

4) 在SPI目录下,New>Source File,填写文件名gpio.c,内容是电机初始化函数以及调速转向停止函数,在新建个gpio.h文件用来声明函数,这个新的头文件需要添加到头文件寻址路径中,点击菜单栏工程属性配置按钮,在弹出的页面中,如下图,点击绿色加号添加路径即可

 

 

 

驱动代码如下:

  1 #include "gpio.h"
  2 
  3 #include "debug.h"
  4 
  5  
  6 
  7 //#define N 4
  8 
  9 #define N 8
 10 
 11  
 12 
 13 //步进电机正反转数组  数组的值,即对应GPIO引脚的值
 14 
 15 //单四拍
 16 
 17 //uint16_t phasecw[4] ={0x0200,0x0100,0x0080,0x0040};// D-C-B-A.(9-8-7-6)
 18 
 19 //uint16_t phaseccw[4]={0x0040,0x0080,0x0100,0x0200};// A-B-C-D.(6-7-8-9)
 20 
 21  
 22 
 23 ////双四拍
 24 
 25 //uint16_t phasecw[4] ={0x0300,0x0180,0x00C0,0x0240};// DC-CB-BA-AD.
 26 
 27 //uint16_t phaseccw[4]={0x00C0,0x0180,0x0300,0x0240};// AB-BC-CD-DA.
 28 
 29  
 30 
 31 //四相八拍
 32 
 33 uint16_t phasecw[8] ={0x0200,0x0300,0x0100,0x0180,0x0080,0x00C0,0x0040,0x0240};// D-DC-C-CB-B-BA-A-AB.
 34 
 35 uint16_t phaseccw[8]={0x0040,0x00C0,0X0080,0x0180,0x0100,0x0300,0x0200,0x0240};// A-AB-B-BC-C-CD-D-DA.
 36 
 37  
 38 
 39 //电机初始化函数
 40 
 41 void Moto_Init(void)
 42 
 43 {
 44 
 45     //步进电机初始化
 46 
 47     // IN1: PB6   a
 48 
 49     // IN2: PB7   b
 50 
 51     // IN3: PB8   c
 52 
 53     // IN4: PB9   d
 54 
 55     GPIO_InitTypeDef GPIO_InitStructure;
 56 
 57     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
 58 
 59  
 60 
 61     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 ;
 62 
 63     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 64 
 65     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 66 
 67     GPIO_Init(GPIOB,&GPIO_InitStructure);
 68 
 69  
 70 
 71     GPIO_ResetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_9 );
 72 
 73 }
 74 
 75  
 76 
 77 //电机正转函数
 78 
 79 //其中,speed的值越大,速度越慢,值越小,速度越快,speed相当于调节脉冲速度
 80 
 81 //转动速度和脉冲频率成正比,在此处,延时越小,频率越高
 82 
 83 void Motorcw(u8 speed)
 84 
 85 {
 86 
 87     uint8_t i=0;
 88 
 89  
 90 
 91     for(i=0;i<N;i++)
 92 
 93     {
 94 
 95         GPIO_Write(GPIOB,phasecw[i]);
 96 
 97         Delay_Ms(speed);
 98 
 99     }
100 
101 }
102 
103  
104 
105 //电机反转函数
106 
107 void Motorccw(u8 speed)
108 
109 {
110 
111     uint8_t i;
112 
113     for(i=0;i<N;i++)
114 
115     {
116 
117         GPIO_Write(GPIOB,phaseccw[i]);
118 
119         Delay_Ms(speed);
120 
121     }
122 
123 }
124 
125  
126 
127 //电机停止函数
128 
129 void MotorStop(void)
130 
131 {
132 
133     //GPIO_ResetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_9 );
134 
135     GPIO_Write(GPIOB,0x0000);
136 
137 }
138 
139  
140 
141 //电机正转角度
142 
143 void Motorcw_angle(int angle,int speed)
144 
145 {
146 
147     int i,j;
148 
149     j=(int)(angle/0.70312);
150 
151     for(i=0;i<j;i++)
152 
153     {
154 
155         Motorcw(speed);
156 
157     }
158 
159 }
160 
161  
162 
163 //电机反转角度
164 
165 void Motorccw_angle(int angle,int speed)
166 
167 {
168 
169     int i,j;
170 
171     j=(int)(angle/0.70312);
172 
173     for(i=0;i<j;i++)
174 
175     {
176 
177         Motorccw(speed);
178 
179     }
180 
181 }

 

 

主函数可以调用我们驱动中的正反转函数来说实现想要的功能

 

int main(void)

{

 

    USART_Printf_Init(115200);

    Moto_Init();

    Delay_Init();

 

    printf("This is Stepper motor driver\r\n");

 

    Motorcw_angle(360,5);   //步进电机正转角度函数

    MotorStop();

    Delay_Ms(1000);

 

    Motorccw_angle(360,5);  //步进电机反转角度函数

    MotorStop();

    Delay_Ms(1000);

 

}

 

代码编辑完成,点击菜单栏编译按钮,在console窗口查看编译结果,无错误,就可以进入到调试去验证逻辑,点击菜单栏调试按钮,如果运行现象和理论不一致,可以通过左下角反汇编窗口,断点,外设寄存器,内核寄存器这几个窗口来配合查找逻辑BUG

 

 

 

 

 

 

小提示,当程序运行到 HardFault_Handler 函数,可以观察Rregister窗口的mepc,mtval,mcause三个寄存器,分别代表,进入硬件错误中断前的pc,cpu取到的值,以及进入异常的原因。

 

4.验证

将编译好的程序下载到开发版并复位,通过逻辑分析仪对这几个GPIO引脚进行波形采集,具体如下图。将开发板、步进电机驱动板、步进电机连接起来,可看到电机进行正反转。

 

 

标签:函数,Pin,电机,RISC,步进,驱动,GPIO,MCU
来源: https://www.cnblogs.com/mounriver/p/15480051.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有