背景:一個項目需要完成一個工件表面粗糙度的測量系統,該系統的驅動方式是雙路的步進電機,分別驅動X軸和Y軸的工作太移動,以完成粗糙度的測量。
硬件介紹:
主控:STM32F103C8T6
電源:CJ7805 + AMX1117
電機:42步進電機
驅動:DRV8825模塊*2
通信:USART
采樣:STM32內置ADC
調試:SWN接口
驅動器功能:
1、雙路步進電機驅動(兼容A4988以及DRV8825模塊)(為了制作方便可靠,該項目中,我選擇使用購買的驅動模塊,而省略了驅動芯片的外圍電路的設計)
2、串口通信(由於項目中需要該測量系統與上位機通信,並且實時顯示工件粗糙度的測量結果,因此這里采用了串口通信的方式,上位機采用Qt編寫,通信已經調通)
3、傳感器接口(STM32內置ADC測量電壓,該項目中的傳感器是一個電感傳感器,傳感器信號經過一系列模擬電路的處理,轉化成可以直徑進行ADC采樣的電壓信號)
驅動器原理圖:(工程采用AD完成)
驅動器PCB三維圖:
軟件部分代碼邏輯:
程序共有三個任務,三個任務並行工作:
由於是開環控制的步進電機,故采用時間作為位移的基准。
同時,由於沒有位置編碼器,為了讓上位機知道電機的位置,在每次向上位機發送傳感器數據的同時,也將時間信息同時發送,達到下位機與上位機的時間統一,從而使上位機獲得工作台的實時位置。
串口發送部分代碼:(包括發送時間基准)
1 void upper_send(void) 2 { 3 uint16_t senser_voltage_100 = 0; 4 5 //header 6 upper_send_buffer[0] = 0xAA; 7 8 //time(low byte in front) 9 upper_send_buffer[1] = (uint8_t)syscnt; 10 upper_send_buffer[2] = (uint8_t)(syscnt>>8); 11 upper_send_buffer[3] = (uint8_t)(syscnt>>16); 12 upper_send_buffer[4] = (uint8_t)(syscnt>>24); 13 14 //content(low byte in front) 15 senser_voltage_100 = (uint16_t)(adc_voltage * 100); 16 upper_send_buffer[5] = (uint8_t)senser_voltage_100; 17 upper_send_buffer[6] = (uint8_t)senser_voltage_100>>8; 18 19 //ending 20 upper_send_buffer[7] = 0xBB; 21 22 for(uint8_t i=0;i<=7;i++) 23 { 24 USART_SendData(USART1,upper_send_buffer[i]); 25 26 while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET); 27 } 28 }
軟件部分實現思路:
1、使用STM32的TIM1獲得系統時間
2、在TIM1的溢出中斷中實現任務的調度(可以方便設定各個任務的調度頻率)
3、使用TIM3生成兩個步進電機的驅動信號(驅動信號為1KHz的方波,32細分)
4、使用STM32的內置ADC1結合DMA采樣電壓
5、使用USART1實現與上位機通信(串口接收中斷處理上位機命令)
工程github地址:(硬件+軟件)
https://github.com/W-yt/Stepper-driver