說明: 本例用PIC單片機控制帶感應器的直流無刷電機,通過調節RA0端口的可變電阻器可實現電機調速控制.由于當前版本PROTEUS不支持換向功能,連接RA1端口的SW1尚不能控制無刷電機的運行方向.
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- //-----------------------------------------------------------------
- // 名稱: 帶位置感應器的直流無刷電機PMW控制仿真
- //-----------------------------------------------------------------
- // 說明: 本例用PIC單片機控制帶感應器的直流無刷電機,通過調節RA0端口的
- // 可變電阻器可實現電機調速控制.
- // 由于當前版本PROTEUS不支持換向功能,連接RA1端口的SW1尚不能控制
- // 無刷電機的運行方向.
- //
- //-----------------------------------------------------------------
- #include <xc.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- #define _XTAL_FREQ 20000000UL //20MHz
- #define BLDC_StopMask 0B11010101 //關閉電機的掩碼(高邊設為全0)
- #define BLDC_DrivePort PORTC //無刷直流電機驅動方向控制端口(6位)
- #define BLDC_DrivePortTris TRISC //無刷直流電機驅動方向控制端口方向設置
- #define BLDC_Direction RA1 //無刷直流電機當前方向檢測位
- #define BLDC_SensorPORT PORTE //無刷直流電機感應器輸入端口
- #define BLDC_SensorTRIS TRISE //無刷直流電機感應器輸入端口方向寄存器
- volatile INT8U ADC_Result; //控制PWM的AN0通道A/D轉換數據
- volatile INT8U DriveByte; //電機驅動字節(低6位有效)
- //-----------------------------------------------------------------
- // 驅動表設置(更詳細說明可參閱本書相關章節)
- //-----------------------------------------------------------------
- //1.6個驅動器共為3對,每2個為一對
- //2.每一對驅動線由一個高邊和一個低邊構成
- //3.三個驅動器對應于三個電機繞組A,B,C
- //4.繞組 A 由RC[1..0]兩位驅動,其中RC1是 A 繞組的高邊
- //5.繞組 B 由RC[3..2]兩位驅動,其中RC3是 B 繞組的高邊
- //6.繞組 C 由RC[5..4]兩位驅動,其中RC5是 C 繞組的高邊
- //7.三個感應器位構成了驅動表的偏移地址,感應器位[0..2]分別對應于繞組A,B,C
- //正向驅動數據表,第1-6字節對應于相位6,4,5,2,1,3的驅動位,各字節中僅低6位有效
- //驅動表中第0,7兩字節無效
- const INT8U FwdTable[] =
- {
- };
- //反向驅動數據表,第1-6字節對應于相位/6,/4,/5,/2,/1,/3的驅動位,0,7兩字節無效
- //表中每個字節后6位中,相鄰兩位為一組,與上表的差別是每組中的兩位顛倒
- const INT8U RevTable[] =
- {
- };
- //-----------------------------------------------------------------
- // 換向控制
- //-----------------------------------------------------------------
- void Get_Drive_Byte()
- {
- //讀取PORTE端口輸入的感應器當前數據(三位)
- INT8U CurrentSensor = PORTE & 0B00000111;
- //根據RA1端口的方向位及當前位置感應器輸出,從正向或反向驅動表中讀取驅動字節
- if (BLDC_Direction == 0)
- DriveByte = FwdTable[CurrentSensor];
- else
- DriveByte = RevTable[CurrentSensor];
- }
- //-----------------------------------------------------------------
- // 初始化程序
- //-----------------------------------------------------------------
- void Initialize()
- {
- Get_Drive_Byte(); //根據當前電機位置取得驅動字節
- ADC_Result= 0x00; //初始速度控制值為0
- BLDC_DrivePort = 0x00; //關閉BLDC驅動端口
- BLDC_DrivePortTris = 0x00; //BLDC驅動方向端口設為輸出
- BLDC_SensorTRIS = 0xFF; //無刷直流電機感應器端口設為輸入
- TRISA = 0B00000011; //AN0為模擬量輸入,RA1為電機方向控制
- T0CS = 0; //TMR0時鐘選擇:內部時鐘
- PSA = 0; //前分頻器分配給TMR0
- PS2 = 1; PS1 = 1; PS0 = 1; //256分頻(OPTION低3位為111,4M,256us)
- ADCON1 = 0B00001110; //A/D轉換結果左對齊,AN0為模擬端口,其余為數字端口
- ADCON0 = 0B11000001; //A/D時鐘源:RC,ADON置位,使能A/D模塊
- GO_nDONE = 1; //啟動ADC
- }
- //-----------------------------------------------------------------
- // 讀取A/D轉換結果的高8位
- //-----------------------------------------------------------------
- void ReadADC()
- {
- //如果模/數轉換已經就緒則讀取速度控制值并重新啟ADC,以便讀取一次ADC結果
- if (GO_nDONE) return;
- ADC_Result = ADRESH; //讀取A/D結果的高8位
- GO_nDONE = 1; //重啟A/D模塊
- }
- //-----------------------------------------------------------------
- // 主程序
- //-----------------------------------------------------------------
- void main()
- {
- Initialize();
- while (1)
- {
- ReadADC();//從模/數轉換端口讀取速度控制值
- //如果A/D轉換值為最大值則電機全速運行,否則調節PWM
- //占空比 = ADC_Result / 255
- if (ADC_Result != 0xFF)
- {
- if (TMR0 + ADC_Result <= 0xFF) DriveByte &= BLDC_StopMask;
- }
- //發送電機驅動字節(6位),驅動電機運行
- BLDC_DrivePort = DriveByte;
- //根據電機位置感應器輸出的當前位置取得新的驅動字節
- Get_Drive_Byte();
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
帶位置感應器的直流無刷電機PMW控制仿真.rar
(64.17 KB, 下載次數: 228)
2017-11-13 20:17 上傳
點擊文件名下載附件
|