感謝電源網給我們提供這樣一個平臺,下面介紹一下我的畢設作品設計主要設計要求
主要指標:
1.對于無刷直流電機進行實物仿真搭建并通過模擬控制器采集主要參數信息
2.模擬控制器能夠將數據傳輸出去并在主控面板上實時顯示
3.主控制器和模擬控制可以進行數據傳輸,數據傳輸模式不限
4.主控制模塊實現對采樣數據的處理并顯示
5.當電動自行車電機失壓、負載過輕、超額定轉速后控制器執行相應動作并讓模擬器執行相應機構
下附原理圖
介紹一下電動自行車無刷直流電機仿真采樣的硬件電路和具體實施方案
1.本系統需要對汽車車載三相發電機的電壓、電流以及轉速進行實時在線采集。針對此系統三相交流電壓的采集,可通過DL-PT202G型電壓互感器將電壓變為低壓可測的范圍之內,將電壓互感器二次側得到的電壓經過整流橋以及電解電容的整流濾波之后輸出一個脈動較小的直流電壓,這個直流電壓由于在0~5V可被STC12C5A60S2單片機AD采樣模塊準確檢測到。
2.針對此系統電流的采樣,采用微電阻壓降放大的間接采樣法,主要原因是因為STC12C5A60S2單片機AD采樣模只識別電壓信號不識別電流等其他類型的信號。其具體做法是在系統主功率回路中串入一個阻值較小的康銅絲或者水泥電阻,在功率電流流向這個阻值較小的電阻時會產生一個微小的壓降,通過類似LM358之類的運算放大器將其電壓放大再送至STC12C5A60S2單片機AD采樣模塊,來實現對系統主回路電流的測量。
3.針對此系統汽車三相交流發電機的轉速測量,在考慮到安裝體積以及其他綜合因素情況之下,本次采集選用電機碼輪以及以LM393為核心的光電門檢測模塊作為檢測發電機轉速的傳感器,通過間接測量光電門測速模塊的下降沿頻率來進一步測出發電機的轉速。
總體設計方案
本系統利用DL-PT202G型電壓互感器作為電動自行車電機電壓采樣傳感器,采用碼盤和基于寬電壓比較器LM393的電機測速模塊來實現對電機速度的測量。保護電路采用JQC-3F(T73)5VDC型繼電器作為保護器件。顯示報警電路由液晶顯示屏LCD1604、LED發光二極管和有源蜂鳴器組成。模擬控制模塊擬采用STC12C5A60S2作為電壓調節電路的主控核心芯片并將采樣回來的電機、電壓、電流和速度參數進行數字化處理通過異步串口通信發送給主控制器。主控制電路核心控制芯片采用PIC18F2580單片機,通過PIC18F2580單片機將采樣值進行處理并發出相應執行命令給相應被控元件。由于本系統需要模擬發電機以及要求負載三相相對對稱的特殊性,現采用A2212無刷直流電機模擬電動自行車電機,通過簡易電子負載電路實現負載的三相對稱要求。
電子負載電路通過三相全橋整流電路和濾波電路將三相交流電壓轉化為直流電壓,通過簡易負載電路調節一路負載便可實現三相電流的均衡調節。
模擬電子負載電路是下圖
保護電路是由JQC-3F(T73)5VDC型繼電器作為主要器件構成的,繼電器在高壓高功率場合下可起到對控制回路以及單片機之間的隔離和驅動保護,其在125V交流電壓條件下可承受10A的電流、在240V交流電壓條件下可承受7A的電流,可滿足本次畢業設計的需求。
下圖保護電路
顯示模塊采用lcd1604,用法和1602類似但是比之前多了倆行
原理圖如下
報警電路采用有源蜂鳴器來作為主要報警器件,有源蜂鳴器配合一個NPN型三極管實現了單片機控制電路與蜂鳴器電路的隔離,等效增大了單片機的驅動能力。值得一提是單片機I/O接口與三極管基極之間一般需要增設一個1K左右的電阻,否則基極電流過大會影響單片機的正常工作。這主要是由于單片機I/O輸出口灌電流比較弱的原因驅動不了較大負載,這也是在單片機和有源蜂鳴器之間需要三極管的主要原因。另外在此基礎上加了綠、藍、紅色三路指示燈,所選LED發光二極管由于通過電流較分別在電小可用單片機直接進行控制。報警電路如圖所示。
實物如下
掉電儲存模塊
AT24C02作為掉電記憶8端口芯片,有2048bit的記憶容量。其可通過端口A0、A1、A2三個電平狀態檢測引腳組合成8種地址,可以讓模擬電壓調節模塊最大識別8個AT24C02芯片。AT24C02記憶芯片通過IIC總線通信協議與模擬電壓調節器進行同步通信,其供電電源可由系統輔助電源模塊的5V供電。AT24C02外圍電路電路如圖所示。
通信選擇選異步串口通信主要是由于異步串口通信建立過程簡便便于實施
核心:串口通信
串口通信的硬件聯調,
介于對系統參數采樣穩定的要求,本系統采用9600bps波特率的串口通信速率,最大可傳輸76米的直線距離。硬件需要外接11.0592MHz的外部無源晶振,由于無源晶振需要起振電容,故選30pF的瓷片電容作為起振電容。由于模擬電壓調節器內部沒有專用波特率生成的寄存器,因此,需要通過軟件算法配置T1定時器和TMOD寄存器。
終端控制器主要是由PIC18F2580單片機組成,由于終端控制器僅有一個異步串口通信接口引腳,因此其終端控制器的工作僅負責對模擬電壓調節器的信號進行處理,并控制顯示和發出控制命令。終端控制器有內部自帶的增強型USART模塊,增強型USART的操作主要由三個寄存器控制,分別是傳輸狀態和控制寄存器、接收狀態和控制寄存器、波特率控制寄存器。EUSART串口控件將根據需要自動將引腳從輸入端配置到輸出端。
這是數據采樣的程序
#include#include #include #define uint unsigned int #define uchar unsigned char #define ADC_FLAG 0X10 #define VCC 220 uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,}; //數碼管位選碼 uchar code SMGwei[] = {0xfe, 0xfd, 0xfb}; unsigned char pdata bufRxd[64]; //接收字節緩沖區 /***********************延時函數*******************************/ void delay(uint z) { uint x,y; for(x = z; x > 0; x--) for(y = 114; y > 0 ; y--); } /************************采用器初始化******************************/ void InitADC(void) { P1M1=0xff; //1^012開啟高阻態 P1M0=0x00; //其余端口當普通端口使用 P1ASF=0Xff; //P^1 DC_V ADC_RES=0; ADC_CONTR=0X80; //1000 0000 開電源,最低速 delay(50); } /**************************采樣函數******************************/ uint GetADC(uchar ch) { uint result=0; ADC_CONTR=0x88|ch; //選擇通道 開始AD轉換e8 ADC最快,88,ADC最慢 _nop_(); _nop_(); _nop_(); _nop_(); while(!(ADC_CONTR&ADC_FLAG)); //查詢ADC_FLOG是否置位1 轉換結束 ADC_CONTR&=!ADC_FLAG; //清除ADC中斷標志 result=ADC_RES; //(ADC_RES<<2)+ADC_RESL (<<2)+ADC_RESL; aa[ss++]= ADC_RES; if(ss==6)ss=2; return(result); } /**********************定時器0初始化****************************/ void timer0Init() { EA = 1; //打開總中斷 ET0 = 1;//打開定時器0中斷 TR0 = 1; //啟動定時器0 REN = 1;//允許串口接收 TMOD |= 0X01; //定時器工作模式1,16位定時模式 TH0 = 0xED; TL0 = 0xFF; //定時5ms } /***********************串口初始化*********************************/ void UARTInit() { EA = 1; //打開總中斷 ES = 1; //打開串口中斷 SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可變 } void main()//main函數自身會循環 { InitADC(); //采樣初始化 timer0Init();//定時器0初始化 UARTInit();//串口初始化 bb=0; while(mode) { } } while(mode==0) { EA=0; //關總中斷 bb=0; while(sw_up==1&sw_down==1&sw_mune0==1&sw_mune1==1&sw_mune2==1)if(mode)break; if(sw_mune1==0) aa[9]=4; if(sw_mune2==0) aa[9]=5; while(sw_up==0|sw_down==0|sw_mune0==0|sw_mune1==0|sw_mune2==0)if(mode)break; if(mode)break; else EA=1; //開總中斷 delay(300); } } /****************************串口通信中斷*****************************/ void UART() interrupt 4 { SBUF=0xff; if(TI)//判斷是否發送完成 { bb++; if(bb>=10&&aa[9]==0xff) { bb=0; delay(1000); } } if(RI==1)//判斷接收是否完成 { int nu; nu =SBUF ;//讀SBUF,讀出串口接收到的數據 //第0號數據不是幀頭,跳過 switch(nu) { case 1:{LED2=1;LED1=0;LED0=1;wmq=0;JDQ=0;}break; //過壓 case 2:{LED2=1;LED1=0;LED0=1;wmq=0;JDQ=0;}break; //過流 case 3:{LED2=0;LED1=1;LED0=1;wmq=1;JDQ=1;}break; //低速 case 0:{LED2=1;LED1=1;LED0=0;wmq=1;JDQ=1;}break; //正常 } RI = 0;//軟件清零接收標志位 cc++; if(cc==1)cc=0; } }
這是終端做顯示,控制功能的程序 #include#include "pic18.h" /* PIC18系列的頭文件 */ #define MAIN_Fosc 22118400L //定義主時鐘 #define e RC5 //LCD使能IO #define rs RC3 //LCD寫數據或命令控制IO #define rw RC4 //LCD讀寫控制IO #define AT24C02_ADDR 0xa0 //AT24C02地址 #define PCF8591_ADDR 0x90 //PCF8591地址 #define VCC 500 unsigned char CXPOS; //列方向地址指針(用于CHARLCDPOS子程序) unsigned char CYPOS; //行方向地址指針(用于CHARLCDPOS子程序) unsigned char receive232[10]={0xfc,0xfc,3,4,5,6,7,8}; /* 接收數據數組 */ unsigned char send232[10]={0xfc,0xfc,3,4,5,6,7,8}; /* 發送數據數組 */ unsigned char receive_count=0; /* 接收數據個數計數 */ unsigned char send_count=1; /* 發送數據個數計數 */ unsigned char *pointer; /* 發送數據指針 */ unsigned char i; /* 程序中用到的循環變量 */ unsigned char SciReceiveFlag; /* =1,接收到8個數據 */ unsigned char Send_Mode=1; /* 不為0,中斷方式發送;=0,非中斷方式發送 */ //#define key RC0 typedef unsigned char uchar; typedef unsigned int uint; //------變量定義 uchar nu[6]={34,06,52,44,66,66,} ; uchar aa[11]; //數字量接收數組 uchar aa1[11]; //數字量溢出標志位 uchar bc[9];uchar xc=0; //={34,06,52,44,66,66,44,66,66,} uchar a=0; uchar bb=0; char web[] = {"Ua"}; uchar U[] = {"****Voltage*****"}; uchar Uv[] = {"V"}; uchar Ua[] = {"Ua="}; uchar Ub[] = {"Ub="}; uchar Uc[] = {"Uc="}; int iu; int result=0x38; int Ucc=500; int Scc=200; int Icc=500; int xz; int pd; void WriteDataLCD(unsigned char WDLCD) { PORTB = WDLCD; RC3 = 1; RC4 = 0; RC5 = 0; //若晶振速度太高可以在這后加小的延時 RC5 = 0; //延時 RC3 = 1; }*/ void sciinitial() /* 串行通訊初始化子程序 */ { TXSTA=0x04; /* 選擇異步高速方式傳輸8位數據 */ RCSTA=0x80; /* 允許串行口工作使能 */ TRISC=TRISC|0X80; /* :將RC7(RX)設置為輸入方式 */ TRISC=TRISC&0Xbf; /* RC6(TX)設置為輸出 */ SPBRG=143; /* 4M晶振且波特率為9600時,SPBRG設置值為25 */ PIR1=0x00; /* 清中斷標志 */ PIE1=PIE1|0x20; /* 允許串行通訊接口接收中斷使能 */ RCIP=0; /* 設置SCI接收中斷為低優先級中斷 */ CREN=1; /* 允許串口連續接收數據 */ if(0==Send_Mode) TXEN=1; /* Send_Mode=0,非中斷方式發送,串口發送數據使能 */ else /* Send_Mode=1,中斷方式發送 */ { PIE1=PIE1|0x10; /* 允許中斷發送 */ TXIP=0; /* 發送低優先級中斷 */ } } void interrupt low_priority LOW_ISR() /* 低優先級中斷子程序 */ { if(RCIF==1) /* RS232接收中斷 */ { RCIF=0; /* 清中斷標志 */ receive232[receive_count]=RCREG; send232[receive_count]=RCREG; /* 接收數據存放到發送緩沖數組 */ receive_count++; /* 接收計數器加1 */ if(receive232[0]==0xfc&&receive232[1]==0xfc);//前兩位是否為0xfc else {receive_count=0;return;}//不是則重新加載數據 if(receive_count==10) /* 如果已經接收到8個數據 */ { receive_count=0; /* 接收計數器清0 */ SciReceiveFlag=1; /* 置接收到8個數據標志 */ } } else if((0!=Send_Mode)&&(TXIF==1)) /* 中斷發送數據方式且為發送中斷 */ { if(send_count==1) /* 已經發送完8個數 */ { TXEN=0; /* 發送不使能 */ return; } else { TXREG=pd; /* 發送當前應發送數據,發送指針加1 */ send_count++; /* 發送計數器加1 */ } } } void init() { TRISC3=0;TRISB=0x00; TRISA=0xFF; TRISC4=0; TRISC5=0; PORTB=0x00;//LATA=0xFF; RCSTA=0X90; } void UartInit(void)//初始化函數 { INTCONbits.GIEL = 1; //使能外設中斷 } void lcdwc(unsigned char c) //送控制字到液晶顯示控制器子程序 { lcdwaitidle(); //HD44780液晶顯示控制器忙檢測 RC3=0; //RS=0 RW=0 E=高電平 RC4=0; PORTB=c; RC5=1; RC5=0; } //------------------------------------------------------------------------------- //子程序名稱:void lcdwd(unsigned char d). //功能:送數據到液晶顯示控制器. //修改日期:2009.08.12 //修改人:chujianjun@sunman.cn,tanchao@sunman.cn //------------------------------------------------------------------------------- void lcdwd(unsigned char d) //送控制字到液晶顯示控制器子程序 { lcdwaitidle(); //HD44780液晶顯示控制器忙檢測 RC3=1; //RS=1 RW=0 E=高電平 RC4=0; PORTB=d; RC5=1; RC5=0; } //------------------------------------------------------------------------------- //子程序名稱:unsigned char lcdrd(void). //功能:讀數據到液晶顯示控制器. //------------------------------------------------------------------------------- unsigned char lcdrd(void) //讀數據子程序 { unsigned char d; lcdwaitidle(); //HD44780液晶顯示控制器忙檢測 PORTB=0xff; RC3=1; //RS=1 RW=1 E=高電平 RC4=1; RC5=1; d=PORTB; RC5=0; return d; } //------------------------------------------------------------------------------- //子程序名稱:void lcdwaitidle(void). //功能:忙檢測. //------------------------------------------------------------------------------- void lcdwaitidle(void) //忙檢測子程序 { unsigned char i; PORTB=0xff; RC3=0; //RS=0 RW=1 E=高電平 RC4=1; RC5=1; for(i=0;i<20;i++) if((PORTB&0x80) == 0) break; //D7=0 表示LCD控制器空閑,則退出檢測 RC5=0; } void Delay_Ms(unsigned int ms) { unsigned int i; do{ i = MAIN_Fosc / 96000; while(--i) ; //96T per loop }while(--ms); } void delay() { int i; for (i=0;i<5000;i++); } void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) { X&=0X0f; //X位置范圍(0到15) Y&=0X03; //Y位置范圍(0到1) if(Y==0) //(第一行)X: 第0----15個字符 lcdwc(X|0x80); // DDRAM: 0----0FH else if (Y==1) //(第二行)X: 第0----15個字符 lcdwc(X|0xC0); // DDRAM: 40----4FH else if (Y==2) //(第三行)X: 第0----15個字符 lcdwc(X|0x90); // DDRAM: 10----1FH else //(第四行)X: 第0----15個字符 lcdwc(X|0xD0); lcdwd(DData); }