1. 程式人生 > 其它 >RISC-V MCU開發實戰(四) :步進電機

RISC-V 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引腳進行波形採集,具體如下圖。將開發板、步進電機驅動板、步進電機連線起來,可看到電機進行正反轉。