' ' ********************************************** ' * * ' * Digital Clock Control Program * ' * * ' * AVR Used is ATmega88 * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2007. 7.12 * ' ********************************************** ' ' Ver 09.00 = (Ver 02.04) to Transplant version. ' Ver 09.01 = Bug fix version. ' ' $regfile = "m88def.dat" $crystal = 12800000 $eepleave ' Const Prgver = &H0901 'Program Version ' ' Dim Segdt(7) As Byte 'Segment Data Buffer Dim Segcvt(10) As Byte 'Segment Data Conversion Table ' Dim Digno As Byte 'DMA Display Digit Number Dim Dmablc As Byte 'DMA Blanking Counter Dim Scnspd As Word 'DMA Scanning Speed Dim Digsup As Byte 'Digit Suppress Flag Dim Ptctmp As Byte 'Port C Temporary Dim Ptdtmp As Byte 'Port D Temporary Dim T100msf As Byte '100mSec Interrupt Flag Dim T1scun As Byte '1Second Counter Dim Bcd7seg As Byte 'BCD or 7Segment Mode Flag Dim Mf82ds As Byte 'Mode Flag 8Time-2Month.Day Display Dim Tdsec As Byte 'Time Data Second Dim Tdmin As Byte 'Time Data Minutes Dim Tdhour As Byte 'Time Data Hour Dim Tdday As Byte 'Time Data Day Dim Tdmonth As Byte 'Time Data Month Dim Tdyear As Byte 'Time Data Year Dim Keymod As Byte 'Key In Mode Dim Keytim As Byte 'Key In Timer Dim Blktim As Byte 'Display Blink Timer Dim Temp As Word 'Temporary Memory Word Dim Temp1 As Byte 'Temporary Memory Byte No.1 Dim Temp2 As Byte 'Temporary Memory Byte No.2 Dim Temp3 As Byte 'Temporary Memory Byte No.3 Dim Temp4 As Byte 'Temporary Memory Byte No.4 Dim Temp5 As Byte 'Temporary Memory Byte No.5 Dim Temp6 As Byte 'Temporary Memory Byte No.6 Dim Temp7 As Byte 'Temporary Memory Byte No.7 Dim Temp8 As Word 'Temporary Memory Word No.8 ' ' ' ' ****************** ' * Initialization * ' ****************** ' Config Portb = Input 'Define PORT B Portb = &B00101011 'PORT B Pull-up Config Portb.2 = Output 'Bit 2 OUTPUT Config Portb.4 = Output 'Bit 4 OUTPUT ' Config Portc = Input 'Define PORT C Config Portc.2 = Output 'Bit 2 OUTPUT Config Portc.3 = Output 'Bit 3 OUTPUT Config Portc.4 = Output 'Bit 4 OUTPUT Config Portc.5 = Output 'Bit 5 OUTPUT ' Config Portd = Output 'Define PORT D ' Config Timer2 = Timer , Prescale = 64 'Timer2 = 12,800,000Hz/64=200,000Hz On Timer2 Dmaint 'Timer2 = DMA Interrupt ' Config Timer1 = Timer , Prescale = 64 'Timer1 = 12,800,000Hz/64=200,000Hz Compare1a = 19999 'Timer1 Compare = 10Hz = 100mSec On Compare1a T100int 'Timer1 = 100mSec Interrupt ' Config Adc = Single , Prescaler = Auto 'A/D Converter Initialization ' ' Segcvt(1) = &H3F '"0" Segment Data Conversion Table setting Segcvt(2) = &H06 '"1" Segcvt(3) = &H5B '"2" Segcvt(4) = &H4F '"3" Segcvt(5) = &H66 '"4" Segcvt(6) = &H6D '"5" Segcvt(7) = &H7D '"6" Segcvt(8) = &H07 '"7" Segcvt(9) = &H7F '"8" Segcvt(10) = &H6F '"9" ' 'Segdt(1) = 0 'Segment Data Buffer Cleared 'Segdt(2) = 0 'Segdt(3) = 0 'Segdt(4) = 0 'Segdt(5) = 0 'Segdt(6) = 0 ' Digno = 2 'DMA Display Digit No. 'Dmablc = 0 'DMA Blanking Counter 'Bcd7seg = 0 'BCD or 7Segment Mode Flag 'T100msf = 0 '100mSecond Interrupt Flag 'T1scun = 0 '1Second Counter 'Keymod = 0 'Key In Mode 'Tdsec = 0 'Time Data Second 'Tdmin = 0 'Time Data Minutes 'Tdhour = 0 'Time Data Hour Tdday = 1 'Time Data Day Tdmonth = 1 'Time Data Month 'Tdyear = 0 'Time Data Year ' ' ********************************* ' * BCD or 7Segment Mode checking * ' ********************************* ' If Pinb.0 = 1 Then 'If 7Segment Mode Then Config Portb.0 = Output 'Bit 0 OUTPUT Bcd7seg = 1 End If ' ' ******************** ' * EEPROM Data Read * ' ******************** ' Readeeprom Mf82ds , 1 'EEPROM (1) 8Time-2Month.Day Display Flag Readeeprom Scnspd , 2 'EEPROM (2) DMA Scanning Speed If Mf82ds > 82 Then 'If EEPROM Initial Condition(FF) Then Mf82ds = 0 Scnspd = 207 'DMA Scanning Speed (75Hz) Gosub Eepwrs 'EEPROM Writing End If ' ' Enable Interrupts Enable Timer2 Enable Compare1a ' ' If Pinb.3 = 0 Then Goto Scnsps 'If Scanning Speed Setting? Then ' ' ' *************************** ' * Program Version Display * ' *************************** ' Prgvds: Digsup = &H3C 'Digit Suppress Flag Temp5 = Prgver And &H00FF 'Digit 3.4 = Lower Data Display Temp2 = &H03 Gosub Segcvwp Temp = Prgver And &HFF00 'Digit 5.6 = Upper Data Display Shift Temp , Right , 8 Temp5 = Temp Temp2 = &H05 Gosub Segcvwp Gosub Dpset1 'Blink Bit Set ' Prgvds1: If Pinb.3 = 0 Then Goto Prgvds2 'If "Timset A" Key On? Then If T100msf = 0 Then Goto Prgvds1 T100msf = 0 If Digsup = 0 Then 'Display Blink Digsup = &H3C Else Digsup = 0 End If Goto Prgvds1 ' Prgvds2: Gosub Segdts 'Segment Data Setting ' ' **************** ' * MAIN Routine * ' **************** ' Main: Gosub T100ms 'Processing Every 100mSec Gosub Timset 'Processing Time Set Goto Main End ' ' ' ' **************************************** ' * Processing every 100mSec Sub Routine * ' **************************************** ' T100ms: If T100msf = 0 Then Return 'If 100mSec Passed? Else T100msf = 0 ' T1scun = T1scun + 1 'Check on Passage of 1Sec If T1scun < 10 Then Goto T100ms1 'If 1 Seconds Passed? Else T1scun = 0 ' Tdsec = Tdsec + 1 'Second is Counted If Tdsec < 60 Then Goto T100ms1 'If 60 Seconds Passed? Else ' Tdsec = 0 Tdmin = Tdmin + 1 'Minutes is Counted If Tdmin < 60 Then Goto T100ms1 'If 60 Minutes Passed? Else ' Tdmin = 0 Tdhour = Tdhour + 1 'Hour is Counted If Tdhour < 24 Then Goto T100ms1 'If 24 Hours Passed? Else ' Tdhour = 0 Tdday = Tdday + 1 'Day is Counted Gosub Monchk 'Month Maximum Value Checking If Tdday =< Temp3 Then Goto T100ms1 'If Days Passed? Else ' Tdday = 1 Tdmonth = Tdmonth + 1 'Month is Counted If Tdmonth < 13 Then Goto T100ms1 'If 12 Months Passed? Else ' Tdmonth = 1 Tdyear = Tdyear + 1 'Year is Counted If Tdyear < 100 Then Goto T100ms1 'If 100 Years Passed? Else Tdyear = 0 ' T100ms1: If Pinc.1 = 1 Then Goto Adconv 'If Speed Display mode? Then ' ' * Segment Data Setting * ' Segdts: If Pinb.3 = 0 Then Goto Segdts2 'If "Timset A" Key On? Then If T1scun < 5 Then '0.5Sec Blink Bit Set Gosub Dpset 'Blink Bit Set Else Gosub Dpreset 'Blink Bit Reset End If If Pinb.5 = 0 Then Goto Segdts3 'If "Timset B" Key On? Then ' Segdts1: If Mf82ds = 82 Then Goto Segdts5 'If Display Mode = 8Time-2Month.Day? Then Segdts6: Temp1 = Tdmin 'Digit 3.4 = Minutes Display Temp2 = &H03 Gosub Segcvw Temp1 = Tdhour 'Digit 5.6 = Hour Display Temp2 = &H85 Gosub Hourcv Return ' ' Segdts2: '"Timset A" Key On Gosub Dpreset 'Blink Bit Reset Reset Portb.2 'AM & PM Display Off Reset Portb.4 Temp1 = Tdday 'Digit 3.4 = Day Display Temp2 = &H83 Gosub Segcvw Temp1 = Tdmonth 'Digit 5.6 = Month Display Temp2 = &H85 Gosub Segcvw Return ' Segdts3: '"Timset B" Key On Reset Portb.2 'AM & PM Display Off Reset Portb.4 Temp1 = Tdsec 'Digit 3.4 = Second Display Temp2 = &H03 Gosub Segcvw Temp1 = Tdmin 'Digit 5.6 = Minutes Display Temp2 = &H05 Gosub Segcvw Return ' Segdts5: 'Display Mode = 8Time-2Month.Day Temp1 = Makebcd(tdsec) Temp1 = Temp1 And &H0F If Temp1 > 7 Then Goto Segdts2 'If Second Lower Byte > 7? Then Goto Segdts6 ' ' * Processing of A/D Conversion * ' Adconv: If T1scun.0 = 0 Then Return 'A/D Conversion Every 200m Sec ' Start Adc 'Speed Voltage A/D Conversion Temp = Getadc(0) 'A/D Conversion Takes for 300 Micro Seconds Stop Adc ' Temp = Temp / 4 'Spped Display 0-255 Km/h Gosub Dpreset 'Blink Bit Reset Reset Portb.2 'AM & PM Display Off Reset Portb.4 Temp8 = Temp / 100 If Temp > 99 Then Goto Adconv1 'If Spped >=100? Then ' Temp2 = &H84 'Spped 0-99 Km/h Digsup = &H18 'Digit Suppress Flag Adconv2: Temp8 = Temp8 * 100 Temp1 = Temp - Temp8 Gosub Segcvw 'Digit 4.5 Lower Data Display Return ' Adconv1: 'Spped >=100 Km/h Digsup = &H38 'Digit Suppress Flag Temp1 = Temp8 Temp2 = &H06 'Digit 6 Upper Data Display Gosub Segcvw Temp2 = &H04 Goto Adconv2 ' ' **************************** ' * Time Setting Sub Routine * ' **************************** ' Timset: Temp1 = Pinb And &H28 If Temp1 = &H00 Then Goto Timset01 'If "TimeSet A&B" Key Input? Then Keymod = 0 'No "TimeSet A&B" Key Input Return ' Timset01: '"TimeSet A&B" Key ON If Keymod = 1 Then Goto Timset02 'If 3Sec passed Check? Then Keymod = 1 '3Sec Wait Mode Set Keytim = 0 Return ' Timset02: If Keytim < 30 Then Return 'If 3Sec passed? Else Keymod = 2 'Time Set Mode Start Waitms 10 '10ms Wait Gosub Dpreset 'Decimal Point Reset Reset Portb.2 'AM & PM Display Off Reset Portb.4 ' ' 'Hour Display 12 or 24 Setting Segdt(5) = &H80 'Digit5 Decimal Point Set Segdt(6) = &H80 'Digit6 Decimal Point Set Timset21: Temp1 = 82 'Display Mode 8Time-2Month.Day Setting Temp2 = &H05 'Digit 5.6 "6.4." Display Gosub Segcvw Timset22: Temp1 = Mf82ds Temp2 = &H03 Gosub Keyin If Pinb.3 = 0 Then Goto Timset23 'If "TimeSet A" Key On? Then If Mf82ds = 0 Then 'If Normal Mode? Then Mf82ds = 82 Else Mf82ds = 0 End If Goto Timset22 ' Timset23: Gosub Eepwrs1 'EEPROM Writing ' 'Year Setting Segdt(5) = &H00 'Digit5 Decimal Point Reset Segdt(6) = &H00 'Digit6 Decimal Point Reset Temp1 = 20 Temp2 = &H05 'Digit 5.6 Year "20" Display Gosub Segcvw Timset32: Temp1 = Tdyear Temp2 = &H03 Gosub Keyin If Pinb.3 = 0 Then Goto Timset41 'If "TimeSet A" Key On? Then Tdyear = Tdyear + 1 'Year Count Up If Tdyear > 99 Then Tdyear = 0 'Year Counter Overflowed? then Goto Timset32 ' Timset41: 'Month Setting Temp1 = Tdday Temp2 = &H83 Gosub Segcvw Timset42: Temp1 = Tdmonth Temp2 = &H85 Gosub Keyin If Pinb.3 = 0 Then Goto Timset51 'If "TimeSet A" Key On? Then Tdmonth = Tdmonth + 1 'Month Count Up If Tdmonth > 12 Then Tdmonth = 1 'Month Counter Overflowed? then Goto Timset42 ' Timset51: 'Day Setting Temp1 = Tdmonth Temp2 = &H85 Gosub Segcvw Timset52: Temp1 = Tdday Temp2 = &H83 Gosub Keyin If Pinb.3 = 0 Then Goto Timset61 'If "TimeSet A" Key On? Then Tdday = Tdday + 1 'Day Count Up Gosub Monchk 'Month Maximum Value Checking If Tdday > Temp3 Then Tdday = 1 Goto Timset52 ' Timset61: 'Hour Setting Gosub Dpset1 'Decimal Point Set Temp1 = Tdmin Temp2 = &H03 Gosub Segcvw Timset62: Temp1 = Tdhour Temp2 = &HA5 'Hour Display Mode Bit Setting Gosub Keyin If Pinb.3 = 0 Then Goto Timset71 'If "TimeSet A" Key On? Then Tdhour = Tdhour + 1 'Hour Count Up If Tdhour > 23 Then Tdhour = 0 'Hour Counter Overflowed? then Goto Timset62 ' Timset71: 'Minutes Setting Temp1 = Tdhour Temp2 = &H85 Gosub Hourcv Timset72: Temp1 = Tdmin Temp2 = &H03 Gosub Keyin If Pinb.3 = 0 Then Goto Timset81 'If "TimeSet A" Key On? Then Tdmin = Tdmin + 1 'Minutes Count Up If Tdmin > 59 Then Tdmin = 0 'Minutes Counter Overflowed? then Goto Timset72 ' Timset81: Temp1 = Pinb And &H28 '"TimeSet A&B" Key Off Checking If Temp1 <> &H28 Then Goto Timset81 'If "TimeSet A&B" Key Off? Else Tdsec = 0 Return ' ' ********************************** ' * Key Input Checking Sub Routine * ' ********************************** ' Keyin: If Blktim > 6 Then Blktim = 0 'If Blink Counter Overflowed? then If Blktim < 5 Then 'If Display or erased? If Temp2.5 = 0 Then 'If Hour Display Mode? Else Gosub Segcvw Else Gosub Hourcv End If Else Temp5 = Temp2 And &H0F 'Display is erased Reset Digsup.temp5 Temp5 = Temp5 - 1 Reset Digsup.temp5 End If ' If Keymod = 1 Then Goto Keyin4 'If Repeat Mode? Then If Keymod = 2 Then Goto Keyin3 'If "TimeSet AorB" Key Off Check? Then If Pinb.3 = 0 Then Goto Keyin1 'If "TimeSet A" Key On? Then If Pinb.5 = 0 Then Goto Keyin2 'If "TimeSet B" Key On? Then Goto Keyin ' ' Keyin1: '"TimeSet A" Key On Keymod = 2 Keytim = 0 Return ' Keyin2: Keymod = 1 '"TimeSet B" Key On Keytim = 0 Return ' Keyin3: '"TimeSet AorB" Key Off Check Waitms 10 'Wait 10msec If Pinb.3 = 0 Then Goto Keyin 'If "TimeSet A" Key Off? Else If Pinb.5 = 0 Then Goto Keyin 'If "TimeSet B" Key Off? Else Keymod = 0 Goto Keyin ' Keyin4: 'Repeat Mode If Pinb.5 = 0 Then Goto Keyin5 'If "TimeSet B" Key On? Then Waitms 10 'Wait 10msec Keymod = 0 Goto Keyin ' Keyin5: If Keytim < 10 Then Goto Keyin 'If 1Sec passed Auto Increment? Else Keytim = 10 'Auto Increment Waitms 100 'Wait 100msec Return ' ' ****************************** ' * Month Checking Sub Routine * (Month Maximum Value = Temp3) ' ****************************** ' Monchk: Select Case Tdmonth 'Month Checking Case 2 : Temp4 = Tdyear And &H03 If Temp4 = 0 Then 'If Leap Year? Then Temp3 = 29 Else Temp3 = 28 End If Case 4 : Temp3 = 30 Case 6 : Temp3 = 30 Case 9 : Temp3 = 30 Case 11 : Temp3 = 30 Case Else : Temp3 = 31 End Select Return ' ' *********************************** (Temp1 = Binary Data) ' * Segment Data Conversion * (Temp2 = Write Segment No.) ' * and 2Digit Writes Sub Routine * (Temp2 Bit7=1 Then Zero Suppress) ' *********************************** ' Segcvw: Temp5 = Makebcd(temp1) Segcvwp: Temp3 = Temp5 And &H0F 'Temp3 = BCD Lower Data Shift Temp5 , Right , 4 Temp4 = Temp5 And &H0F 'Temp4 = BCD Upper Data Temp5 = Temp2 And &H0F 'Temp5 = Write Segment No. Temp6 = Segdt(temp5) And &H80 'Temp6 = Lower Decimal Point Bit Temp7 = Segdt(temp5 + 1) And &H80 'Temp7 = Upper Decimal Point Bit ' If Temp2.7 = 1 Then Goto Segcvw4 'If Zero Suppress? Then ' Segcvw1: Set Digsup.temp5 'Upper Digit On Segcvw2: Temp5 = Temp5 - 1 'Lower Digit On Set Digsup.temp5 Temp5 = Temp5 + 1 If Bcd7seg = 0 Then Goto Segcvw3 'If Display Mode is BCD? Then ' '7Segment Mode Display Segdt(temp5) = Segcvt(temp3 + 1) Or Temp6 'Lower Data is Written Segdt(temp5 + 1) = Segcvt(temp4 + 1) Or Temp7 'Upper Data is Written Return ' Segcvw3: 'BCD Mode Display Segdt(temp5) = Temp3 Or Temp6 'Lower Data is Writte Segdt(temp5 + 1) = Temp4 Or Temp7 'Upper Data is Written Return ' ' Segcvw4: 'Zero Suppress is Checked If Temp4 <> 0 Then Goto Segcvw1 'If Upper Data <> 0? Then Reset Digsup.temp5 'Upper Digit Off Goto Segcvw2 ' ' ************************************ (Temp1 = Binary Data) ' * Hour Data Conversion Sub Routine * (Temp2 = Write Segment No.) ' ************************************ ' Hourcv: If Pinb.1 = 1 Then Goto Hourcv1 'If Hour Display 12Hour Mode? Then Reset Portb.2 '24Hour Mode Reset Portb.4 'AM & PM Display Off Hourcv2: Gosub Segcvw Temp1 = Tdhour Return ' Hourcv1: '12Hour Mode If Temp1 < 12 Then 'If AM or PM? Set Portb.2 'AM Set Reset Portb.4 Else Set Portb.4 'PM Set Reset Portb.2 End If If Temp1 = 0 Then Temp1 = 24 If Temp1 > 12 Then Temp1 = Temp1 - 12 Goto Hourcv2 ' ' ******************************************* ' * Decimal Point Blink Bit Set Sub Routine * ' ******************************************* ' Dpset: Dpset1: 'Set Segdt(3).7 == Error! Segdt(5) = Segdt(5) Or &H80 Return ' ' ********************************************** ' * Decimal Point Blink Bit Reset Sub Routine * ' ********************************************** ' Dpreset: Segdt(5) = Segdt(5) And &H7F Return ' ' **************************** ' * EEPROM Write Sub Routine * ' **************************** ' Eepwrs: Writeeeprom Scnspd , 2 Eepwrs1: Writeeeprom Mf82ds , 1 Return ' ' ******************************* ' * Scanning Speed Setting Mode * ' ******************************* ' Scnsps: Digsup = &H3F Segdt(3) = &H80 'Digit3 Decimal Point Set Segdt(6) = &H80 'Digit6 Decimal Point Set Keymod = 2 ' Scnsps1: Temp1 = 256 - Scnspd Temp = 3704 / Temp1 Temp8 = Temp / 100 Temp1 = Temp8 Temp2 = &H05 'Digit 5.6 Upper Data Display Gosub Segcvw Temp8 = Temp8 * 100 Temp1 = Temp - Temp8 Temp2 = &H03 Gosub Keyin If Pinb.3 = 0 Then Goto Scnsps2 'If "TimeSet A" Key On? Then Scnspd = Scnspd + 1 If Scnspd > 253 Then 'If Scanning Speed > 1234Hz? Then Scnspd = 182 'Scanning Speed 50Hz Set End If Goto Scnsps1 ' Scnsps2: Gosub Eepwrs 'EEPROM Writing Scnsps3: If Pinb.3 = 0 Then Goto Scnsps3 'If "Timset A" Key On? Then Segdt(3) = &H00 'Digit3 Decimal Point Reset Segdt(6) = &H00 'Digit6 Decimal Point Reset Goto Prgvds End ' ' ************************* ' * DMA Display Interrupt * ' ************************* ' Dmaint: Timer2 = Scnspd 'Timer2 = DMA Scanning Speed Setting Select Case Dmablc Case 0 : 'Segment Data Change Ptdtmp = Segdt(digno + 1) Portd = Ptdtmp Reset Ptdtmp.7 If Ptdtmp = &H66 Then 'If Segment Data = 4 Then Set Portb.0 'Segment (h) Bit Set Else Reset Portb.0 'Segment (h) Bit Reset End If Case 1 : 'Digit Bit ON (H Level) Set Ptctmp.digno Portc = Ptctmp And Digsup Case 7 : Ptctmp = 0 'Digit Bit OFF (L Level) Portc = Ptctmp Digno = Digno + 1 If Digno > 5 Then Digno = 2 End If End Select Dmablc = Dmablc + 1 If Dmablc > 8 Then Dmablc = 0 Return ' ' ************************* ' * 100mSec Interrupt * ' ************************* ' T100int: Timer1 = 0 'Timer1 Reset T100msf = 1 '100ms Flag On Keytim = Keytim + 1 'Key Timer Count Up Blktim = Blktim + 1 'Blink Timer Count Up Return End