字體:小 中 大 | |
|
|
2015/03/05 04:56:25瀏覽873|回應0|推薦0 | |
8051單軸馬達微控器 — 開發程式說明三 壹,前言 本文在延續之前兩篇文章介紹微控器程式碼的其他較小的副程式,包括以下七個 void Timer2_isr(void) interrupt 5 (內部Timer2:用於偵測sensor狀態) void ISR_INT0(void) interrupt 0 (外部中斷0副程序 緊急停上按鈕鍵) void ISR_INT1(void) interrupt 2 (外部中斷2副程序 HOME SENSOR偵測) void UART_Init(void) (UART啟始副程式) void SendByte(unsigned char dat) (SendByte傳送一個Byte副程式) void SendStr(unsigned char *s) (SendStr傳送一個字串副程式) void UART_SER (void) interrupt 4 (UART中斷4副程式) 貳,程式碼功能介紹 在此需要講解的部份,有前三個副程式,因為後四個副程式屬常用的UART服務用,各位同好應該早就耳熟的程式碼,我們就從Timer2_isr先開使,在微控器設計中,為了隨時偵測微控器運作的情形,利用了PORT3中的P3^2~P3^7(除了P3^6腳,因為在89C2051中,並未提供P3^6腳的功能,為了將來此微控器程式碼能夠直接適用至89C2051晶片的原故),作為系統操作的按鍵或SENSOR的輸入端,接腳功能定義如下: 接腳位置 功能 說明 ===================================================================== P3^0 => RXD USB RXD P3^1 => TXD USB TXD P3^2 => INTR0 M_STOP:緊急停止按鈕鍵 P3^3 => INTR1 M_HOME:HOME位置信號 P3^4 => T0 M_SYNC:SYNC信號 P3^5 => T1 M_SENSOR:SENSOR INPUT P3^7 => LIMIT M_LIMIT:LIMIT信號 其中對應的中斷表如下: INTERRUPT# FUNCTION ============================================= 0 緊急按鈕鍵中斷 1 TIMER_0中斷 2 HOME SENSOR中斷 3 TIMER_1中斷,SENSOR COUNT 4 UART中斷 5 TIMER_2 M_STOP:緊急停止按鈕鍵:是一個外接的按鈕,當緊急收況需要馬達立即停機時使用 M_HOME:此可連接光遮LED或微動開關,再配合機構來鑑別馬達在HOME之位置 M_SYNC:是一個可以併連方式連接至主機,由主機決定微控器同步動作的信號輸入端 M_SENSOR:連接光遮LED SENSOR,用來偵測馬達軸承旋轉的0度位置 M_LIMIT:連接光遮LED SENSOR或微動開關,用來偵測馬達是否已超過極限位置 ||======|| < M_SENSOR /////////////////////////////////////////////////////////|| 馬達 ||/////// ^ ^ ||======|| M_LIMIT M_HOME 在TIMER-2程式撰寫是程式宣告中的兩個參數來定義TIMER 2的計數為0x255 #define MSB_reload_value 0x255 /* TIMER2 msb reload value exemple */ #define LSB_reload_value 0x255 /* TIMER2 lsb reload value exemple */ 如此TIMER 2在每0x255 CYCLE時會產生中斷5的服務,於是在副程式中就可以將外部SENSOR加以偵測一次,並分別依情況設定相關的旗號,還後續的程式去處理特別事件了。 /*------------------------------------------------ TIMER-2 INTR (供應給外部sensor) ------------------------------------------------*/ void Timer2_isr(void) interrupt 5 // interrupt address is 0x002b { if(M_home==0) { Home_flag=0;Err_flag=4;OnOff_flag=0;Rcv_Buf[0]=0x53;Rcv_Buf_Index=0;timesx=0;timesy=0; } //偵測HOME POSITION SENSOR else { Home_flag=1; } if(M_limit==0) { Err_flag=5;OnOff_flag=0;Rcv_Buf[0]=0x4c;Rcv_Buf_Index=0; } //偵測LIMIT POSITION SENSOR if(M_sensor==0 && Sensor_flag==0) //檢知M_sensor==0信號,如經過low至high時,SensorCnt加一次 { Sensor_flag=1;SensorCnt++; } if(M_sensor==1 && Sensor_flag==1) { Sensor_flag=0; } EXF2 =0; // reset flag TF2 = 0; // reset interrupt flag } 而ISR_INT0:外部中斷0是用來做"緊急停上按鈕鍵",因為其中斷層級為最優先,是假設在運作時出現緊急狀態,需要立即停機時使用。 /*------------------------------------------------ 外部中斷0副程序 緊急停上按鈕鍵 ------------------------------------------------*/ void ISR_INT0(void) interrupt 0 { if (!INT0) { DelayUs2x(20); if(!INT0) { OnOff_flag=0;Rcv_Buf[0]=0x45; } //立即停機,顯示訊息"E" } } 而ISR_INT1:外部中斷1是用來做為HOME位置定位用,因為使用上單軸軸承需要一個啟使點,如此主機才依此啟使點進行步進數計算,此位置在裝設時需要校正之。 /*------------------------------------------------ 外部中斷1副程序 HOME SENSOR偵測 ------------------------------------------------*/ void ISR_INT1(void) interrupt 2 { if (!INT1) { DelayUs2x(20); if(!INT1) { OnOff_flag=0;Rcv_Buf[0]=0x48;timesy=0; }//已至HOME位置,立即停機,並清空步數為0,顯示訊息"H" } } UART_Init 副程式是UART設定傳送速率9600,8位元,1 STOP位元。 /*------------------------------------------------ RS232 INIT. ------------------------------------------------*/ void UART_Init(void) { SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收 TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重裝 TH1 = 0xfd; // TH1: 重裝值 9600 串列傳輸速率 晶振 11.0592MHz TR1 = 1; // TR1: timer 1 打開 // EA = 1; //打開總中斷 ES = 1; //打開串口中斷 } SendByte 副程式是服務傳送出一個位元BYTE用。 /*------------------------------------------------ SENT A BYTE ------------------------------------------------*/ void SendByte(unsigned char dat) { SBUF = dat; while(!TI); TI = 0; } SendStr 副程式是服務傳送出一個字串用 /*------------------------------------------------ SENT A STRING ------------------------------------------------*/ void SendStr(unsigned char *s) { while(*s!='\0')// \0 表示字串結束標誌,通過檢測是否字串末尾 { SendByte(*s); s++; } } void UART_SER (void) interrupt 4副程式是專屬UART的中斷4服務程式碼。 /*------------------------------------------------ 串口中斷程式 ------------------------------------------------*/ void UART_SER (void) interrupt 4 //串列中斷服務程式 { if(RI==1) //判斷是接收中斷?生 { ; RI = 0; // Clear RI (Receive Interrupt). if (Rcv_Get == 0) // If Receive_Buffer Not Full. { if ((SBUF >= 0x21) && (SBUF <= 0x7f="" only="" ascii="" from="" 0x21="" to="" into="" receive_buffer="" o:p=""> { Rcv_Buf[Rcv_Buf_Index] = SBUF; Rcv_Buf_Index++; if (Rcv_Buf_Index == Rcv_Buf_Size) Rcv_Get = 1; } } } if (TI == 1) { TI = 0; // Clear TI (Transmit Interrupt). } } 參,結論 這七個副程式,前三個是針對微控器的外部SENSOR進行偵測的功能,再提供對應的旗號,讓後續程式碼可應變馬達在運作時的狀況,請特別留意M_HOME,M_SENSOR與M_LIMIT等這三個需配合機構進行校正其位置,方可讓微控器將來在運作時具有保護機制,而且此牽涉主機與微控器兩者之間對步進數的定義,現已介紹至第三篇,後續第四篇將介紹微控器的主程式,請同好再延伸閱讀。(待續) |
|
( 興趣嗜好|其他 ) |