'******************************************************************* ' Program name gps_clock_rec ' Start Date 22st.Mar.2010 ' Author Yoshio KATO ' Description : Used MCU ATtiny2313 ' : System Clock 12.8MHz External OSC ' : Receive the time data from gps unit and send to display unit ' : Communication speed 9600bps 8bit non parity ' Receive format :"$GPRMC,hhmmss.sss,dd,mm,yy,,*pp" ' ex $GPRMC,094032.003,A,3603.9923,N,13931.4934,E,000.0,328.5,200709,,,A*65 '******************************************************************* $regfile = "attiny2313.dat" $crystal = 12800000 $baud = 9600 Dim I As Byte , J As Byte , K As Byte Dim Alarm_flg As Bit Dim Check_sum_ok As Bit Dim Gprmc_flg As Bit Dim Sum_stop_flg As Bit Dim Sw_no As Byte Dim Year As Byte Dim Month As Byte Dim Day As Byte Dim Hour As Byte Dim Minute As Byte Dim Second As Byte Dim Utc_year As Byte Dim Utc_month As Byte Dim Utc_day As Byte Dim Utc_hour As Byte Dim Utc_minute As Byte Dim Utc_second As Byte Dim Check_sum As Byte Dim Tmcount As Byte Dim Wk As Byte Dim Save_rec_data As Byte Dim Tm_hour As Byte 'timer hour Dim Tm_minute As Byte 'timer minute Dim Rec_data(15) As Byte Dim Month_kind(12) As Byte Dim Comma_counter As Byte Dim Rec_counter As Byte Const Sw_m1 = 4 'PB0 Const Sw_m10 = 5 'PB1 Const Sw_h1 = 6 'PB2 Const Sw_h10 = 7 'PB3 Const Sec_led = 6 'PD6 Const Timer_sw = 3 'PD3 Const Melody = 4 'PD4 reley Const Timer_led = 5 'PD5 Const Tmconst = 100 'timer interrup counter Main: Stop Ac Config Portb = &HF0 Config Portd = &HF4 'Output Config Timer0 = Timer , Prescale = 1024 , Clear Timer = 1 Ocr0a = 124 On Oc0a Tmovf ' if timer0 overflow go to Tmovf interrupt routine Enable Oc0a Enable Urxc On Urxc Rec_dt Enable Interrupts Portb = &H0F 'PB4 to PB7 pull up Portd = &H08 'PD3 pull up 'parameter clear Tmcount = 0 Alarm_flg = 0 Month_kind(1) = 3 '3:large month Month_kind(2) = 1 '1:Febrary Month_kind(3) = 3 Month_kind(4) = 2 '2:small mont Month_kind(5) = 3 Month_kind(6) = 2 Month_kind(7) = 3 Month_kind(8) = 3 Month_kind(9) = 2 Month_kind(10) = 3 Month_kind(11) = 2 Month_kind(12) = 3 'evrer loop Do If Alarm_flg = 1 Then Reset Portd.melody Else Set Portd.melody End If Loop End '******************************************************************* ' Timer1 interrupt ' Interrupt ever 10ms '******************************************************************* Tmovf: Incr Tmcount If Tmcount >= 50 Then Set Portd.sec_led Else Reset Portd.sec_led End If If Pind.timer_sw = 0 Then 'timer switch on? Set Portd.timer_led Gosub Check_timer 'get timer value and compare now time Else Reset Portd.timer_led Alarm_flg = 0 End If If Tmcount >= Tmconst Then Tmcount = 0 Incr Second 'increment second If Second = 60 Then 'second over 60 ? Second = 0 Incr Minute 'increment minute If Minute >= 60 Then 'minute over 60 ? Minute = 0 'yes minute is over 60 Incr Hour 'increment hour If Hour = 24 Then 'hour over 24 ? Hour = 0 'yes hour is over 24 End If End If End If Wk = Second Or &HC0 Printbin Wk Wk = Minute Or &H80 Printbin Wk Wk = Hour Or &H40 Printbin Wk Wk = Day Or &H20 Printbin Wk Printbin Month End If Return '******************************************************************* ' Get timer value from digital switch '******************************************************************* Check_timer: Gosub Get_digital_switch If Tm_minute = Minute Then 'check timer value:now time If Tm_hour = Hour Then Alarm_flg = 1 'relay on End If End If Return '******************************************************************* ' Get digital switch '******************************************************************* Get_digital_switch: Disable Interrupts Sw_no = Sw_m1 Gosub Read_digital_sw Tm_minute = Wk Sw_no = Sw_m10 Gosub Read_digital_sw Wk = Wk * 10 Tm_minute = Tm_minute + Wk Sw_no = Sw_h1 Gosub Read_digital_sw Tm_hour = Wk Sw_no = Sw_h10 Gosub Read_digital_sw Wk = Wk * 10 Tm_hour = Tm_hour + Wk Enable Interrupts Return '******************************************************************* ' Get digital switch '******************************************************************* Read_digital_sw: Set Portb.sw_m1 Set Portb.sw_m10 Set Portb.sw_h1 Set Portb.sw_h10 Waitus 50 Reset Portb.sw_no Waitus 50 Wk = Pinb Wk = Wk And &H0F Return '******************************************************************* ' Serial communication interrupt ' receive date and time data from GPS unit ' $GPRMC,225446.00,A,4916.452653,N,12311.123747,W,000.5,054.7,191194,06.2,W,A*68 '******************************************************************* Rec_dt: Save_rec_data = Udr Select Case Save_rec_data Case &H24 : Gprmc_flg = 0 'detect the top of sentense '$' Comma_counter = 0 Rec_counter = 1 Check_sum = 0 Sum_stop_flg = 0 Case &H2C : Incr Comma_counter 'detect comma Rec_counter = 1 Check_sum = Check_sum Xor Save_rec_data Select Case Comma_counter Case 1 : If Rec_data(3) = &H52 Then 'R If Rec_data(4) = &H4D Then 'M If Rec_data(5) = &H43 Then 'C Gprmc_flg = 1 'detect $GPRMC End If End If End If Case 2 : If Gprmc_flg = 1 Then Gosub Conv_bin 'hour,minute,second Utc_hour = I Utc_minute = J Utc_second = K End If Case 10 : If Gprmc_flg = 1 Then Gosub Conv_bin 'day,month,year Utc_day = I Utc_month = J Utc_year = K End If End Select Case &H0D : If Gprmc_flg = 1 Then 'detect the end of sentense 'CR,LF' If Rec_data(1) > &H39 Then I = Rec_data(1) - &H37 Else I = Rec_data(1) - &H30 End If If Rec_data(2) > &H39 Then J = Rec_data(2) - &H37 Else J = Rec_data(2) - &H30 End If Shift I , Left , 4 I = I Or J If Check_sum = I Then Check_sum_ok = 1 Else Check_sum_ok = 0 End If If Check_sum_ok = 1 Then Utc_hour = Utc_hour + 9 'conversion UTC to JST If Utc_hour > 23 Then Incr Utc_day Utc_hour = Utc_hour - 24 Select Case Month_kind(utc_month) Case 1: 'Febrary I = Utc_year Mod 4 If I = 0 Then 'leap year If Utc_day = 30 Then Utc_day = 1 Incr Utc_month End If Else If Utc_day = 29 Then Utc_day = 1 Incr Utc_month End If End If Case 2: 'Apr,Jun,Sep,Nov Small month If Utc_day = 31 Then Utc_day = 1 Incr Utc_month End If Case 3: 'Jan,Mar,May,Jul,Aug,Oct,Dec Large month If Utc_day = 32 Then Utc_day = 1 Incr Utc_month If Utc_month = 13 Then Utc_month = 1 Incr Utc_year End If End If End Select End If If Utc_second = 0 Or Month = 0 Then Year = Utc_year Month = Utc_month Day = Utc_day Hour = Utc_hour Minute = Utc_minute Second = Utc_second Tmcount = 0 'set this data when calibration End If End If End If Case &H2A : Rec_counter = 1 'detect '*' Sum_stop_flg = 1 Case Else : If Sum_stop_flg = 0 Then Check_sum = Check_sum Xor Save_rec_data 'calculate check sum End If Rec_data(rec_counter) = Save_rec_data Incr Rec_counter End Select Return '******************************************************************* ' Conversion char to binary '******************************************************************* Conv_bin: I = Rec_data(1) - &H30 I = I * 10 Wk = Rec_data(2) - &H30 I = I + Wk J = Rec_data(3) - &H30 J = J * 10 Wk = Rec_data(4) - &H30 J = J + Wk K = Rec_data(5) - &H30 K = K * 10 Wk = Rec_data(6) - &H30 K = K + Wk Return