沃pos機,stm32做PID算法控制減速直流電機

 新聞資訊  |   2023-04-10 09:12  |  投稿人:pos機之家

網上有很多關于沃pos機,stm32做PID算法控制減速直流電機的知識,也有很多人為大家解答關于沃pos機的問題,今天pos機之家(www.tonybus.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、沃pos機

沃pos機

本例程采用了HAL庫進行項目開發(主要使用軟件CubexMX和keil5),文章末尾會有代碼開源,歡迎各位對文章進行指正和探討。

基于PID的減速電機控制一、 硬件模塊與原理圖1、硬件組成

硬件組成:stm32f103c8t6最小系統板;0.96寸LED12864(I2C通訊模式);智能小車12v移動電源;25GA370直流減速電機(帶霍爾編碼器);JDY-31藍牙模塊;L298N電機驅動模塊;杜邦線若干;1個面包板;

圖片如下:

2、模塊分析1、L298N電機驅動模塊

1.模塊可驅動兩路直流電機,輸出A和B各接一直流電機即可;

2.若使用12V供電,將12V供電端口及GND接上電源正負即可,同時5V供電端可以作為最小系統板的輸入電源;

3.若不需要使用PWM調速,只需要控制電機正反轉,則邏輯A與B跳線帽插上即可,相當于始終使能;

4.若需要使用PWM調速,需將跳線帽拔起,將使能端接上單片機IO口。(定時器IO口,PWM輸出模式);

5.邏輯輸入四個端口IN1、IN2、IN3、IN4接單片機四個IO口,每兩個端口控制的一路電機。

溫馨提示: 特別不建議新手或者資金有限的情況下,使用電機驅動模塊直連成品開發板,很容易燒壞。

原因:(1) 由于電機的特性,電機在堵轉或者高負載下,電流會增大,可能會影響到單片機。(2)新手玩單片機可能出現短路等情況,很容易板子冒煙;

L298N的轉動邏輯圖:

2、0.96寸OLED(I2C通訊)

(1)目前市面主要分為OLED與LCD這2種屏幕;

(2)OLED自發光特性,LCD都要背光,而OLED不需要,因為它是自發光。這樣同樣的顯示,OLED效果要來得好一些;

(3)多種接口方式:6800,8080兩種并行接口方式,4線的穿行SPI接口,IIC接口方式(2線);

(4)不要接過高電壓,3.3V就可以正常工作了;

(5)OLED不足之處是做大之后成本較高。

本實驗采用了0.96寸OLED的屏幕(通訊方式IIC),4個接線柱(SCL,SDA,GND,VCC); IIC通訊實現方式: IIC(Inter-Integrated Circuit)總線是一種由 PHILIPS 公司開發的兩線式串行總線,用于連接微控制器及其外圍設備。它是由數據線 SDA 和時鐘 SCL 構成的串行總線,可發送和接收數據。高速 IIC 總線一般可達 400kbps 以上。

模擬IIC通訊:

I2C 是支持多從機的,也就是一個 I2C 控制器下可以掛多個 I2C 從設備,這些不同的 I2C從設備有不同的器件地址,這樣 I2C 主控制器就可以通過 I2C 設備的器件地址訪問指定的 I2C設備了。SDA 和SCL 這兩根線必須要接一個上拉電阻,一般是 4.7K。其余的 I2C 從器件都掛接到 SDA 和 SCL 這兩根線上,這樣就可以通過 SDA 和 SCL 這兩根線來訪問多個 I2C設備。

I2C 協議:(1)起始位;(2)停止位;(3)數據傳輸;(4)應答信號;(5)I2C 寫時序;(6)I2C 讀時序

I2C 寫時序:

1)、開始信號。

2)、發送 I2C 設備地址,每個 I2C 器件都有一個設備地址,通過發送具體的設備地址來決

定訪問哪個 I2C 器件。這是一個 8 位的數據,其中高 7 位是設備地址,最后 1 位是讀寫位,為

1 的話表示這是一個讀操作,為 0 的話表示這是一個寫操作。

3)、 I2C 器件地址后面跟著一個讀寫位,為 0 表示寫操作,為 1 表示讀操作。

4)、從機發送的 ACK 應答信號。

5)、重新發送開始信號。

6)、發送要寫寫入數據的寄存器地址。

7)、從機發送的 ACK 應答信號。

8)、發送要寫入寄存器的數據。

9)、從機發送的 ACK 應答信號。

10)、停止信號。

I2C 讀時序:

I2C 單字節讀時序比寫時序要復雜一點,讀時序分為 4 大步,第一步是發送設備地址,第二步是發送要讀取的寄存器地址,第三步重新發送設備地址,最后一步就是 I2C 從器件輸出要讀取的寄存器值,我們具體來看一下這幾步。

1)、主機發送起始信號。

2)、主機發送要讀取的 I2C 從設備地址。

3)、讀寫控制位,因為是向 I2C 從設備發送數據,因此是寫信號。

4)、從機發送的 ACK 應答信號。

5)、重新發送 START 信號。

6)、主機發送要讀取的寄存器地址。

7)、從機發送的 ACK 應答信號。

8)、重新發送 START 信號。

9)、重新發送要讀取的 I2C 從設備地址。

10)、讀寫控制位,這里是讀信號,表示接下來是從 I2C 從設備里面讀取數據。

11)、從機發送的 ACK 應答信號。

12)、從 I2C 器件里面讀取到的數據。

13)、主機發出 NO ACK 信號,表示讀取完成,不需要從機再發送 ACK 信號了。

14)、主機發出 STOP 信號,停止 I2C 通信。

3、JDY-31藍牙模塊

市場上藍牙模塊有很多,常見的JDY-xx,HC-xx等系列。其實看似高級的藍牙功能背后就是簡單的串口通訊;

USART 的全稱是 Universal Synchronous/Asynchronous Receiver/Transmitter,也就是同步/異步串行收發器。相比 UART 多了一個同步的功能,在硬件上體現出來的就是多了一條時鐘線。一般 USART 是可以作為 UART 使用的,也就是不使用其同步的功能。

串口通訊協議:

數據包:串口通訊的數據包由發送設備通過自身的TXD接口傳輸到接收設備得RXD接口,在協議層中規定了數據包的內容,具體包括起始位、主體數據(8位或9位)、校驗位以及停止位,通訊的雙方必須將數據包的格式約定一致才能正常收發數據。

具體如圖所示:

波特率:由于異步通信中沒有時鐘信號,所以接收雙方要約定好波特率,即每秒傳輸的碼元個數,以便對信號進行解碼,常見的波特率有4800、9600、115200等。STM32中波特率的設置通過串口初始化結構體來實現。

注意:MCU設置的波特率大小要與藍牙APP設置的大小一致!

4、6線減速電機(帶編碼器)模塊:

市面上電機有很多,常用的有步進電機,直流減速電機,伺服電機等等; 編碼器:用來測量電機轉速的儀器元件,常見的有:霍爾編碼器,光電編碼器等 電機的驅動原理很簡單,給電壓差即可使得電機轉動,調速則利用PWM調節發。

編碼器原理: 編碼器是一種將角位移或者角速度轉換成一串電數字脈沖的旋轉式傳感器。 編碼器工作原理: 霍爾編碼器是有霍爾馬盤和霍爾元件組成。霍爾馬盤是在一定直徑的圓板上等分的布置有不同的磁極?;魻栺R盤與電動機同軸,電動機旋轉時,霍爾元件檢測輸出若干脈沖信號,為判斷轉向,一般輸出兩組存在一定相位差的方波信號。

注意:通過判斷A與B相哪一位在前,即可判斷出正轉還是反轉

二、CubexMX設置

使用的MCU為stm32f103c8t6:

RCC:

SYS:

注意:Debug這里一定要設置成Serial Wire否則可能出現芯片自鎖

GPIO設置:

定時TIM2用來測速與測量正轉反轉(計數器模式)

定時3:PWM調節

I2C:

USART1:

之后按照自己習慣生成初始化文件

三、代碼

自動生成的:

需要自己編寫的:

I2C代碼:

#include "oled.h"#include "asc.h"#include "main.h"void WriteCmd(unsigned char I2C_Command)//??? {HAL_I2C_Mem_Write(&hi2c2,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT,&I2C_Command,1,100); }void WriteDat(unsigned char I2C_Data)//??? {HAL_I2C_Mem_Write(&hi2c2,OLED0561_ADD,DAT,I2C_MEMADD_SIZE_8bit,&I2C_Data,1,100); }void OLED_Init(void){HAL_Delay(100); //????????WriteCmd(0xAE); //display offWriteCmd(0x20);//Set Memory Addressing ModeWriteCmd(0x10);//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0);//Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8);//Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //???? 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panel} void OLED_SetPos(unsigned char x, unsigned char y) //???????{ WriteCmd(0xb0+y);WriteCmd(((x&0xf0)>>4)|0x10);WriteCmd((x&0x0f)|0x01);} void OLED_Fill(unsigned char fill_Data)//????{unsigned char m,n;for(m=0;m<8;m++){WriteCmd(0xb0+m);//page0-page1WriteCmd(0x00);//low column start addressWriteCmd(0x10);//high column start addressfor(n=0;n<128;n++){WriteDat(fill_Data);}}} void OLED_CLS(void)//??{OLED_Fill(0x00);} void OLED_ON(void){WriteCmd(0X8D); //?????WriteCmd(0X14); //?????WriteCmd(0XAF); //OLED??} void OLED_OFF(void){WriteCmd(0X8D); //?????WriteCmd(0X10); //?????WriteCmd(0XAE); //OLED??} // Parameters : x,y -- ?????(x:0~127, y:0~7); ch[] -- ???????; TextSize -- ????(1:6*8 ; 2:8*16)// Description : ??codetab.h??ASCII??,?6*8?8*16???void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize){unsigned char c = 0,i = 0,j = 0;switch(TextSize){case 1:{while(ch[j] != '\\0'){c = ch[j] - 32;if(x > 126){x = 0;y++;}OLED_SetPos(x,y);for(i=0;i<6;i++)WriteDat(F6x8[c][i]);x += 6;j++;}}break;case 2:{while(ch[j] != '\\0'){c = ch[j] - 32;if(x > 120){x = 0;y++;}OLED_SetPos(x,y);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i]);OLED_SetPos(x,y+1);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i+8]);x += 8;j++;}}break;}} // Parameters : x,y -- ?????(x:0~127, y:0~7); N:???.h????// Description : ??ASCII_8x16.h????,16*16??void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N){unsigned char wm=0;unsigned int adder=32*N;OLED_SetPos(x , y);for(wm = 0;wm < 16;wm++){WriteDat(F16x16[adder]);adder += 1;}OLED_SetPos(x,y + 1);for(wm = 0;wm < 16;wm++){WriteDat(F16x16[adder]);adder += 1;}} // ????????????????,????????“??——???——????”??????ascll.h?????(????)//???????:x:????? //y:???(??0-7) //begin:????????????????ascll.c??????? // num:????????// ????“??”,??????????????????0,1,???0,??????,??:x:0,y:2,begin:0,num:2void OLED_ShowCN_STR(u8 x , u8 y , u8 begin , u8 num){u8 i;for(i=0;i<num;i++){OLED_ShowCN(i*16+x,y,i+begin);} //OLED????} // Parameters : x0,y0 -- ?????(x0:0~127, y0:0~7); x1,y1 -- ?????(???)???(x1:1~128,y1:1~8)// Description : ??BMP??void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]){unsigned int j=0;unsigned char x,y; if(y1%8==0)y = y1/8; elsey = y1/8 + 1;for(y=y0;y<y1;y++){OLED_SetPos(x0,y); for(x=x0;x<x1;x++){WriteDat(BMP[j++]);}}} void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size){ unsigned char c=0,i=0;c=chr-' ';//???????if(x>128-1){x=0;y=y+2;}if(Char_Size ==16){OLED_SetPos(x,y);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i]);OLED_SetPos(x,y+1);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i+8]);}else {OLED_SetPos(x,y);for(i=0;i<6;i++)WriteDat(F6x8[c][i]);}}u32 oled_pow(u8 m,u8 n){u32 result=1; while(n--)result*=m; return result;}//??2???//x,y :???? //len :?????//size:????//mode:??0,????;1,????//num:??(0~4294967295); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2){ u8 t,temp;u8 enshow=0; for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1));if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x+(size2/2)*t,y,' ',size2);continue;}else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); }}

UART代碼:

#include "uart.h" uint8_t USART1_RX_BUF[USART1_REC_LEN];//????,??USART_REC_LEN???.uint16_t USART1_RX_STA=0;//??????//bit15:??????,bit14~0:??????????uint8_t USART1_NewData;//?????????1???????? extern int flag; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//????????{ if(huart ==&huart1) { if((USART1_RX_STA&0x8000)==0)//????? { if(USART1_NewData==0x5A)//????0x5A { USART1_RX_STA|=0x8000; //?????,?USART2_RX_STA??bit15(15?)?1 } else { USART1_RX_BUF[USART1_RX_STA&0X7FFF]=USART1_NewData; if(USART1_RX_BUF[1] == 0x01){flag = 2;} USART1_RX_STA++; //???????1 if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//??????,?????? } } HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1); }}

常規的編寫如上,但是本人的MCU存在問題,單片機并未接收到預設的數據。

所以,本人項目中采用了下方代碼:

#include "uart.h" uint8_t USART1_RX_BUF[USART1_REC_LEN];//????,??USART_REC_LEN???.uint16_t USART1_RX_STA=0;//??????//bit15:??????,bit14~0:??????????uint8_t USART1_NewData;//?????????1???????? extern int flag; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//????????{ if(huart ==&huart1) { USART1_RX_BUF[USART1_RX_STA&0X7FFF]=USART1_NewData; USART1_RX_STA++; //???????1 if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//??????,??????if(USART1_RX_BUF[USART1_RX_STA-4] == 0xA0){flag = 1;}if(USART1_RX_BUF[USART1_RX_STA-4] == 0x90){flag = 2;}if(USART1_RX_BUF[USART1_RX_STA-4] == 0xD0){flag = 3;}if(USART1_RX_BUF[USART1_RX_STA-4] == 0x88){flag = 4;}if(USART1_RX_BUF[USART1_RX_STA-4] == 0x48){flag = 5;} HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1); }}

如果大家自己使用的花,可以根據自己的藍牙APP寫這段程序,有問題歡迎留言

Motor代碼:

#include "motor.h" void MOTOR_GO(){__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,3000);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);} void MOTOR_BACK(){HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);} void MOTOR_STOP(){HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);} void MOTOR_UP(){__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,1);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);} void MOTOR_DOWN(){__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,400);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);}

PID:

PID算法:

PID分為位置型和增量型

增量型即通過 u(k)-u(k-1) 從而得出式子:

公式的第一部分是比例式 是為了讓值按一定比例達到目標值;

第二部分是積分值,正值,在計算的過程中往往會受到環境等一些其他因素的影響,導致值不能到達目標值;

第三部分是微分值,通常是負值,后一次偏差值往往小于前一次偏差值,目的是為了防止值增加過大,通常起一個阻礙的作用;

PID代碼:

#include "pid.h"#include "tim.h"#include "main.h"#include "math.h"#include "i2c.h"#include "oled.h" unsigned int MotorSpeed;//è???±?á?£?μ??úμ±?°×a?ùint SpeedTarget = 750;//??±ê×a?ùint MotorOutput;//μ??úê?3? //1.à?ó?TIM2????μ??ú×a?ù void GetMotorSpeed(void){//int CaptureNumber =(short)__HAL_TIM_GET_COUNTER(&htim2); //HAL?aoˉêy??????3?′?êy//////μ??ú×a?ù×a??Speed=1s?úμ???3?êy/44(ò?è|11??D?o?£?4±??μ·¨)/34???ù±è//int MotorSpeed=CaptureNumber*20/44/34*2*3.14*3;//OLED_ShowNum(40,0,MotorSpeed,4,16);////__HAL_TIM_GET_COUNTER(&htim2) = 0;//??êy?÷??á?int CaptureNumber =(short)__HAL_TIM_GET_COUNTER(&htim2); //???????__HAL_TIM_GET_COUNTER(&htim2) = 0;//int Speed=CaptureNumber*5/44/34*2*3.14*3; int Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2); if(Direction == 1){CaptureNumber -= 65535;}MotorSpeed=CaptureNumber;OLED_ShowNum(40,0,MotorSpeed,4,16);HAL_Delay(100);OLED_CLS();//__HAL_TIM_GET_COUNTER(&htim2) = 0;} //2.??á?ê?PID?????÷£¨PID3£??·??a????PIDoí??á?ê?PID£? int Error_Last,Error_Prev;//é?′??ó2?£?é?é?′??ó2?int Pwm_add,Pwm;//PWM??á?,PWM????±è int Kp = 5, Ki = 3, Kd = 1;//PID??·¨?μêy£???μ?ààDí£?D????????üá|ò?°?ê±?¨òé??Dí£??ò??*1024 int SpeedInnerControl(int Speed,int Target)//?ù?è?ú?·????{ int Error = Target - Speed;//?ó2? = ??±ê?ù?è - êμ?ê?ù?è Pwm_add = Kp * (Error - Error_Last) + //±èàyKi * Error +//?y·?Kd * (Error - 2.0f * Error_Last + Error_Prev);//?¢·? Pwm += Pwm_add;//ê?3?á?=?\xadê?á?+??á?Error_Prev = Error_Last;//±£′?é?é?′??ó2? Error_Last = Error;//±£′?é?′??ó2? if(Pwm > 4999) Pwm = 3000;//?T??é????T£?·à?1PWM3?3?á?3ì if(Pwm <-4999) Pwm =-3000; return Pwm;//·μ??ê?3??μ} //3.μ??ú×a?ùó?·??òμ?oˉêy£¨PID????£? void SetMotorVoltageAndDirection(int Pwm){ if(Pwm < 0)//è?1?PWMD?óú0 { HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); Pwm = (-Pwm);//PWM???üè??y?μ£?è?1??a?oêy£??±?óè?·′ __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, Pwm);//PWMμ÷?ù } else {HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, Pwm);//PWMμ÷?ù }} void ModePID(){ GetMotorSpeed(); MotorOutput = SpeedInnerControl(MotorSpeed,SpeedTarget); SetMotorVoltageAndDirection(MotorOutput);}

主函數代碼:

while (1) { switch(flag) { case(1):MOTOR_GO();break; case(2):MOTOR_BACK();break; case(3):MOTOR_STOP();break; case(4):MOTOR_UP();break; case(5):ModePID();break; default:break; } /* USER CODE END WHILE */if(flag != 5){int CaptureNumber =(short)__HAL_TIM_GET_COUNTER(&htim2); //???????__HAL_TIM_GET_COUNTER(&htim2) = 0;// int Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2); //μ??ú×a?ù×a??Speed=1s?úμ???3?êy/44(ò?è|11??D?o?£?4±??μ·¨)/34???ù±è//int Speed=CaptureNumber*5/44/34*2*3.14*3; int Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2); if(Direction == 1){CaptureNumber -= 65535;}int Speed=CaptureNumber; OLED_ShowNum(40,0,Speed,5,16);HAL_Delay(100);OLED_CLS();} int Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2); OLED_ShowCN_STR(0,0,0,3);// OLED_ShowNum(40,0,Speed,4,16);OLED_ShowStr(90,0,"cm/s",2);OLED_ShowCN_STR(0,3,3,2); if(Direction==0){OLED_ShowCN_STR(40,3,5,2);}if(Direction==1){OLED_ShowCN_STR(40,3,7,2);}//HAL_Delay(1000);//OLED_CLS(); /* USER CODE BEGIN 3 */ }

藍牙APP源代碼以及技術論文:鏈接:https://pan.baidu.com/s/1-rbicxuyLVCq6rglCWcJTg 提取碼:huzm

以上就是關于沃pos機,stm32做PID算法控制減速直流電機的知識,后面我們會繼續為大家整理關于沃pos機的知識,希望能夠幫助到大家!

轉發請帶上網址:http://www.tonybus.com/news/17016.html

你可能會喜歡:

版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 babsan@163.com 舉報,一經查實,本站將立刻刪除。