#include /* for EnableInterrupts macro */ #include "MC9S08LG32.h" #include "utils.h" #include "lcd.h" #include "print.h" #include "lcd_driver.h" //global variables byte mode, ms_count = 0; word period_temp, period_air, duty, adc_value = 0; //globals for ISR //function prototypes void Init_Sys_Peripheral(void); void Init_RTC(void); void Init_TPM(void); void Init_KBI(void); void Init_ADC(void); void Set_ADC(byte); void main(void) { //local variables byte result, i = 0; float frequency_temp, frq_air, temperature, dutycycle, humidity, airmass, pressure, ntc = 0; //system initialisation Init_Sys_Peripheral(); Init_RTC(); Init_TPM(); Init_KBI(); Init_ADC(); EnableInterrupts; //enable interrupts result = lcd_Init(); //init LCD result = lcd_Clear(); //clear LCD while(1) { //PRESSURE, analog if(mode == 2) { lcd_Clear(); TPM2C4SC_CH4IE = 0; //disable interrups T2C4 TPM2C5SC_CH5IE = 0; //disable interrups T2C5 Set_ADC(0x06); //init ADC with chanel 6 while (mode == 2) //to init ADC ch only once { pressure = (5.0 * adc_value) / 65535.0; //calculate to 0-5V value lcd_PrintStringPos("P", 1); lcd_DispDecVal(pressure, 5); } } //NTC- TEMPERATURE, analog if(mode == 4) { lcd_Clear(); TPM1C0SC_CH0IE = 0; //disable interrups T1C0 Set_ADC(0x07); //init ADC with chanel 7 while (mode == 4) //to init ADC ch only once { ntc = (5.0 * adc_value) / 65535.0; //calculate to 0-5V value lcd_PrintStringPos("TN", 1); lcd_DispDecVal(ntc, 5); } } Set_ADC(0x1F); //deinitialize ADC if(mode > 4) mode = 0; //reset mode after 4 -> 5 different modes } } ///////////////////////////////////////////////////////////////////////////////////// //Functions // ///////////////////////////////////////////////////////////////////////////////////// //system clock initialisation void Init_Sys_Peripheral() { SOPT1_COPE = 0; //try ICSC1 = 0x80; //ext ref clock, ICSC2_ERCLKEN = 1; //ext ref clock en for use as ICSERCLK ICSSC_DMX32 = 1; //DCO max freq with 32.768kHz ref X ICSC1_IRCLKEN = 1; //internal reference clock enable //einkommentieren, wenn "try" nicht aktiv //SCI_Init(); // for using uart } //init real time counter void Init_RTC() { SCGC1_RTC = 1; //enable bus clock to RTC module RTCSC_RTCLKS = 0; //intern 1kHz source to RTC RTCSC_RTCPS = 0x8; //prescaler = 0 -> RTC period is 1ms RTCSC_RTIE = 1; //RTC INT enable } //init timer void Init_TPM(void) { //use TPM1 //mode 3 airmass SCGC1_TPM1 = 1; //enalbe bus clock to TPM1 moule TPM1SC = 0x00; //clear TPM1 TPM1SC = 0x09; //selext bus clock, prescaler = 2 (9) //ch0 for rising edges TPM1C0SC = 0x04; //ch0 INT enable, input capture, rising edges //use TPM2 //mode 0 and mode 1 for temp and hum SCGC1_TPM2 = 1; //enable bus clock to TPM2 module TPM2SC = 0x00; //clear TPM2 TPM2SC = 0x0B; //T2 Status Control Reg; bus clock, prescaler = 8 (B) //Ch4 for rising egdes TPM2C4SC = 0x04; //Ch4 INT enable, input capture, rising //Ch5 for duty cycle, detecting negative edge TPM2C5SC = 0x08; //Ch4 INT enable, input capture, falling edge //Ch3 for testing TPM2C3SC = 0x14; TPM2C3V = 0x0001; //toggle LED every time reaching 1 } //init keyboard interrupt void Init_KBI() { SCGC2_KBI = 1; //ebable bus clock to KBI module PINPS1_KBI7 = 1; //KBI7 (on board printed: KBI8) PTH3 KBISC_KBIE = 0; //KBI request disable, for masking false interrupts during init KBISC_KBIMOD = 0; //detecting edges only KBIPE = 0x80; //selects pins for interrupt usage, KBI8 KBIES = 0x00; //KBI edge/level select, 0 = falling edge, low level PTHPE = 0xFF; //Port pull up if(KBISC_KBF) KBISC_KBACK = 1; KBISC_KBIE = 1; //KBI request enable } //init analog to digital converter void Init_ADC(void) { SCGC1_ADC = 1; //enable bus clock to ADC module ADCSC1_AIEN = 1; //enable INT after AD conversion -> enabled in mode 2 or 4 only!! ADCSC2_ADTRG = 1; //RTC triggers ADC every 1ms ADCCFG=0x14; //high speed, bus clock, divided by 1, long sampling time, 12-bit conversion APCTL1 = 0xC0; //pin control, inputs for ADC6 and ADC7 for ADC, not for GPIO } //set adc chanel void Set_ADC(byte chanel) { ADCSC1_ADCO =0; if(chanel < 0x1F) //check whether a suitable chanel is selected, 0x1F is: module off { ADCSC1_ADCH = chanel; //init specified chanel for conversion } else ADCSC1_ADCH = 0x1F; //deinitalize ADC } ///////////////////////////////////////////////////////////////////////////////////// //Interrupt Service Routines // ///////////////////////////////////////////////////////////////////////////////////// //ISR for TPM1C0 rising edges void interrupt VectorNumber_Vtpm1ch0 TPM1C0_ISR() { TPM1C0SC_CH0F; //read flag bit period_air = TPM1C0V; TPM1CNT = 0; //clear TPM1 counter value TPM1C0SC_CH0F = 0; //write zero to clear flag } //ISR for KBI INT Lv16 void interrupt VectorNumber_Vkeyboard KBI_ISR() { static word ms_count_old = 0; if(ms_count == 0xFF) //mode incrementable only once every 256ms { mode++; //increment mode ms_count = 0; //reset ms-counter } KBISC_KBACK = 1; //part of clearing INT flag } //ISR for ADC INT Lv17 void interrupt VectorNumber_Vadc ADC_ISR() { adc_value = ADCR; //give out 12bit conversion result (H,L- byte union) ADCSC1_COCO = 0; //interrupt flag cleared } //ISR for TPM2C4 Lv22 rising edges void interrupt VectorNumber_Vtpm2ch4 TPM2C4_ISR() { TPM2C4SC_CH4F; //read flag bit period_temp = TPM2C4V; TPM2CNT = 0; //clear TPM2 counter value TPM2C4SC_CH4F = 0; //write zero to clear flag } //ISR for TPM2C5 Lv23 void interrupt VectorNumber_Vtpm2ch5 TPM2C5_ISR() { TPM2C5SC_CH5F; //read flag bit duty = TPM2C5V; TPM2C5SC_CH5F = 0; //write zero to clear flag } //ISR for RTC Lv26, used for delay void interrupt VectorNumber_Vrtc RTC_ISR() { if(ms_count < 0xFF) ms_count++; //ms counter for debouncing mode- switch milliseconds++; //upcount ms value for delay RTCSC_RTIF = 1; //clear RTC INT flag }