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

2021-10-29 14:26 2345 13 4 分类: MCU/ 嵌入式 文集: RISC-V MCU开发
软件平台: MounRiver Studio(MRS),硬件平台: CH32V103开发板、ULN2003步进电机驱动板、28BYJ-48步进电机,使用GPIO进行步进电机控制。

1.    ULN200328BYJ-48简介

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

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

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

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

关于步进电机,此处所用电机型号为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. #include "debug.h"
  3. //#define N 4
  4. #define N 8
  5. //步进电机正反转数组 数组的值,即对应GPIO引脚的值
  6. //单四拍
  7. //uint16_t phasecw[4] ={0x0200,0x0100,0x0080,0x0040};// D-C-B-A.(9-8-7-6)
  8. //uint16_t phaseccw[4]={0x0040,0x0080,0x0100,0x0200};// A-B-C-D.(6-7-8-9)
  9. ////双四拍
  10. //uint16_t phasecw[4] ={0x0300,0x0180,0x00C0,0x0240};// DC-CB-BA-AD.
  11. //uint16_t phaseccw[4]={0x00C0,0x0180,0x0300,0x0240};// AB-BC-CD-DA.
  12. //四相八拍
  13. uint16_t phasecw[8] ={0x0200,0x0300,0x0100,0x0180,0x0080,0x00C0,0x0040,0x0240};// D-DC-C-CB-B-BA-A-AB.
  14. uint16_t phaseccw[8]={0x0040,0x00C0,0X0080,0x0180,0x0100,0x0300,0x0200,0x0240};// A-AB-B-BC-C-CD-D-DA.
  15. //电机初始化函数
  16. void Moto_Init(void)
  17. {
  18. //步进电机初始化
  19. // IN1: PB6 a
  20. // IN2: PB7 b
  21. // IN3: PB8 c
  22. // IN4: PB9 d
  23. GPIO_InitTypeDef GPIO_InitStructure;
  24. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  25. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 ;
  26. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  27. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  28. GPIO_Init(GPIOB,&GPIO_InitStructure);
  29. GPIO_ResetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_9 );
  30. }
  31. //电机正转函数
  32. //其中,speed的值越大,速度越慢,值越小,速度越快,speed相当于调节脉冲速度
  33. //转动速度和脉冲频率成正比,在此处,延时越小,频率越高
  34. void Motorcw(u8 speed)
  35. {
  36. uint8_t i=0;
  37. for(i=0;i<N;i++)
  38. {
  39. GPIO_Write(GPIOB,phasecw[i]);
  40. Delay_Ms(speed);
  41. }
  42. }
  43. //电机反转函数
  44. void Motorccw(u8 speed)
  45. {
  46. uint8_t i;
  47. for(i=0;i<N;i++)
  48. {
  49. GPIO_Write(GPIOB,phaseccw[i]);
  50. Delay_Ms(speed);
  51. }
  52. }
  53. //电机停止函数
  54. void MotorStop(void)
  55. {
  56. //GPIO_ResetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_9 );
  57. GPIO_Write(GPIOB,0x0000);
  58. }
  59. //电机正转角度
  60. void Motorcw_angle(int angle,int speed)
  61. {
  62. int i,j;
  63. j=(int)(angle/0.70312);
  64. for(i=0;i<j;i++)
  65. {
  66. Motorcw(speed);
  67. }
  68. }
  69. //电机反转角度
  70. void Motorccw_angle(int angle,int speed)
  71. {
  72. int i,j;
  73. j=(int)(angle/0.70312);
  74. for(i=0;i<j;i++)
  75. {
  76. Motorccw(speed);
  77. }
  78. }

 

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

 

  1. int main(void)
  2. {
  3. USART_Printf_Init(115200);
  4. Moto_Init();
  5. Delay_Init();
  6. printf("This is Stepper motor driver\r\n");
  7. Motorcw_angle(360,5); //步进电机正转角度函数
  8. MotorStop();
  9. Delay_Ms(1000);
  10. Motorccw_angle(360,5); //步进电机反转角度函数
  11. MotorStop();
  12. Delay_Ms(1000);
  13. }

 

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





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

 

4.      验证

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


文章评论2条评论)

登录后参与讨论

yzw92 2021-10-31 08:59

谢谢分享

curton 2021-10-30 15:58

学习了
相关推荐阅读
EeterRV 2022-12-06 15:03
RISC-V IDE MRS使用笔记(六):新建文件时使用自定义文件头
MRS新建文件时,用户可以选择创建空白文件,也可以使用预置的自定义文件模板来新建对应格式的文件。同时,用户还可自由配置不同文件模板的详细内容,并支持导入、导出包含模板详细内容的配置文件。 【从模板新...
EeterRV 2022-10-19 10:47
RSIC-V IDE MRS使用笔记(五):调试前代码擦除问题
【代码页擦】在调试IAP+APP的程序时,一般IAP的程序固定后就不需要再去调试了,只需要关注APP程序本身就可以了,但是直接调试APP的时候会默认使用全擦指令,导致IAP程序被擦除。这个时候我们只需...
EeterRV 2022-10-18 10:19
RISC-V IDE MounRive Studio V182更新点速览(二):工作空间切换
MRS作为基于Eclipse平台开发的RISC-V MCU集成开发环境,在保留原有平台工作空间概念的同时,还针对广大非Eclipse用户的嵌入式开发者使用习惯,对其进行了一系列的“本土化”与“自动化改...
EeterRV 2022-10-17 16:50
RISC-V IDE MounRive Studio V182更新点速览(一):目标文件内存分析
近日,RISC-V IDE MRS发布了最新的 V182版本。本文让我们一起来关注MRS最新增加的目标输出文件内存分析功能! 首先是功能入口:主菜单Project->Analysis After Bu...
EeterRV 2021-12-16 15:18
RISC-V MCU IDE MRS(MounRiver Studio)开发之: 解决编译后显示RAM占用率100%的问题
上一篇文章中,我们一同学习了“如何开启编程后打印FLASH以及RAM占用信息”的功能,但是在实际开发中,尽管我们的程序并未使用到全部的RAM空间,但仍存在IDE中该打印信息提示RAM占用达到100%的...
EeterRV 2021-12-15 16:07
RISC-V MCU IDE MRS(MounRiver Studio)开发之: 编译后打印FLASH及RAM使用占比信息
在嵌入式开发中,我们有时需要在编译结束后查看目标芯片FLASH及RAM区使用占比情况,而大部分IDE是默认关闭该功能的,此时我们可以通过以下步骤来手动来开启:   以RISC-V MCU...
我要评论
2
13
关闭 站长推荐上一条 /2 下一条