//Including the standard file #include <90S8515.h> #include #include #include //Defining constant and states #define begin { #define end } #define LCDwidth 16 #define t1 50 #define t2 15 #define t3 100 #define t4 1 #define t5 200 #define t6 100 #define prescale1 #define clear_on_match #define Start 1 #define Release 2 #define Maybe 3 #define StillPressed 4 #define DebounceRel 5 #define SetMin 6 #define SetHour 7 #define HourSwitch 8 #define OperationStart 9 #define AlarmSetHour 10 #define AlarmSetMin 11 #define EnterCal 12 #define DaySet 13 #define MonthSet 14 #define YearSet 15 #define WeekSet 16 //Variables that have used void initialize(void); void LCD(void); void StateMachine(void); void Operation(void); void clocksetLCD(void); void alarmLCD(void); void Alarm(void); void CurrTime(void); void Trigger(void); unsigned char PushState; unsigned char Function; unsigned char States; unsigned char hrFlag; unsigned char reload; unsigned char time1; unsigned char time2; unsigned char time3; unsigned char time4; unsigned char time5; unsigned char time6; unsigned char lcd_buffer[17]; unsigned char led; unsigned char AMFlag; unsigned char PMFlag; unsigned char LCDcheck; unsigned char buttonpress; unsigned char tempkey; unsigned char secondcounter; unsigned char AlarmhrFlag; unsigned char AlarmAMFlag; unsigned char AlarmPMFlag; unsigned char Alarmcounter; unsigned char OnFlag; unsigned char Alarmbutton; unsigned char TriggerCounter; unsigned int counter; unsigned int second; unsigned int minute; unsigned int hour; unsigned int temphour; unsigned int changinghour; unsigned int settemphour; unsigned int Alarmhour; unsigned int Alarmsettempmin; unsigned int Alarmtemphour; unsigned int Day; unsigned int Month; unsigned int Week; unsigned int Year; unsigned int Weekday; //Assigning PORTC to LCD output #asm .equ __lcd_port=0x15 #endasm //======Timer 0 Interrupt===================================================== interrupt [TIM0_OVF] void timer0_overflow(void) begin TCNT0=reload; if (time1>0) --time1; //To control the LCD display function if (time2>0) --time2; //Detect key press and debounce if (time3>0) --time3; //The major state machine if (time4>0) --time4; //Alarm time checking if (time5>0) --time5; //Triggering the listening mode of the voice kit end //============================================================================= //timer 1 compare-match A ISR interrupt [TIM1_COMPA] void cmpA_overflow(void) begin if (counter==1000) //1 second, interrupt every 1ms, 1000 ms=1 sec begin if (secondcounter==0) secondcounter=1; else secondcounter=0; counter=0; //--Calender Part------------------------------------------------------------ if ((temphour==23)&&(minute==59)&&(second==59)) begin Day++; //Incrementing day if it is 00:00:00 Weekday++; //Incrementing day of the week if (Weekday>7) Weekday=1; //Reseting day of week after Sunday //Months with 30 days if (((Month==4)||(Month==6)||(Month==9)||(Month==11))&&(Day>30)) begin Day=1; Month++; end //Months with 31 days else if (((Month==1)||(Month==3)||(Month==5)||(Month==7)||(Month==8)||(Month==10)||(Month==12))&&(Day>31)) begin Day=1; Month++; end else if ((Month==2)&&(Day==30)&&(Year%4==0)) //February with 29 days begin Day=1; Month++; end else if ((Month==2)&&(Day==29)&&(Year%4!=0)) //February with 28 days begin Day=1; Month++; end if(Month>12) //Resetting month after December begin Month=1; Year++; end end //--Time Part------------------------------------------------------------------------------ if (second < 59) second++; //Incrementing the second else begin second=0; //Resetting second to 0 if second=60 if (minute < 59) minute++; //Incrementing minute else begin if (hrFlag==0) //If it is in 12-HR mode begin minute=0; if (AMFlag==1) //If it is AM begin temphour++; //Incrementing hour, temphour is in 24HR mode always if (temphour==12) //If it is 12:00pm begin AMFlag=0; PMFlag=1; end hour=temphour; end else if (PMFlag==1) //If is is PM begin temphour++; //Minus 12 from temphour to obtain the time in 12HR mode if ((temphour>12) && (temphour<24)) hour=temphour-12; else if (temphour==24) //If it is 12:00am midnight begin hour=temphour-12; temphour=0; //Resetting temphour to 0 AMFlag=1; //Back to AM PMFlag=0; end end end if (hrFlag==1) //If it is in 24HR mode begin minute=0; if (temphour == 23) //Resetting temphour if is 12:00 midnight begin temphour = 0; hour=temphour; end else begin temphour++; //Else increment temphour hour=temphour; end end end end end else counter++; end //=============================================================================================== void main(void) begin initialize(); while(1) begin if (time1==0) begin if (LCDcheck==1) LCD(); //The normal LCD display mode else if (LCDcheck==2) alarmLCD(); //The alarm setting mode else clocksetLCD(); //The clock setting mode end if (time2==0) StateMachine(); //The detect button press and debounce if (time3==0) Operation(); //The main state machine if (time4==0) Alarm(); //Detect if current time = alarm time if (time5==0) Trigger(); //Triggering the listening mode //of the voice chip end end //================================================================================================ void StateMachine(void) begin time2=t2; switch (PushState) begin case Start: begin PushState=Release; //Go to Release state end break; case Release: begin buttonpress=0; //No button is pressed if (PINA!=0xff) //If button is pressed begin tempkey=PINA; PushState=Maybe; //Go to Maybe state end else PushState=Release; //Go back to Release state end break; case Maybe: begin if (tempkey==PINA) //If the key is still pressing begin buttonpress=1; //Confirm button is pressed PushState=StillPressed; //Go to StillPressed end else PushState=Release; //Go to Release state end break; case StillPressed: begin if (tempkey==PINA) PushState=StillPressed; //Button still pressed, stay here else PushState=DebounceRel; //Else go to DebounceRel end break; case DebounceRel: begin buttonpress=0; if (tempkey==PINA) PushState=StillPressed; //Still pressed? Go to StillPressed else PushState=Release; //Go to Release if button is released end break; end end //================================================================================================ void Operation(void) begin time3=t3; if (buttonpress==1) //If button is pressed begin if (PINA.6==0) //If the light button is pressed begin if (PORTD.2==0) PORTD.2=1; //Turn on the LEDs else PORTD.2=0; //Turn them off end switch (Function) begin case OperationStart: begin if (buttonpress==1) //If button is pressed begin if (PINA.3==0) //If the 12HR/24HR button is pressed begin lcd_clear(); CurrTime(); Function=HourSwitch; end else if ((PINA.0==0)) //If the Set button is pressed begin LCDcheck=0; CurrTime(); Function=SetHour; end else if (PINA.1==0) //If the Alarm Set button is pressed begin AlarmhrFlag=hrFlag; //Telling the alarm mode whether it is //in 12HR or 24HR mode LCDcheck=2; //Change LCD display mode CurrTime(); Function=AlarmSetHour; end else if ((PINA.4==0)||(PINA.5==0)) //If the Alarm on/off button //is pressed/ voice is recog. begin if (Alarmbutton==0) Alarmbutton=1; //Alram off, turn it on else if (Alarmbutton==1) //Alarm on, turn it off begin CurrTime(); OnFlag=0; //Turn off the alarm Alarmbutton=0; end end end else Function=OperationStart; //Go back to OperationStart end break; case HourSwitch: //Changing between 12HR / 24HR begin lcd_clear(); CurrTime(); if (hrFlag==0) begin hrFlag=1; if ((temphour>12)||(temphour==0)) hour=temphour; end else begin hrFlag=0; if ((temphour>12)&&(temphour<24)) hour=temphour-12; else if (temphour==0) hour=12; end Function=OperationStart; end break; case SetHour: //Time Setting (Hour Setting) begin if ((PINA.1==0)) //If the increment button is pressed begin if (hrFlag==0) //If it is now in 12HR mode begin temphour++; //Increment hour if (temphour>12) hour=temphour-12; else hour=temphour; if (temphour>=12) //If it is now 12:00pm noon begin AMFlag=0; //PM PMFlag=1; end else begin AMFlag=1; //else AM PMFlag=0; end if (temphour==24) //If it is now 12:00am midnight begin temphour=0; //Resetting temphour=0 AMFlag=1; //AM PMFlag=0; end end else begin //If it is now in 24HR mode temphour++; if (temphour == 24) //Resetting temphour if it is 12:00am begin temphour = 0; hour=0; end else hour=temphour; if(temphour>=12) //If it is now 12:00pm begin PMFlag=1; //PM AMFlag=0; end else if (temphour==0) //If it is now 12:00am begin PMFlag=0; //AM AMFlag=1; end end Function=SetHour; //Go back to SetHour end else if (PINA.0==0) Function=SetMin; //If Set button is pressed, go to SetMin else Function=SetHour; //Go to SetHour end break; case SetMin: //Clock setting (Minute set) begin if (PINA.1==0) //If increment button is pressed, add minute begin minute++; if (minute > 59) minute=0; Function=SetMin; end else if (PINA.2==0) //If decrement button is pressed, decrement minute begin minute--; if (minute == -1) minute=59; Function=SetMin; end else if (PINA.0==0) //If Set button is pressed, go to DaySet begin LCDcheck=1; Function=DaySet; end else Function=SetMin; end break; case DaySet: //Calender, setting the day of month begin if (PINA.1==0) //If increment button is pressed, increment Day begin Day++; if (Day>31) Day=1; end else if (PINA.2==0) //If decrement button is pressed, decrement Day begin Day--; if (Day<1) Day=31; end else if (PINA.0==0) //If Set button is pressed, go to MonthSet begin LCDcheck=1; lcd_clear(); CurrTime(); Function=MonthSet; end else Function=DaySet; //Go to DaySet end break; case MonthSet: //Calender, setting the month of the year begin if (PINA.1==0) //Incrememnt Month when increment button is pressed begin Month++; if (Month>12) Month=1; end else if (PINA.0==0) Function=YearSet; //If pressed Set, go to YearSet else Function=MonthSet; end break; case YearSet: //Calender, setting the year begin if (PINA.1==0) Year++; //Increment year if increment button is pressed else if (PINA.2==0) Year--; //Decrement year if decrement button is pressed else if (PINA.0==0) //Go to WeekSet if Set button is pressed begin LCDcheck=1; lcd_clear(); CurrTime(); Function=WeekSet; end else Function=YearSet; end break; case WeekSet: //Calender, setting day of the week begin if (PINA.1==0) //Increment day of the week if increment button is pressed begin Weekday++; if (Weekday>7) Weekday=1; end else if (PINA.2==0) //Decrement day of the week if decrement button is pressed begin Weekday--; if (Weekday<1) Weekday=7; end else if (PINA.0==0) //Go to OperationStart if Set is pressed begin LCDcheck=1; lcd_clear(); CurrTime(); Function=OperationStart; end else Function=WeekSet; //Go to WeekSet end break; //=================================================================================== //Alarm setting part, it works basically the same as SetHour and SetMin case AlarmSetHour: //Setting Alarm hour begin if ((PINA.1==0)) //If increment button is pressed begin if (AlarmhrFlag==0) //If it is in 12HR mode begin Alarmtemphour++; if (Alarmtemphour>12) Alarmhour=Alarmtemphour-12; else Alarmhour=Alarmtemphour; if (Alarmtemphour>=12) begin AlarmAMFlag=0; AlarmPMFlag=1; end else begin AlarmAMFlag=1; AlarmPMFlag=0; end if (Alarmtemphour==24) begin Alarmtemphour=0; AlarmAMFlag=1; AlarmPMFlag=0; end end else begin //If it is in 24HR mode Alarmtemphour++; if (Alarmtemphour == 24) begin Alarmtemphour = 0; Alarmhour=0; end else Alarmhour=Alarmtemphour; if(Alarmtemphour>=12) begin AlarmPMFlag=1; AlarmAMFlag=0; end else if (Alarmtemphour==0) begin AlarmPMFlag=0; AlarmAMFlag=1; end end Function=AlarmSetHour; end else if (PINA.0==0) Function=AlarmSetMin; //Go to AlarmSetMin else Function=AlarmSetHour; //Go to AlarmSetHour end break; case AlarmSetMin: //Setting the Alarm minute begin if ((PINA.1==0)) //Increment minute if increment is pressed begin Alarmsettempmin++; if (Alarmsettempmin > 59) Alarmsettempmin=0; end else if ((PINA.2==0)) //Decrement minute if decrement is pressed begin Alarmsettempmin--; if (Alarmsettempmin == -1) Alarmsettempmin=59; end else if ((PINA.0==0)) //Go to OperationStart if Set button is pressed begin LCDcheck=1; lcd_clear(); CurrTime(); Function=OperationStart; end else Function=AlarmSetMin; end break; end end if (Function==HourSwitch) buttonpress=1; else buttonpress=0; //This forces the statemachine to stop running unless a button is pressed //as buttonpress is set to 1 in StateMachine end //================================================================================================ //================================================================================================= void CurrTime(void) //Outputting the Month, Day of the week. //Outputting the format of Day, Month, Year and Day of the month if in //setting mode begin lcd_clear(); lcd_gotoxy(0,0); sprintf(lcd_buffer,"%01d",Day); lcd_puts(lcd_buffer); lcd_gotoxy(3,0); if (Month==1) lcd_putsf("Jan"); if (Month==2) lcd_putsf("Feb"); if (Month==3) lcd_putsf("Mar"); if (Month==4) lcd_putsf("Apr"); if (Month==5) lcd_putsf("May"); if (Month==6) lcd_putsf("Jun"); if (Month==7) lcd_putsf("Jul"); if (Month==8) lcd_putsf("Aug"); if (Month==9) lcd_putsf("Sep"); if (Month==10) lcd_putsf("Oct"); if (Month==11) lcd_putsf("Nov"); if (Month==12) lcd_putsf("Dec"); lcd_gotoxy(7,0); sprintf(lcd_buffer,"%01d",Year); lcd_puts(lcd_buffer); lcd_gotoxy(12,0); if (Weekday==1) lcd_putsf("Mon"); if (Weekday==2) lcd_putsf("Tue"); if (Weekday==3) lcd_putsf("Wed"); if (Weekday==4) lcd_putsf("Thr"); if (Weekday==5) lcd_putsf("Fri"); if (Weekday==6) lcd_putsf("Sat"); if (Weekday==7) lcd_putsf("Sun"); if ((Function==DaySet)||(Function==MonthSet)||(Function==YearSet)||(Function==WeekSet)) begin lcd_gotoxy(0,1); if (Function==DaySet) lcd_putsf("Day?"); else if (Function==MonthSet) lcd_putsf("Month?"); else if (Function==YearSet) lcd_putsf("Year?"); else if (Function==WeekSet) lcd_putsf("Day of week?"); end end //================================================================================================ void LCD(void) //Normal LCD display begin time1=t1; if ((Function==DaySet)||(Function==MonthSet)||(Function==YearSet)||(Function==WeekSet)) CurrTime(); else begin CurrTime(); lcd_gotoxy(0,1); if (hour < 10) //Outputting Hour begin sprintf(lcd_buffer,"%02d",hour); //If hour < 10, add a 0 in front lcd_puts(lcd_buffer); end else //If hour > 10, no 0 in front begin sprintf(lcd_buffer,"%01d",hour); lcd_puts(lcd_buffer); end lcd_gotoxy(3,1); if (minute < 10) begin sprintf(lcd_buffer,"%02d",minute); //If minute < 10, add a 0 in front lcd_puts(lcd_buffer); end else begin sprintf(lcd_buffer,"%1d",minute); //If minute > 10, no 0 in front lcd_puts(lcd_buffer); end lcd_gotoxy(6,1); if (second < 10) begin sprintf(lcd_buffer,"%02d",second); //If second < 10, add a 0 in front lcd_puts(lcd_buffer); end else begin sprintf(lcd_buffer,"%01d",second); //If second > 10, no 0 in front lcd_puts(lcd_buffer); end lcd_gotoxy(9,1); if ((AMFlag == 1) && (hrFlag == 0)) lcd_putsf("AM"); //Output AM/PM/24hr else if ((PMFlag == 1) && (hrFlag == 0)) lcd_putsf("PM"); else if (hrFlag == 1) lcd_putsf("24hr"); if (Alarmbutton==1) //Output letter A if alarm button is on begin lcd_gotoxy(12,1); lcd_putsf("A"); end if (secondcounter==0) //Outputting the flashing dots, syncronize with second begin lcd_gotoxy(2,1); lcd_putsf(":"); lcd_gotoxy(5,1); lcd_putsf(":"); end else begin lcd_gotoxy(2,1); lcd_putsf(" "); lcd_gotoxy(5,1); lcd_putsf(" "); end end end //================================================================================================= void clocksetLCD(void) //LCD format in the clock setting mode begin lcd_gotoxy(2,1); lcd_putsf(":"); lcd_gotoxy(0,0); if (Function==SetHour) lcd_putsf("Hours "); else if (Function=SetMin) lcd_putsf("Minutes"); lcd_gotoxy(0,1); if (hour < 10) begin sprintf(lcd_buffer,"%02d",hour); lcd_puts(lcd_buffer); end else begin sprintf(lcd_buffer,"%01d",hour); lcd_puts(lcd_buffer); end lcd_gotoxy(3,1); if (minute < 10) begin sprintf(lcd_buffer,"%02d",minute); lcd_puts(lcd_buffer); end else begin sprintf(lcd_buffer,"%01d",minute); lcd_puts(lcd_buffer); end lcd_gotoxy(9,1); if ((AMFlag == 1) && (hrFlag == 0)) lcd_putsf("AM"); else if ((PMFlag == 1) && (hrFlag == 0)) lcd_putsf("PM"); end //======================================================================================== void alarmLCD(void) //LCD format in Alarm setting mode begin lcd_gotoxy(2,1); lcd_putsf(":"); lcd_gotoxy(0,0); if (Function==AlarmSetHour) lcd_putsf("Alarm Hours "); else if (Function=AlarmSetMin) lcd_putsf("Alarm Minutes"); lcd_gotoxy(0,1); if (Alarmhour < 10) begin sprintf(lcd_buffer,"%02d",Alarmhour); lcd_puts(lcd_buffer); end else begin sprintf(lcd_buffer,"%01d",Alarmhour); lcd_puts(lcd_buffer); end lcd_gotoxy(3,1); if (Alarmsettempmin < 10) begin sprintf(lcd_buffer,"%02d",Alarmsettempmin); lcd_puts(lcd_buffer); end else begin sprintf(lcd_buffer,"%01d",Alarmsettempmin); lcd_puts(lcd_buffer); end lcd_gotoxy(9,1); if ((AlarmAMFlag == 1) && (AlarmhrFlag == 0)) lcd_putsf("AM"); else if ((AlarmPMFlag == 1) && (AlarmhrFlag == 0)) lcd_putsf("PM"); end //===================================================================================================== void Alarm(void) //To see if the Set Alarm time matches with the current time begin time4=t4; if ((Alarmtemphour==temphour)&&(Alarmsettempmin==minute)&&(Alarmbutton==1)) OnFlag=1; if ((OnFlag==1)) //Turn on the alarm if the OnFlag == 1 begin PORTB=~PORTB; lcd_gotoxy(0,0); lcd_putsf("Sound Alarm "); end else PORTB=0xff; end //===================================================================================================== void Trigger(void) //Noticing the voice kit to be in listening mode, the port pin goes on and //off simultaneously begin time5=t5; if (TriggerCounter<=30) begin TriggerCounter++; PORTD.3=1; end else if ((TriggerCounter>30)&&(TriggerCounter<60) ) begin PORTD.3=0; TriggerCounter++; end else TriggerCounter=0; end //==================================================================================================== void initialize(void) begin //set up the ports DDRA=0x00; // PORT A is an input DDRB=0xff; //PORT B is an output DDRC=0xff; // PORT C is an ouput DDRD=0xff; PORTA=0xff; PORTB=0; UBRR = 51; //================================================================================================ //set up timer 0 //62.5 x (64x.25) microSec = 1.0 mSec, so prescale 64, and count 62 times. reload=256-62; //value for 1 Msec, we are using 4 MHz clock TCNT0=reload; //preload timer 1 so that is interrupts after 1 mSec. TCCR0=3; //prescalar to 64 TIMSK=2; //turn on timer 0 overflow ISR //================================================================================================ //set up timer 1 TIMSK = TIMSK | 0x40; //turn on timer 1 compare match interrupt TCCR1B = 9; OCR1A= 8000; TCNT1 = 0; //and zero the timer //==init the task timers============ time1=t1; time2=t2; time3=t3; time4=t4; time5=t5; time6=t6; //==init variables================== second=45; minute=0; hour=12; temphour=0; settemphour=0; changinghour=0; counter=0; hrFlag=0; AMFlag=1; PMFlag=0; //==Alarm============================= AlarmhrFlag=hrFlag; AlarmAMFlag=1; AlarmPMFlag=0; Alarmtemphour=0; Alarmhour=12; Alarmsettempmin=0; Alarmcounter=0; OnFlag=0; Alarmbutton=0; //==Calender============================ Day=1; Weekday=1; Month=1; Year=2000; //====================================== TriggerCounter=0; secondcounter=0; buttonpress=0; LCDcheck=1; PushState=Start; Function=OperationStart; States=EnterCal; lcd_init(LCDwidth); CurrTime(); //crank up the ISRs #asm sei #endasm end