HT66F60

1 HT66F60 編碼

使用 C 語言和組合語言說明 HT66F60 的編碼技巧,包括主程式流程、應用程式與各個特殊功能區塊的驅動程式。


2 HITECK HT-IDE3000

HOLTEK 免費提供程式編輯器 HT-IDE3000,可以編輯並編譯 C 語言和組合語言。 筆者覺得 HT-IDE3000 非常不穩,容易當掉,所以只用來編譯程式碼。 編輯程式碼可以用 ECLIPSE FOR C++,或使用一般的文字編輯器,即可。

HT-IDE3000 下載網址 http://www.holtek.com.tw/chinese/tech/tool/Mainpage1.htm

HOLTEK

下載後,直接安裝,即可。之後,建立各程式碼檔案,編譯程式。

HOLTEK

筆者將程式碼分成 11 個程式碼檔案,包括 11 個 C 語言檔和 1 個組合語言檔。

main.c主程式。
system.c系統應用程式。
drivers.c晶片內部驅動程式。
ext_drivers.c外部驅動程式。
key.c按鍵驅動程式,讀取按鍵資訊。
monitor.c監督應用程式,讀取環境感測器參數。
actuator.c致動器應用程式。
menu.c目錄應用程式。
debug.c偵錯應用程式。
configtable.c組態表,使用 EEPROM。
display.asm面板顯示程式。

3 MAIN.C

主程式負責整支程式的主要流程,包括驅動程式與應用程式的初始化與執行流程。

main.c
01 ENTRY(startup_32)
01 void main(void){
01     _emi=0;
01     GpioInit();
01     RemapInit();
01     SystemInit();
01     AdInit();
01     XintInit();
01     ComparatorInit();
01     TmInit();
01     SimInit();
01     TbInit();
01     LvdInit();
01     EepromInit();
01     IicMasterInit();
01     PwmInit();
01     UartInit();
01     RtcInit();
01     SystemInit();
01     KeyInit(); 
01     MenuInit();
01     MonitorInit();
01     ActuatorInit();
01     DISPLAY_INIT();     
01     ConfigTableInit();
01 	#if DEBUG_ENABLE==1
01 		DebugInit();
01 		DebugcmdInit();
01 	#endif
01     _emi=1;                
01     while(1){
01         KeySvc();        
01         MenuSvc();       
01         MonitorSvc();    
01         ActuatorSvc();   
01         RtcSvc();        
01         UartSvc();       
01         PwmSvc();        
01         SystemSvc();
01 		#if DEBUG_ENABLE==1
01 			DebugSvc();     
01 			DebugcmdSvc();
01 		#endif
01     }
01 }

main.c
01 #pragma vector _Int0Isr @ 0x04
01 #pragma vector _Int1Isr @ 0x08
01 #pragma vector _Int2Isr @ 0x0c
01 #pragma vector _Int3Isr @ 0x10
01 #pragma vector _Comparator0Isr @ 0x14
01 #pragma vector _Comparator1Isr @ 0x18
01 #pragma vector _Mfunct0Isr @ 0x1c
01 #pragma vector _Mfunct1Isr @ 0x20
01 #pragma vector _Mfunct2Isr @ 0x24
01 #pragma vector _Mfunct3Isr @ 0x28
01 #pragma vector _AdIsr @ 0x2c
01 #pragma vector _Mfunct4Isr @ 0x30
01 #pragma vector _Timebase0Isr @ 0x34
01 #pragma vector _Timebase1Isr @ 0x38
01 #pragma vector _Mfunct5Isr @ 0x3c

main.c
01 void  _Int0Isr(void){ 
01     SystemFlags0|=SYSTEM_FLAG_INT0;
01 }
01 void  _Int1Isr(void){
01     SystemFlags0|=SYSTEM_FLAG_INT1;
01 }
01 void  _Int2Isr(void){ 
01     SystemFlags0|=SYSTEM_FLAG_INT2; 
01 }
01 void  _Int3Isr(void){ 
01     SystemFlags0|=SYSTEM_FLAG_INT3;
01 }

main.c
01 void  _Comparator0Isr(void){ 
01     SystemFlags0|=SYSTEM_FLAG_CP0_CHANGE;
01     if(_c0out==1) SystemFlags0|=SYSTEM_FLAG_CP0_CPGTCN;
01     else SystemFlags0&=SYSTEM_FLAG_CP0_CPGTCN;
01 }
01 void  _Comparator1Isr(void){ 
01     SystemFlags0|=SYSTEM_FLAG_CP1_CHANGE;
01     if(_c1out==1) SystemFlags0|=SYSTEM_FLAG_CP1_CPGTCN;
01     else SystemFlags0&=SYSTEM_FLAG_CP1_CPGTCN;
01 }

main.c
01 void  _Mfunct0Isr(void){ 
01     if(_t0af==1) {
01         _t0af=0;
01     }
01 }
01 void  _Mfunct1Isr(void){}
01 void  _Mfunct2Isr(void){}
01 void  _Mfunct3Isr(void){
01     if(_t3af==1) {
01         _t3af=0;
01     }
01 }

main.c
01 void  _AdIsr(void){ 
01     if(_adf){
01         _adf=0;
01         SystemFlags1|=SYSTEM_FLAG1_AD;
01         //AdCtrl.AdDataLow=_adrl;
01         //AdCtrl.AdDataHigh=_adrh;
01         _adoff=1;
01     }
01 }
01 void  _Mfunct4Isr(void){ 
01 	/*if(_simf==1){
01 		_simf=0;
01 	}*/
01     if(_xpf==1){ // handle uart interrupt
01         _xpf=0;  //clear PINT interrupt flag    
01         //read uart usr register
01         _csen=1;
01         _wcol=0;
01         _simd=UART_READREG+UART_REG_USR; //read uart status register...this clear
01         //for(IsrTemp1=0;IsrTemp1<2;IsrTemp1++);
01         while(_trf==0);
01         _trf=0;
01         _wcol=0;
01         _simd=0x00;
01         while(_trf==0);
01         _trf=0;
01         IsrTemp0=_simd;  //save USR in ram.
01         //for(IsrTemp1=0;IsrTemp1<5;IsrTemp1++);
01         _csen=0;
01         UartCtrl.Usr=IsrTemp0;
01         if(IsrTemp0&UART_TXIF){ //tx register empty
01             UartCtrl.Flags|=UART_TX_FLAG;
01             //todo: send another byte.
01         }
01         //if(IsrTemp0&UART_TIDLE){} /* don't care */
01         if(IsrTemp0&UART_RXIF){
01             //read uart rxr 
01             _csen=1;
01             _wcol=0;
01             _simd=UART_READFIFO; // read RXR to clear OERR flag
01             //for(IsrTemp1=0;IsrTemp1<2;IsrTemp1++);
01             while(_trf==0);
01             _trf=0;
01             _wcol=0;
01             _simd=0x00;
01             while(_trf==0);
01             _trf=0;
01             IsrTemp1=_simd;      // don't care value in _simd
01             _csen=0;
01             if((UartCtrl.Flags&UART_RX_FLAG)==0){   // prevent overrun 
01                 UartCtrl.Flags|=UART_RX_FLAG;
01                 UartCtrl.RxData=IsrTemp1;
01             }
01             //todo:put byte to rx buffer.
01         }
01         //if(IsrTemp0&UART_RIDLE){} /* don't care */
01         if(IsrTemp0&(UART_OERR|UART_FERR|UART_NF|UART_PERR)){
01             //read uart rxr to clear int flag
01             _csen=1;
01             _wcol=0;
01             _simd=UART_READFIFO; // read RXR to clear OERR flag
01             while(_trf==0);
01             _trf=0;
01             _wcol=0;
01             _simd=0x00;
01             while(_trf==0);
01             //for(IsrTemp1=0;IsrTemp1<2;IsrTemp1++);
01             _trf=0;
01             IsrTemp0=_simd;     // don't care value in _simd
01             _csen=0;
01         }
01     }
01 }

main.c
01 void  _Timebase0Isr(void){ 
01     /*if(TestBit==1) TestBit=0; 
01     else TestBit=1; 
01     */   
01 }

main.c
01 void  _Timebase1Isr(void){ 
01     if(DebugCtrl.Timer!=0) DebugCtrl.Timer--;
01     if(RtcCtrl.Timer!=0) RtcCtrl.Timer--;
01     if(DISPLAY_TIMER!=0) DISPLAY_TIMER--;
01     if(MenuCtrl.Timer!=0) MenuCtrl.Timer--;
01     if(KeyCtrl.Timer!=0) KeyCtrl.Timer--;
01     if(KeyCtrl.RepeatTimer!=0) KeyCtrl.RepeatTimer--;
01     if(UartCtrl.Timer!=0) UartCtrl.Timer--;
01     if(ActuatorCtrl.Timer!=0) ActuatorCtrl.Timer--;
01     if(PwmCtrl.PeriodTimer!=0) PwmCtrl.PeriodTimer--;
01     if(PwmCtrl.DutyTimer!=0) PwmCtrl.DutyTimer--;
01     if(MonitorCtrl.Timer!=0) MonitorCtrl.Timer--;
01     if(DISPLAY_TIMER==0){
01         DISPLAY_TIMER=1;
01         DISPLAY_SVC();
01     }
01 }

main.c
01 void  _Mfunct5Isr(void){ 
01     /*if(_def==1){
01        //_def=0; 
01        //todo eeprom isr    
01     }*/
01     if(_lvf==1){
01         _lvf=0; 
01         SystemFlags1|=SYSTEM_FLAG1_LVD;
01     }
01 }


4 SYSTEM.C

系統服務程式的功能是執行系統啟動步驟,檢查系統參數與資料,啟動應用程式。之後,監視系統狀態,執行系統事件的處理,例如系統休眠。目前是空函式。


5 DRIVERS.C

內部驅動程式,包括 GPIO、AD、INT、COMPARATOR、TM、SIM、TB、LVD、EEPROM、IIC MASTER、PWM。其中,IIC 和 PWM 是用 GPIO 模擬的內部驅動程式。 HT66F60 沒有提供 IIC MASTER 的硬體,必須使用 GPIO 模擬。 HT66F60 有提供 PWM,但硬體 PWM 的解析度太高(20MS),無法用於加熱器,所以使用計時器配合 GPIO 製作一個低度率的 PWM。

DRIVERS.C
01 void GpioInit(void){
01     _pawu=0b00000000; 
01     _pa=0b00000000;
01     _pac=0b00001111;
01     _papu=0b00000000; 
01     _pb=0b00000000;
01     _pbc=0b00100111; 
01     _pbpu=0b00000000;
01     _pc=0b00000000;
01     _pcc=0b00011100;
01     _pcpu=0b00001100;
01     _pd=0b00000000;
01     _pdc=0b00000000;
01     _pdpu=0b00000000; 
01     _pe=0b00000000;
01     _pec=0b00000000;
01     _pepu=0b00000000;
01     _pf=0b00000000;
01     _pfc=0b00000000;
01     _pfpu=0b00000000;
01     _pgc=0b00000000;
01     _pgpu=0b00000000;
01 }
01 void RemapInit(void){
01     _prm0=0b00000111;
01     _prm1=0b00000000;
01     _prm2=0b00000000; 
01 }
01 void XintInit(void){
01     _integ=0b00000000;
01     Xint0Init();
01     Xint1Init();
01     Xint2Init();
01     Xint3Init();
01 }
01 void Xint0Init(void){
01  #if XINT_INT0_SELECT == 0
01     _int0s0=0;
01     _int0s1=0;
01     _int0e=0;
01  #elif XINT_INT0_SELECT==1
01     _int0s0=1;
01     _int0s1=0;
01     _int0e=1;
01  #elif XINT_INT0_SELECT==2
01     _int0s0=0;
01     _int0s1=1;
01     _int0e=1;
01  #elif XINT_INT0_SELECT==3
01     _int0s0=1;
01     _int0s1=1;
01     _int0e=1;
01  #endif	
01 }
01 void Xint1Init(void){
01  #if XINT_INT11_SELECT==0
01     _int0s0=0;
01     _int0s1=0;
01     _int0e=0;
01  #elif XINT_INT1_SELECT==1
01     _int0s0=1;
01     _int0s1=0;
01     _int0e=1;
01  #elif XINT_INT1_SELECT==2
01     _int0s0=0;
01     _int0s1=1;
01     _int0e=1;
01  #elif XINT_INT1_SELECT==3
01     _int0s0=1;
01     _int0s1=1;
01     _int0e=1;
01  #endif	
01 }
01 void Xint2Init(void){
01  #if XINT_INT2_SELECT==0
01     _int0s0=0;
01     _int0s1=0;
01     _int0e=0;
01  #elif XINT_INT2_SELECT==1
01     _int0s0=1;
01     _int0s1=0;
01     _int0e=1;
01  #elif XINT_INT2_SELECT==2
01     _int0s0=0;
01     _int0s1=1;
01     _int0e=1;
01  #elif XINT_INT2_SELECT==3
01     _int0s0=1;
01     _int0s1=1;
01     _int0e=1;
01  #endif	
01 }
01 void Xint3Init(void){
01  #if XINT_INT3_SELECT==0
01     _int0s0=0;
01     _int0s1=0;
01     _int0e=0;
01  #elif XINT_INT3_SELECT==1
01     _int0s0=1;
01     _int0s1=0;
01     _int0e=1;
01  #elif XINT_INT3_SELECT==2
01     _int0s0=0;
01     _int0s1=1;
01     _int0e=1;
01  #endif	
01 }
01 void ComparatorInit(void){
01     Comparator0Init();
01     Comparator1Init();
01 }
01 void Comparator0Init(void){
01  #if COMPARATOR0_SELECT==0
01    	_cp0c=0b00000000;
01    	_cp0e=0;
01  #elif COMPARATOR0_SELECT==1
01    	_cp0c=0b11000001;
01    	_cp0e=1;
01  #endif
01 }
01 void Comparator1Init(void){
01  #if COMPARATOR1_SELECT==0
01    	_cp1c=0b00000000;
01    	_cp1e=0;
01  #elif COMPARATOR1_SELECT==1
01    	_cp1c=0b11000001;
01    	_cp1e=1;
01  #endif
01 }
01 void TmInit(void){
01     _tmpc0=0; 
01     _tmpc1=0; 
01     Tm0Init();
01     Tm1Init();
01     Tm2Init();
01     Tm3Init();
01 }
01 void Tm0Init(void){
01  #if TM_TM0_PORT_SELECT==0
01     _t0cp0=0;         
01     _t0cp1=0;         
01  #elif TM_TM0_PORT_SELECT==1
01     _t0cp0=1;         
01     _t0cp1=0;         
01  #elif TM_TM0_PORT_SELECT==2
01     _t0cp0=0;         
01     _t0cp1=1;         
01  #endif
01  #if TM_TM0_SELECT==0
01     _tm0c0=0b00000000; 
01     _tm0c1=0b00000000; 
01     _t0ae=0;          
01     _mf0e=0;           
01  #elif TM_TM0_SELECT==1   
01     _tm0c0=0b00000010; 
01     _tm0c1=0b10101001; 
01     _tm0al=0b01000000; 
01     _tm0ah=0b00000000; 
01     _t0on=1;           
01     _t0ae=1;           
01     _mf0e=1;           
01  #elif TM_TM0_SELECT==2   
01     _tm0c0=0b00010010; 
01     _tm0c1=0b10101001; 
01     _tm0al=0b01000000; 
01     _tm0ah=0b00000000; 
01     _t0on=1;           
01     _t0ae=1;           
01     _mf0e=1;           
01  #elif TM_TM0_SELECT==3   
01     _tm0c0=0b00100010; 
01     _tm0c1=0b10101001; 
01     _tm0al=0b01000000;
01     _tm0ah=0b00000000;
01     _t0on=1;           
01     _t0ae=1;           
01     _mf0e=1;           
01  #elif TM_TM0_SELECT==4   
01     _tm0c0=0b00110010; 
01     _tm0c1=0b10101001; 
01     _tm0al=0b01000000; 
01     _tm0ah=0b00000000; 
01     _t0on=1;           
01     _t0ae=1;           
01     _mf0e=1;          
01  #elif TM_TM0_SELECT==5  
01     _tm0c0=0b01000010;
01     _tm0c1=0b10101001;
01     _tm0al=0b01000000; 
01     _tm0ah=0b00000000; 
01     _t0on=1;          
01     _t0ae=1;           
01     _mf0e=1;           
01  #endif
01 }
01 void Tm1Init(void){
01  #if TM_TM1_SELECT==0
01      _tm1c0=0b00000000;
01      _tm1c1=0b00000000;
01      _tm1c2=0b00000000;
01      _mf1e=0;
01      _t1ae=0;
01  #elif TM_TM1_SELECT==1
01     _tm1c0=0b00000000; 
01     _tm1c1=0b10001000; 
01     _tm1c2=0b10001000; 
01     _tm1al=0b10000000; 
01     _tm1ah=0b00000000; 
01     _tm1bl=0b10000000; 
01     _tm1bh=0b00000000;
01     //_t10n=1;
01     _mf1e=1;
01     _t1ae=1;
01  #endif
01  #if TM_TM1_PORT_SELECT==0
01     _t1acp0=0;
01     _t1bcp0=0;
01     _t1bcp1=0;
01     _t1bcp2=0;
01  #elif TM_TM1_PORT_SELECT==1
01     _t1acp0=1;
01     _t1bcp0=0;
01     _t1bcp1=0;
01     _t1bcp2=0;
01  #elif TM_TM1_PORT_SELECT==2
01     _t1acp0=0;
01     _t1bcp0=1;
01     _t1bcp1=0;
01     _t1bcp2=0;
01  #elif TM_TM1_PORT_SELECT==3
01     _t1acp0=0;
01     _t1bcp0=0;
01     _t1bcp1=1;
01     _t1bcp2=0;
01  #elif TM_TM1_PORT_SELECT==4
01     _t1acp0=0;
01     _t1bcp0=0;
01     _t1bcp1=0;
01     _t1bcp2=1;
01  #endif
01 }
01 void Tm2Init(void){
01  #if TM_TM2_PORT_SELECT==0
01     _t2cp0=0;
01     _t2cp1=0;
01  #elif TM_TM2_PORT_SELECT==1
01     _t2cp0=1;
01     _t2cp1=0;
01  #elif TM_TM2_PORT_SELECT==2
01     _t2cp0=0;
01     _t2cp1=1;
01  #endif
01  #if TM_TM2_SELECT==0
01     _tm2c0=0b00000000;
01     _tm2c0=0b10001000;
01     _tm2al=0b00000000; 
01     _tm2ah=0b00000000;
01     _tm2rp=0b00000000; 
01     _mf1e=0;
01     _t1ae=0;
01  #elif TM_TM2_SELECT==1
01     _tm2c0=0b00000000;
01     _tm2c0=0b00000000;
01     _tm2al=0b00000000; 
01     _tm2ah=0b00000000;
01     _tm2rp=0b00000000; 
01     //_t10n=1;
01     _mf1e=1;
01     _t1ae=1;
01  #endif
01 }
01 void Tm3Init(void){
01  #if TM_TM3_PORT_SELECT==0
01     _t3cp0=0;         
01     _t3cp1=0;         
01  #elif TM_TM3_PORT_SELECT==1
01     _t3cp0=1;         
01     _t3cp1=0;         
01  #elif TM_TM3_PORT_SELECT==2
01     _t3cp0=0;         
01     _t3cp1=1;         
01  #elif TM_TM3_PORT_SELECT==3
01     _t3cp0=1;         
01     _t3cp1=1;         
01  #endif
01  #if TM_TM3_SELECT==0
01     _tm3c0=0b00000000; 
01     _tm3c1=0b00000000; 
01     _t3ae=0;           
01     _mf3e=0;           
01  #elif TM_TM3_SELECT==1   
01     _tm3c0=0b00000010; 
01     _tm3c1=0b10101001; 
01     _tm3al=0b01000000; 
01     _tm3ah=0b00000000; 
01     _t3on=1;           
01     _t3ae=1;           
01     _mf3e=1;           
01  #endif
01 }
01 #pragma norambank
01 AD_CONTROL AdCtrl;
01 void AdInit(void){
01  #if AD_SELECT==0
01     _adcr0=0b01100000; 
01     _adcr1=0b00000000; 
01     _acerl=0b00000000;
01     _acerh=0b00000000;
01     _ade=0;
01  #elif AD_SELECT==1
01     _adcr0=0b00110000;
01     _adcr1=0b00000011;
01     _acerl=0b00001111; 
01     _acerh=0b00000000;
01     _ade=0;
01  #endif
01 }
01 void AdActivate(void){
01     _adcr0&=0xf0;
01     _adcr0|=AdCtrl.ChannelNumber;
01     _adoff=0;
01     _start=1;
01     _start=0;
01 }
01 	
01 void AdChannelSet(INT8U ChannelNumber){
01     if(ChannelNumber>SYSTEM_CHANNEL_MAX) return;
01     AdCtrl.ChannelNumber=ChannelNumber;
01 }
01 #pragma norambank
01 SIM_CONTROL SimCtrl;
01 void SimInit(void){
01 	#if SIM_SELECT==0
01         _simc0=0b11100000;
01         _simc2=0b00000000;
01         _sime=0; 
01 	#elif SIM_SELECT==1
01         _simc0=0b00010010; 
01         _simc2=0b00001100; 
01         _sime=0;          
01     #endif
01     SimCtrl.Command=0;
01     SimCtrl.Data=0;
01 }
01 void SimSpiWrite(void){
01 	_xpe=0;
01 	_csen=1;
01 	_wcol=0;
01 	_simd=SimCtrl.Command;
01 	while(_trf==0);
01     _trf=0;
01 	_wcol=0;
01     _simd=SimCtrl.Data;
01 	while(_trf==0);
01     _trf=0;
01     SimCtrl.Data1=_simd;
01     _csen=0;
01     _xpe=1;
01 }
01 void SimSpiRead(void){
01 	_xpe=0;
01 	_csen=1;
01 	_wcol=0;
01 	_simd=SimCtrl.Command;
01 	while(_trf==0);
01     _trf=0;
01 	_wcol=0;
01     _simd=00;
01 	while(_trf==0);
01     _trf=0;
01     SimCtrl.Data1=_simd;
01     _csen=0;
01     _xpe=1;
01 }
01 void SimSpiRead2(void){
01 	_xpe=0;
01 	_csen=1;
01 	_wcol=0;
01 	_simd=SimCtrl.Command;
01 	while(_trf==0);
01     _trf=0;
01     SimCtrl.Data=_simd;
01     _csen=0;
01 	_xpe=1;
01 }
01 void SimPckFsysSet(void){
01 	_pckp0=0;
01 	_pckp1=0;
01 }
01 void TbInit(void){
01 #if TB_SELECT==0
01     _tbon=0;
01 #elif TB_SELECT==1
01     _tbon=0;
01     _tbck=0;
01     Tb0Init();
01     Tb1Init();
01     _tbon=1;
01 #elif TB_SELECT==2
01     _tbon=0;
01     _tbck=1;
01     Tb0Init();
01     Tb1Init();
01     _tbon=1;
01 #endif
01 }
01 
01 void Tb0Init(void){
01  #if TB0_SELECT==0
01     _tb0e=0;
01  #elif TB0_SELECT==1
01     _tb0e=0;
01     _tb00=0;
01     _tb01=0;
01     _tb02=0;
01     _tb0e=1;
01  #elif TB0_SELECT==2
01     _tb0e=0;
01     _tb00=1;
01     _tb01=0;
01     _tb02=0;
01     _tb0e=1;
01  #elif TB0_SELECT==3
01     _tb0e=0;
01     _tb00=0;
01     _tb01=1;
01     _tb02=0;
01     _tb0e=1;
01  #elif TB0_SELECT==4
01     _tb0e=0;
01     _tb00=1;
01     _tb01=1;
01     _tb02=0;
01     _tb0e=1;
01  #elif TB0_SELECT==5
01     _tb0e=0;
01     _tb00=0;
01     _tb01=0;
01     _tb02=1;
01     _tb0e=1;
01  #elif TB0_SELECT==6
01     _tb0e=0;
01     _tb00=1;
01     _tb01=0;
01     _tb02=1;
01     _tb0e=1;
01  #elif TB0_SELECT==7
01     _tb0e=0;
01     _tb00=0;
01     _tb01=1;
01     _tb02=1;
01     _tb0e=1;
01  #elif TB0_SELECT==8
01     _tb0e=0;
01     _tb00=1;
01     _tb01=1;
01     _tb02=1;
01     _tb0e=1;
01  #endif
01 }
01 
01 void Tb1Init(void){
01  #if TB1_SELECT==0
01     _tb1e=0;
01  #elif TB1_SELECT==1
01     _tb1e=0;
01     _tb10=0;
01     _tb11=0;
01     _tb1e=1;
01  #elif TB1_SELECT==2
01     _tb1e=0;
01     _tb10=1;
01     _tb11=0;
01     _tb1e=1;
01  #elif TB1_SELECT==3
01     _tb1e=0;
01     _tb10=0;
01     _tb11=1;
01     _tb1e=1;
01  #elif TB1_SELECT==4
01     _tb1e=0;
01     _tb10=1;
01     _tb11=1;
01     _tb1e=1;
01  #endif
01 }
01 void LvdInit(void){
01  #if LVD_SELECT==0
01     _lvdc=0b00000000;
01     _lve=0;
01  #elif  LVD_SELECT==1
01     _lvdc=0b00010000;
01     _lve=1;
01     _mf5e=1;
01  #elif  LVD_SELECT==2
01     _lvdc=0b00010001;
01     _lve=1;
01     _mf5e=1;
01  #elif  LVD_SELECT==3
01     _lvdc=0b00010010;
01     _lve=1;
01     _mf5e=1;
01  #elif  LVD_SELECT==4
01     _lvdc=0b00010011;
01     _lve=1;
01     _mf5e=1;
01  #elif  LVD_SELECT==5
01     _lvdc=0b00010100;
01     _lve=1;
01     _mf5e=1;
01  #elif  LVD_SELECT==6
01     _lvdc=0b00010101;
01     _lve=1;
01     _mf5e=1;
01  #elif  LVD_SELECT==7
01     _lvdc=0b00010110;
01     _lve=1;
01     _mf5e=1;
01  #elif  LVD_SELECT==8
01     _lvdc=0b00010111;
01     _lve=1;
01     _mf5e=1;
01  #endif
01 }
01 #pragma norambank
01 EEPROM_CONTROL EepromCtrl;
01 extern  EEPROM_INIT_ASM();
01 extern  EEPROM_READ_ASM();
01 extern  EEPROM_WRITE_ASM();
01 void EepromInit(void){
01 	_eea=0;
01 	_eed=0;
01 	EepromCtrl.Address=0;
01 	EepromCtrl.Data=0;
01 }
01 void EepromRead(void){
01 	_eea=EepromCtrl.Address;
01 	EEPROM_READ_ASM();
01 	EepromCtrl.Data=_eed;
01 }
01 void EepromWrite(void){
01 	_eea=EepromCtrl.Address;
01 	_eed=EepromCtrl.Data;
01 	EEPROM_WRITE_ASM();
01 }
01 #define IIC_GPIO_WRITE_ADDRESS 0xd0
01 #define IIC_GPIO_READE_ADDRESS  0xd1
01 #define IicMasterSdaDir _1b_7 
01 #define IicMasterSda _1a_7
01 #define IicMasterScl _1a_6
01 #pragma rambank0
01 bit   bIicMasterAck;
01 bit   bIicMasterSda;
01 #pragma norambank
01 IIC_MASTER_GPIO_CONTROL IicMasterCtrl;
01 INT8U  IicMasterData;
01 
01 void IicMasterInit(void){
01 	IicMasterSdaDir=0;
01     IicMasterSda=1;
01     IicMasterScl=1;
01 	bIicMasterAck=0;
01 	bIicMasterSda=0;
01     IicMasterCtrl.Speed=0;
01 }
01 void IicMasterStartSignal(void){
01     IicMasterSda=1; 
01     IicMasterScl=1; 
01     IicMasterSda=0;
01     IicMasterDelay();
01     IicMasterScl=0;
01 }
01 void  IicMasterStopSignal(void){
01     IicMasterSda=0; 
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterSda=1;
01 }
01 INT8U IicMasterTxAckGet(void){
01     IicMasterSdaDir=1; 
01     IicMasterScl=1;
01     IicMasterDelay();
01     bIicMasterSda=IicMasterSda; 
01     bIicMasterSda=IicMasterSda;
01     bIicMasterSda=IicMasterSda;
01     IicMasterScl=0; 
01     IicMasterSda=0;                
01     IicMasterSdaDir=0; 
01     if (bIicMasterSda==1) return 1;
01     else return 0;
01 }
01 void IicMasterRxAckPut(void){
01     IicMasterSda=0;                
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;
01     IicMasterSda=0;
01 }
01 void IicMasterRxNackPut(void){
01     IicMasterSda=1;                
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;
01     IicMasterSda=0;
01 }
01 void IicMasterTxByte(INT8U Data){
01     if(Data&0x80) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0; 
01     IicMasterDelay();
01     if(Data&0x40) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;   
01     IicMasterDelay();
01     if(Data&0x20) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;        
01     IicMasterDelay();
01     if(Data&0x10) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;      
01     IicMasterDelay();
01     if(Data&0x08) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;   
01     IicMasterDelay();
01     if(Data&0x04) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;   
01     IicMasterDelay();
01     if(Data&0x02) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0;   
01     IicMasterDelay();
01     if(Data&0x01) IicMasterSda=1;
01     else  IicMasterSda=0;
01     IicMasterScl=1;
01     IicMasterDelay();
01     IicMasterScl=0; 
01     IicMasterDelay();            
01 }
01 INT8U IicMasterRxByte(void){
01     IicMasterSdaDir=1;
01     i=0;        
01     IicMasterScl=1;
01     IicMasterDelay(); 
01     if(IicMasterSda)  i|=0x80;               
01     IicMasterScl=0; 
01     IicMasterDelay(); 
01     IicMasterScl=1;
01     IicMasterDelay();                  
01     if(IicMasterSda)  i|=0x40; 
01     IicMasterScl=0;   
01      IicMasterDelay(); 
01     IicMasterScl=1;
01     IicMasterDelay();                  
01     if(IicMasterSda)  i|=0x20; 
01     IicMasterScl=0;        
01     IicMasterDelay(); 
01     IicMasterScl=1;
01     IicMasterDelay();                  
01     if(IicMasterSda)  i|=0x10; 
01     IicMasterScl=0;      
01     IicMasterDelay(); 
01     IicMasterScl=1;
01     IicMasterDelay();                  
01     if(IicMasterSda)  i|=0x08; 
01     IicMasterScl=0;   
01     IicMasterDelay();     
01     IicMasterScl=1;
01     IicMasterDelay();                  
01     if(IicMasterSda)  i|=0x04; 
01     IicMasterScl=0;   
01     IicMasterDelay();     
01     IicMasterScl=1;
01     IicMasterDelay();                  
01     if(IicMasterSda)  i|=0x02; 
01     IicMasterScl=0;   
01     IicMasterDelay();      
01     IicMasterScl=1;
01     IicMasterDelay();                  
01     if(IicMasterSda)  i|=0x01; 
01     IicMasterScl=0;
01     IicMasterSda=0;
01     IicMasterSdaDir=0;
01     return i;           
01 }
01 #define PWM_OUT _20_6
01 #pragma norambank
01 PWM_CONTROL PwmCtrl;
01 void PwmInit(void){
01 	PwmCtrl.State=PwmIdleState;
01 	PwmCtrl.Period=PWM_DEFAULT_PERIOD; //1sec
01 	PwmCtrl.Duty=PWM_DEFAULT_DUTY;
01 	PwmCtrl.PeriodTimer=0;
01 	PwmCtrl.DutyTimer=0;
01 	PWM_OUT=0;
01 }
01 void PwmSvc(void){
01 	if(PwmCtrl.State==PwmIdleState) return;
01 	if(PwmCtrl.DutyTimer!=0) PWM_OUT=1;
01 	else PWM_OUT=0;
01 	if(PwmCtrl.PeriodTimer!=0) return;
01 	PwmCtrl.PeriodTimer=PwmCtrl.Period;
01 	PwmCtrl.DutyTimer=PwmCtrl.Duty;
01 	if(PwmCtrl.DutyTimer!=0) PWM_OUT=1;
01 	else PWM_OUT=0;
01 }
01 void PwmStop(void){
01     PwmCtrl.State=PwmIdleState;
01     PwmCtrl.PeriodTimer=0;
01     PwmCtrl.DutyTimer=0;
01     PWM_OUT=0;
01 }
01 void PwmStart(void){
01 	PwmCtrl.State=PwmRunState;
01 	PwmCtrl.PeriodTimer=PwmCtrl.Period;
01 	PwmCtrl.DutyTimer=PwmCtrl.Duty;
01 	if(PwmCtrl.DutyTimer!=0) PWM_OUT=1;
01 	else PWM_OUT=0;
01 }


6 EXT_DRIVERS.C

外部驅動程式,包括 HT45B0F、HT1382。 HT45B0F 是一個透過 SPI 介面操作的串列埠控制器。 HT66F60 是一個透過 IIC MASTER 操作的萬年曆控制器。

DEBUG.C
01 #define UART_IDLE_STATE 0
01 #define UART_MONITOR_STATE 1
01 #pragma rambank0
01 bit UartTxing;
01 #pragma norambank
01 UART_CONTROL UartCtrl;
01 UART_BUFFER_CONTROL TxBuffer;
01 UART_BUFFER_CONTROL RxBuffer;
01 void UartInit(void){
01  #if UART_HBRG==0
01     SimCtrl.Command=UART_WRITEREG+UART_REG_BRG;
01     SimCtrl.Data=UART_BRG; 
01     SimSpiWrite();
01     SimCtrl.Command=UART_WRITEREG+UART_REG_UCR2;
01     SimCtrl.Data=0b11000101; 
01     SimSpiWrite();
01     SimCtrl.Command=UART_WRITEREG+UART_REG_UCR1;
01     SimCtrl.Data=0b10000000; 
01     SimSpiWrite();
01  #else
01     SimCtrl.Command=UART_WRITEREG+UART_REG_BRG; 
01     SimCtrl.Data=UART_BRG;
01     SimSpiWrite();
01     SimCtrl.Command=UART_WRITEREG+UART_REG_UCR2;
01     SimCtrl.Data=0b11100101; 
01     SimSpiWrite();
01     SimCtrl.Command=UART_WRITEREG+UART_REG_UCR1; 
01     SimCtrl.Data=0b10000000; 
01     SimSpiWrite();
01  #endif
01     TxBuffer.Get=0;
01     TxBuffer.Put=0;
01     RxBuffer.Get=0;
01     RxBuffer.Put=0;
01 	UartCtrl.Usr=0;
01     UartCtrl.State=UART_MONITOR_STATE;
01     UartCtrl.Timer=0;
01     UartTxing=0;
01     _xpe=1;
01     _mf4e=1; 
01 }
01 
01 void UartSvc(void){
01 	if((UartCtrl.Flags&UART_RX_FLAG)!=0);
01 	else if((UartCtrl.Flags&UART_TX_FLAG)!=0);
01 	else if(TxBuffer.Put!=TxBuffer.Get);
01 	else return;
01     switch(UartCtrl.State){
01         case UART_IDLE_STATE: 
01             break;
01         case UART_MONITOR_STATE:
01             if(UartCtrl.Flags&UART_RX_FLAG){
01                 UartRxBufferPut(UartCtrl.RxData);
01                 UartCtrl.Flags&=(INT8U)(~UART_RX_FLAG);
01             }
01             if((UartTxing==1)&&((UartCtrl.Flags&UART_TX_FLAG)==0)) break;
01 			UartCtrl.Flags&=(INT8U)(~UART_TX_FLAG);
01 			UartTxing=0;
01 			if(UartTxBufferCheck()==BUFFER_NOT_EMPTY){
01 				UartCtrl.TxData=UartTxBufferGet();
01 				SimCtrl.Command=UART_WRITEFIFO;
01 				SimCtrl.Data=UartCtrl.TxData;
01 				SimSpiWrite();
01 				UartTxing=1;
01 			}
01             break; 
01     }
01 }
01 void UartBufferReset(void){
01     TxBuffer.Get=0;
01     TxBuffer.Put=0;
01     RxBuffer.Get=0;
01     RxBuffer.Put=0;
01 }
01 INT8U UartRxBufferCheck(void){
01     if(RxBuffer.Put!=RxBuffer.Get){
01         if(RxBuffer.Put==(UART_MAX_BUFFER_SIZE-1)){
01             if(RxBuffer.Get==0) return BUFFER_FULL;
01             else return BUFFER_NOT_EMPTY;
01         }
01         else{
01             if((RxBuffer.Put+1)==RxBuffer.Get) return BUFFER_FULL;
01             else return BUFFER_NOT_EMPTY;
01         }
01     }
01     else return BUFFER_EMPTY;
01 }
01 void UartRxBufferPut(INT8U Data){
01     if(UartRxBufferCheck()==BUFFER_FULL) return;
01     if(RxBuffer.Put==(UART_MAX_BUFFER_SIZE-1)){
01         RxBuffer.Data[RxBuffer.Put]=Data;
01         RxBuffer.Put=0;
01     }
01     else{
01         RxBuffer.Data[RxBuffer.Put]=Data;
01         RxBuffer.Put++;
01     }
01 }
01 INT8U UartRxBufferGet(void){
01     INT8U Data;
01 
01     if(UartRxBufferCheck()==BUFFER_EMPTY) return 0;
01     if(RxBuffer.Get==(UART_MAX_BUFFER_SIZE-1)){
01         Data=RxBuffer.Data[RxBuffer.Get];
01         RxBuffer.Get=0;
01     }
01     else{
01         Data=RxBuffer.Data[RxBuffer.Get];
01         RxBuffer.Get++;
01     }
01     return Data;
01 }
01 INT8U UartTxBufferCheck(void){
01     if(TxBuffer.Put!=TxBuffer.Get){
01         if(TxBuffer.Put==(UART_MAX_BUFFER_SIZE-1)){
01             if(TxBuffer.Get==0) return BUFFER_FULL;
01             else return BUFFER_NOT_EMPTY;
01         }
01         else{
01             if((TxBuffer.Put+1)==TxBuffer.Get) return BUFFER_FULL;
01             else return BUFFER_NOT_EMPTY;
01         }
01     }
01     else return BUFFER_EMPTY;
01 }
01 void UartTxBufferPut(INT8U Data){
01     if(UartTxBufferCheck()==BUFFER_FULL) return;
01     if(TxBuffer.Put==(UART_MAX_BUFFER_SIZE-1)){
01         TxBuffer.Data[UART_MAX_BUFFER_SIZE-1]=Data;
01         TxBuffer.Put=0;
01     }
01     else{
01         TxBuffer.Data[TxBuffer.Put]=Data;
01         TxBuffer.Put++;
01     }
01 }
01 INT8U UartTxBufferGet(void){
01     INT8U Data;
01 
01     if(UartTxBufferCheck()==BUFFER_EMPTY) return 0;
01     if(TxBuffer.Get==(UART_MAX_BUFFER_SIZE-1)){
01         Data=TxBuffer.Data[UART_MAX_BUFFER_SIZE-1];
01         TxBuffer.Get=0;
01     }
01     else{
01         Data=TxBuffer.Data[TxBuffer.Get];
01         TxBuffer.Get++;
01     }
01     return Data;
01 }
01 void UartCharTx(INT8U Data){
01     //while(UartTxBufferCheck()==BUFFER_FULL) UartSvc();
01     while(UartTxBufferCheck()!=BUFFER_EMPTY) UartSvc();
01     UartTxBufferPut(Data);
01     UartSvc();
01 }
01 void UartStringTx(const char *pString){
01     while(*pString!=0){ 
01         UartCharTx(*pString);
01         pString++;
01     }
01 }
01 #define RTC_INTRQ _1d_5 
01 #define RTC_FOUT _1d_5 
01 #pragma norambank
01 RTC_CONTROL RtcCtrl;
01 void RtcInit(void){
01 	RtcCtrl.Second=0x00;
01     RtcCtrl.Minute=0x41;
01 	RtcCtrl.Hour=0x08;
01     RtcCtrl.WeekDay=5;
01 	RtcCtrl.Date=0x14;
01     RtcCtrl.Month=0x04;
01 	RtcCtrl.Year=0x12;
01 	RtcCtrl.Address=0;
01 	RtcCtrl.Data=0;
01 	RtcCtrl.Timer=0;
01 	RtcCtrl.Flag=0;
01 	RtcCtrl.State=RtcInitialState;
01 }
01 void RtcSvc(void){
01 	if(RtcCtrl.Timer!=0) return;
01 	RtcCtrl.Timer=200;
01     switch(RtcCtrl.State){
01 	    case RtcIdleState: 
01 		    break;
01 		case RtcInitialState:
01 			RtcCtrl.Address=RTC_REG_YEAR;
01 			RtcRegisterRead();
01 			RtcCtrl.Year=RtcCtrl.Data;
01 			RtcCtrl.Address=RTC_REG_MONTH;
01 			RtcRegisterRead();
01 			RtcCtrl.Month=RtcCtrl.Data;
01 			RtcCtrl.Address=RTC_REG_DATE;
01 			RtcRegisterRead();
01 			RtcCtrl.Date=RtcCtrl.Data;
01 			RtcCtrl.Address=RTC_REG_HOURS;
01 			RtcRegisterRead();
01 			RtcCtrl.Hour=RtcCtrl.Data;
01 			RtcCtrl.Hour&=0x7f;
01             if(RtcCtrl.Data&0x08) RtcCtrl.Flag|=RTC_FLAG_12VS24;
01             else RtcCtrl.Flag&=(INT8U)(~RTC_FLAG_12VS24);
01 			RtcCtrl.Address=RTC_REG_MINUTES;
01 			RtcRegisterRead();
01 			RtcCtrl.Minute=RtcCtrl.Data;
01 			RtcCtrl.Address=RTC_REG_SECONDS;
01 			RtcRegisterRead();
01 			RtcCtrl.Second=RtcCtrl.Data;
01             if(RTC_FOUT==LOW) RtcCtrl.State=RtcFoutLowState;
01             else RtcCtrl.State=RtcFoutLowState;
01 		    break;
01 		case RtcFoutLowState:
01 		    if(RTC_FOUT==LOW) break;
01 		    //todo TIME++;
01 		    if(RtcCtrl.Second!=0x59){ //RtcCtrl.Second++
01 		    	if((RtcCtrl.Second&0x0f)!=0x09) RtcCtrl.Second++;
01 		    	else{
01 		    		RtcCtrl.Second&=0xf0;
01 		    		RtcCtrl.Second+=0x10;
01 		    	}
01 		    }
01 		    else{ //RtcCtrl.Minute++
01 		    	RtcCtrl.Second=0;
01 		        if(RtcCtrl.Minute!=0x59){
01 			    	if((RtcCtrl.Minute&0x0f)!=0x09) RtcCtrl.Minute++;
01 			    	else{
01 			    		RtcCtrl.Minute&=0xf0;
01 			    		RtcCtrl.Minute+=0x10;
01 			    	}
01 			    }
01 		    	else{ //RtcCtrl.Hour++
01 		    	    RtcCtrl.Minute=0;
01 		    	    if(RtcCtrl.Hour!=0x23){
01 		    	    	if(RtcCtrl.Hour<0x20){
01 					    	if((RtcCtrl.Hour&0x0f)!=0x09) RtcCtrl.Hour++;
01 					    	else{
01                                 RtcCtrl.Hour&=0xf0;
01 					    		RtcCtrl.Hour+=0x10;
01 					    	}
01 		    	    	}
01 				    	else if((RtcCtrl.Hour&0x0f)!=0x03) RtcCtrl.Hour++;
01 				    	else RtcCtrl.Hour=0x00;
01 				    }
01 		    	}
01 		    }
01 		    RtcCtrl.State=RtcFoutHighState;
01 		    break;
01 		case RtcFoutHighState:
01 		    if(RTC_FOUT==HIGH) break;
01 		    DISPLAY_YEAR0=RtcHex2Segment7(RtcCtrl.Year&0x0f);
01 		    DISPLAY_YEAR1=RtcHex2Segment7((RtcCtrl.Year&0xf0)>>4);
01 		    DISPLAY_MONTH0=RtcHex2Segment7(RtcCtrl.Month&0x0f);;
01 		    DISPLAY_MONTH1=RtcHex2Segment7((RtcCtrl.Month&0xf0)>>4);
01 		    DISPLAY_DATE0=RtcHex2Segment7(RtcCtrl.Date&0x0f);
01 		    DISPLAY_DATE1=RtcHex2Segment7((RtcCtrl.Date&0xf0)>>4);
01 		    DISPLAY_HOUR0=RtcHex2Segment7(RtcCtrl.Hour&0x0f);;
01 		    DISPLAY_HOUR1=RtcHex2Segment7((RtcCtrl.Hour&0xf0)>>4);
01 		    DISPLAY_MINUTE0=RtcHex2Segment7(RtcCtrl.Minute&0x0f);
01 		    DISPLAY_MINUTE1=RtcHex2Segment7((RtcCtrl.Minute&0xf0)>>4);
01 		    DISPLAY_SECOND0=RtcHex2Segment7(RtcCtrl.Second&0x0f);;
01 		    DISPLAY_SECOND1=RtcHex2Segment7((RtcCtrl.Second&0xf0)>>4);
01 		    RtcCtrl.State=RtcFoutLowState;
01 		    break;
01 	}    
01 }
01 INT8U RtcHex2Segment7(INT8U Data){
01 	if(Data==0) return SEGMENT7_0;
01 	if(Data==1) return SEGMENT7_1;
01 	if(Data==2) return SEGMENT7_2;
01 	if(Data==3) return SEGMENT7_3;
01 	if(Data==4) return SEGMENT7_4;
01 	if(Data==5) return SEGMENT7_5;
01 	if(Data==6) return SEGMENT7_6;
01 	if(Data==7) return SEGMENT7_7;
01 	if(Data==8) return SEGMENT7_8;
01 	if(Data==9) return SEGMENT7_9;
01 	return SEGMENT7_NONE;
01 }
01 void RtcRegisterWrite(void){
01     IicMasterStartSignal();
01     IicMasterTxByte(0xd0);
01     IicMasterTxAckGet();
01     IicMasterTxByte(RtcCtrl.Address);
01     IicMasterTxAckGet();
01     IicMasterTxByte(RtcCtrl.Data);
01     IicMasterTxAckGet();
01     IicMasterStopSignal();
01 }
01 void RtcRegisterRead(void){
01     IicMasterStartSignal();
01     IicMasterTxByte(0xd0);
01     IicMasterTxAckGet();
01     IicMasterTxByte(RtcCtrl.Address);
01     IicMasterTxAckGet();
01     IicMasterStopSignal();
01 
01     IicMasterStartSignal();
01     IicMasterTxByte(0xd1);
01     IicMasterTxAckGet();
01     RtcCtrl.Data=IicMasterRxByte();
01     IicMasterRxAckPut();
01     IicMasterStopSignal();
01 }


7 KEY.C

KEY.C 是按鍵服務程式,用來讀取使用者的按鍵輸入。

KEY.C
01 #define KeyIdleState              0
01 #define KeyReleaseState           1
01 #define KeyPressTransitionState   2
01 #define KeyPressState             3
01 #define KeyReleaseTransitionState 4
01 
01 #define KeyScan0 _29_4
01 #define KeyScan1 _29_7
01 #define KeyScan2 _2c_0
01 #define KeyButton0 _1d_4
01 #define KeyButton1 _29_3
01 #define KeyButton2 _29_7
01 #define KeyButton3 _2c_1
01 
01 #pragma rambank0
01 KEY_CONTROL KeyCtrl; 
01 INT16U KeyValue;
01 
01 #pragma rombank0
01 void KeyInit(void){
01     KeyCtrl.HasKey=FALSE;
01     KeyCtrl.State=KeyReleaseState;
01     KeyValue=0;
01     KeyCtrl.Timer=0;
01 }
01 void KeySvc(void){
01     if(KeyCtrl.Timer!=0) return;
01     KeyCtrl.Timer=KEY_DEBOUNCE_TIME;
01     switch(KeyCtrl.State){
01         case KeyReleaseState:
01             KeyValueGet();
01             if(KeyValue!=0){
01                 KeyCtrl.KeyValue=KeyValue;     
01                 KeyCtrl.ScanKeyCounter=0;        
01                 KeyCtrl.HitKeyCounter=0;
01                 KeyCtrl.State=KeyPressTransitionState;
01             }
01             break;
01         case KeyPressTransitionState:
01             KeyValueGet();
01             if(KeyValue!=0){
01                 if(KeyValue==KeyCtrl.KeyValue){
01                      KeyCtrl.HitKeyCounter++;
01                 }
01                 else{                            
01                     KeyCtrl.KeyValue=KeyValue;   
01                     KeyCtrl.HitKeyCounter=0;     
01                     KeyCtrl.ScanKeyCounter=0;    
01                 }
01             }
01             KeyCtrl.ScanKeyCounter++;
01             if(KeyCtrl.ScanKeyCounter>=KEY_DEBOUNCE_NUMBER){
01                 if(KeyCtrl.HitKeyCounter>=KEY_ACCEPT_NUMBER){
01                     if(KeyCtrl.HasKey==FALSE){
01                         KeyCtrl.HasKey=TRUE;
01                         KeyCtrl.HasKeyValue=KeyCtrl.KeyValue;
01                         KeyCtrl.RepeatTimer=KEY_REPEAT_TIME;
01                         KeyCtrl.State=KeyPressState;
01                     }
01                     else{ 
01                         KeyCtrl.State=KeyPressState;
01                     }
01                 }
01                 else{ 
01                     KeyCtrl.State=KeyReleaseState;
01                 }
01             }
01             break;
01         case KeyPressState:
01             KeyValueGet();
01             if(KeyValue!=KeyCtrl.HasKeyValue){
01                 KeyCtrl.ScanKeyCounter=0;        
01                 KeyCtrl.HitKeyCounter=0;
01                 KeyCtrl.State=KeyReleaseTransitionState;
01             }
01             else{
01                 if(KeyCtrl.RepeatTimer==0){ 
01                     if(KeyCtrl.HasKey==FALSE){
01                         KeyCtrl.HasKey=TRUE;
01                         KeyCtrl.HasKeyValue=KeyCtrl.KeyValue;
01                         KeyCtrl.RepeatTimer=KEY_REPEAT_TIME;
01                     }
01                 }
01                 //todo: time delay for key repeat
01             }
01             break;
01         case KeyReleaseTransitionState:
01             KeyCtrl.ScanKeyCounter++; 
01             if((KeyValue&0x80)==0x80){
01                 if(KeyCtrl.ScanKeyCounter>=KEY_DEBOUNCE_NUMBER){
01                     KeyCtrl.ScanKeyCounter=0;
01                     KeyCtrl.HitKeyCounter=0;
01                 } 
01             }
01             else{
01                 KeyCtrl.HitKeyCounter++;
01                 if(KeyCtrl.ScanKeyCounter>=KEY_DEBOUNCE_NUMBER){
01                     if(KeyCtrl.HitKeyCounter>=KEY_ACCEPT_NUMBER){
01                         KeyCtrl.State=KeyReleaseState;
01                     }
01                     else{
01                         KeyCtrl.ScanKeyCounter=0;
01                         KeyCtrl.HitKeyCounter=0;
01                     }
01                 } 
01             }
01             break;
01     }
01 }
01 INT8U KeyStatusCheck(void){
01     if(KeyCtrl.HasKey==TRUE) return TRUE;
01     else return FALSE;
01 }
01 INT16U KeyGet(void){
01     if(KeyCtrl.HasKey==TRUE){
01         KeyCtrl.HasKey=FALSE;
01         return KeyCtrl.HasKeyValue;
01     }
01     else return 0;
01 }
01 void KeyValueGet(void){
01     KeyValue=0;
01     KeyScan0=1;
01     KeyScan1=0;
01     KeyScan2=0;
01     if(KeyButton0==1) KeyValue|=KEY_0;
01     if(KeyButton1==1) KeyValue|=KEY_1;
01     if(KeyButton2==1) KeyValue|=KEY_2;
01     if(KeyButton3==1) KeyValue|=KEY_3;
01     KeyScan0=0;
01     KeyScan1=1;
01     KeyScan2=0;
01     if(KeyButton0==1) KeyValue|=KEY_4;
01     if(KeyButton1==1) KeyValue|=KEY_5;
01     if(KeyButton2==1) KeyValue|=KEY_6;
01     if(KeyButton3==1) KeyValue|=KEY_7;
01     KeyScan0=0;
01     KeyScan1=0;
01     KeyScan2=1;
01     if(KeyButton0==1) KeyValue|=KEY_8;
01     if(KeyButton1==1) KeyValue|=KEY_9;
01     if(KeyButton2==1) KeyValue|=KEY_A;
01     if(KeyButton3==1) KeyValue|=KEY_B;
01 }


8 MENU.C

MENU.C 是目錄服務程式,配合按鍵輸入,讓使用者操作目錄系統。


9 MONITOR.C

MONITOR.C 是環境監督服務程式,讀取佈置在環境中的感測器,包括溫溼度感測器。


10 ACTUATOR.C

ACTUATOR.C 是致動器服務程式,用來啟動壓縮機和加熱器等設備。其中,加熱器必須配合 PWM,控制加熱速度。


11 DISPLAY.ASM

DISPLAY.ASM 是面板資訊顯示程式,用來目錄資訊或系統資訊顯示於面板。


12 DEBUG.C

DEBUG.C 是偵錯程式,用來接受偵錯指令,並執行偵錯指令。

DEBUG.C
01 void DebugSvc(void){
01     switch(DebugCtrl.State){
01         case DebugIdleState:
01             return;
01         case DebugStartState:
01             DebugPromptShow();
01             DebugCtrl.State=DebugPoolingState;
01             return;
01         case DebugPoolingState:
01             if(UartRxBufferCheck()!=BUFFER_EMPTY){
01                 DebugCtrl.Data[DebugCtrl.Position]=UartRxBufferGet();
01                 DebugCtrl.Position++;
01             }
01             if(DebugCtrl.Position>0){
01                 if(DebugCtrl.Data[DebugCtrl.Position-1]==0x0d){
01                     DebugCtrl.State=DebugMeetEnterKey;
01                 }
01                 else if(DebugCtrl.Position>=9){
01                     DebugCtrl.Position=0;
01                     DebugCtrl.State=DebugErrorState;
01                 }
01             }
01             return;
01         case DebugMeetEnterKey:
01             if((DebugCtrl.Data[0]=='w')||(DebugCtrl.Data[0]=='W'))
01                 DebugCtrl.Command=DEBUG_COMMAND_WRITE;
01             else if((DebugCtrl.Data[0]=='r')||(DebugCtrl.Data[0]=='R'))
01                 DebugCtrl.Command=DEBUG_COMMAND_READ;
01             else if((DebugCtrl.Data[0]=='d')||(DebugCtrl.Data[0]=='D'))
01                 DebugCtrl.Command=DEBUG_COMMAND_DUMP;
01             else if(DebugCtrl.Data[0]==0x0D){
01                 DebugCtrl.Position=0;
01                 DebugCtrl.State=DebugStartState;
01                 return;
01             }
01             else{
01                 DebugCtrl.State=DebugErrorState;
01                 return;
01             }
01             if(DebugCtrl.Data[1]!=' '){
01                 DebugCtrl.State=DebugErrorState;
01                 return;
01             }
01             if((DebugCtrl.Data[2]>='0')&&(DebugCtrl.Data[2]<='9')) unTemp.uc[0]=DebugCtrl.Data[2]-'0';
01             else if((DebugCtrl.Data[2]>='A')&&(DebugCtrl.Data[2]<='F')) unTemp.uc[0]=DebugCtrl.Data[2]-'A'+10;
01             else if((DebugCtrl.Data[2]>='a')&&(DebugCtrl.Data[2]<='f')) unTemp.uc[0]=DebugCtrl.Data[2]-'a'+10;
01             else{
01                 DebugCtrl.State=DebugErrorState;
01                 return;
01             }
01             if((DebugCtrl.Data[3]>='0')&&(DebugCtrl.Data[3]<='9')){
01                 unTemp.uc[1]=DebugCtrl.Data[3]-'0';
01                 DebugCtrl.Address=unTemp.uc[0]*0x10+unTemp.uc[1];
01                 if((DebugCtrl.Command==DEBUG_COMMAND_READ)||(DebugCtrl.Command==DEBUG_COMMAND_DUMP)){
01                     if((DebugCtrl.Data[4]==' ')||(DebugCtrl.Data[4]==0x0d)){
01                         DebugCtrl.State=DebugExecutionState;
01                         return;
01                     }
01                     else{
01                         DebugCtrl.State=DebugErrorState;
01                         return;
01                     }
01                 }
01                 else if(DebugCtrl.Data[4]!=' '){
01                     DebugCtrl.State=DebugErrorState;
01                     return;
01                 }
01                 ucTemp=5;
01             }
01             else if((DebugCtrl.Data[3]>='A')&&(DebugCtrl.Data[3]<='F')){
01                 unTemp.uc[1]=DebugCtrl.Data[3]-'A'+10;
01                 DebugCtrl.Address=unTemp.uc[0]*0x10+unTemp.uc[1];
01                 if((DebugCtrl.Command==DEBUG_COMMAND_READ)||(DebugCtrl.Command==DEBUG_COMMAND_DUMP)){
01                     if((DebugCtrl.Data[4]==' ')||(DebugCtrl.Data[4]==0x0d)){
01                         DebugCtrl.State=DebugExecutionState;
01                         return;
01                     }
01                     else{
01                         DebugCtrl.State=DebugErrorState;
01                         return;
01                     }
01                 }
01                 else if(DebugCtrl.Data[4]!=' '){
01                     DebugCtrl.State=DebugErrorState;
01                     return;
01                 }
01                 ucTemp=5;
01             }
01             else if((DebugCtrl.Data[3]>='a')&&(DebugCtrl.Data[3]<='f')){
01                 unTemp.uc[1]=DebugCtrl.Data[3]-'a'+10;
01                 DebugCtrl.Address=unTemp.uc[0]*0x10+unTemp.uc[1];
01                 if((DebugCtrl.Command==DEBUG_COMMAND_READ)||(DebugCtrl.Command==DEBUG_COMMAND_DUMP)){
01                     if((DebugCtrl.Data[4]==' ')||(DebugCtrl.Data[4]==0x0d)){
01                         DebugCtrl.State=DebugExecutionState;
01                         return;
01                     }
01                     else{
01                         DebugCtrl.State=DebugErrorState;
01                         return;
01                     }
01                 }
01                 else if(DebugCtrl.Data[4]!=' '){
01                     DebugCtrl.State=DebugErrorState;
01                     return;
01                 }
01                 ucTemp=5;
01             }
01             else if(DebugCtrl.Data[3]==' '){
01                 DebugCtrl.Address=unTemp.uc[0];
01                 if((DebugCtrl.Command==DEBUG_COMMAND_READ)||(DebugCtrl.Command==DEBUG_COMMAND_DUMP)){
01                     if((DebugCtrl.Data[4]==' ')||(DebugCtrl.Data[4]==0x0d)){
01                         DebugCtrl.State=DebugExecutionState;
01                         return;
01                     }
01                     else{
01                         DebugCtrl.State=DebugErrorState;
01                         return;
01                     }
01                 }
01                 ucTemp=4;
01             }
01             else if(DebugCtrl.Data[3]==0x0d){
01                 DebugCtrl.Address=unTemp.uc[0];
01                 if((DebugCtrl.Command==DEBUG_COMMAND_READ)||(DebugCtrl.Command==DEBUG_COMMAND_DUMP)){
01                     DebugCtrl.State=DebugExecutionState;
01                     return;
01                 }
01                 else{
01                     DebugCtrl.State=DebugErrorState;
01                     return;
01                 }
01             }
01             else{
01                 DebugCtrl.State=DebugErrorState;
01                 return;
01             }
01             if((DebugCtrl.Command==DEBUG_COMMAND_READ)||(DebugCtrl.Command==DEBUG_COMMAND_DUMP)){  // Never reach
01                 DebugCtrl.State=DebugExecutionState;
01                 return;
01             }
01             else{
01                 if((DebugCtrl.Data[ucTemp]>='0')&&(DebugCtrl.Data[ucTemp]<='9')) unTemp.uc[0]=DebugCtrl.Data[ucTemp]-'0';
01                 else if((DebugCtrl.Data[ucTemp]>='A')&&(DebugCtrl.Data[ucTemp]<='F')) unTemp.uc[0]=DebugCtrl.Data[ucTemp]-'A'+10;
01                 else if((DebugCtrl.Data[ucTemp]>='a')&&(DebugCtrl.Data[ucTemp]<='f')) unTemp.uc[0]=DebugCtrl.Data[ucTemp]-'a'+10;
01                 else{
01                     DebugCtrl.State=DebugErrorState;
01                     return;
01                 }
01                 ucTemp++;
01                 if((DebugCtrl.Data[ucTemp]>='0')&&(DebugCtrl.Data[ucTemp]<='9')){
01                     unTemp.uc[1]=DebugCtrl.Data[ucTemp]-'0';
01                     DebugCtrl.Value=unTemp.uc[0]*0x10+unTemp.uc[1];
01                     ucTemp++;
01                     if((DebugCtrl.Data[ucTemp]==' ')||(DebugCtrl.Data[ucTemp]==0x0D));
01                     else{
01                         DebugCtrl.State=DebugErrorState;
01                         return;
01                     }
01                 }
01                 else if((DebugCtrl.Data[ucTemp]>='A')&&(DebugCtrl.Data[ucTemp]<='F')){
01                     unTemp.uc[1]=DebugCtrl.Data[ucTemp]-'A'+10;
01                     DebugCtrl.Value=unTemp.uc[0]*0x10+unTemp.uc[1];
01                     ucTemp++;
01                     if((DebugCtrl.Data[ucTemp]==' ')||(DebugCtrl.Data[ucTemp]==0x0D));
01                     else{
01                         DebugCtrl.State=DebugErrorState;
01                         return;
01                     }
01                 }
01                 else if((DebugCtrl.Data[ucTemp]>='a')&&(DebugCtrl.Data[ucTemp]<='f')){
01                     unTemp.uc[1]=DebugCtrl.Data[ucTemp]-'a'+10;
01                     DebugCtrl.Value=unTemp.uc[0]*0x10+unTemp.uc[1];
01                     ucTemp++;
01                     if((DebugCtrl.Data[ucTemp]==' ')||(DebugCtrl.Data[ucTemp]==0x0D));
01                     else{
01                         DebugCtrl.State=DebugErrorState;
01                         return;
01                     }
01                 }
01                 else if(DebugCtrl.Data[ucTemp]==' '){
01                     DebugCtrl.Value=unTemp.uc[0];
01                 }
01                 else if(DebugCtrl.Data[ucTemp]==0x0D){
01                     DebugCtrl.Value=unTemp.uc[0];
01                 }
01                 else{
01                     DebugCtrl.State=DebugErrorState;
01                     return;
01                 }
01             }
01             DebugCtrl.State=DebugExecutionState;
01             return;
01         case DebugErrorState:
01             DebugLineChange();
01             DebugStringPrint(0);
01             DebugCtrl.Position=0;
01             DebugCtrl.State=DebugStartState;
01             return;
01         case DebugExecutionState:
01             if((DebugCtrl.Command==DEBUG_COMMAND_WRITE)&&(DebugCtrl.Address==0)){
01                 DebugcmdCtrl.State=DebugCtrl.Value;
01             }
01             DebugCtrl.Position=0;
01             DebugCtrl.State=DebugStartState;
01             return;
01     }
01 }
01 void DebugcmdSvc(void){
01     switch(DebugcmdCtrl.State){
01         case 0:
01         	break;
01         case 1:
01         	DebugLineChange();
01         	DebugStringPrint(5);
01         	DebugLineChange();
01         	DebugStringPrint(4);
01         	DebugLineChange();
01         	DebugStringPrint(5);
01         	DebugCtrl.State=DebugStartState; 
01         	DebugcmdCtrl.State=0;
01         	break;
01 		case 2:
01 		    //debug code
01         	DebugcmdCtrl.State=0;
01 			break;
01 		case 3:
01 		    //debug code
01         	DebugcmdCtrl.State=0;
01         	break;
01 		case 4:
01 		    //debug code
01         	DebugcmdCtrl.State=0;
01         	break;
01         default:
01         	DebugcmdCtrl.State=0;
01         	break;
01     }
01 }