' ' ************************************************* ' * * ' * Speed Meter & Digital Clock Control Program * ' * * ' * AVR Used is ATmega88 * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2007. 7.27 * ' ************************************************* ' ' Ver 09.21 = (Ver 09.01) to Transplant version. For LED Type. ' ' ' $regfile = "m88def.dat" $crystal = 12800000 $eepleave ' Const Prgveru = 09 'Program Version Upper Byte Const Prgverl = 21 'Program Version Lower Byte ' ' 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 Mf1224 As Byte 'Mode Flag Hour 12/24 Display Dim Kf1224 As Byte 'Key In Flag 12/24 Button 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 Keymax As Byte 'Key In Max Data Dim Keymin As Byte 'Key In Min Data Dim Blktim As Byte 'Display Blink Timer Dim Tempw1 As Word 'Temporary Memory Word No.1 Dim Tempw2 As Word 'Temporary Memory Word No.2 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 Byte 'Temporary Memory Word No.8 Dim Temp9 As Byte 'Temporary Memory Word No.9 ' ' ' ' ****************** ' * 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 Scnspd = 244 'Default DMA Scanning Speed (308Hz) Else Scnspd = 207 'Default DMA Scanning Speed (75Hz) End If ' ' ******************** ' * EEPROM Data Read * ' ******************** ' Readeeprom Mf82ds , 1 'EEPROM (1) 8Time-2Month.Day Display Flag If Mf82ds > 1 Then 'If EEPROM Initial Condition(FF) Then Mf82ds = 0 Gosub Eepwrs 'EEPROM Writing Else Readeeprom Scnspd , 2 'EEPROM (2) DMA Scanning Speed Readeeprom Tdyear , 3 'EEPROM (3) Year Readeeprom Tdmonth , 4 'EEPROM (4) Month Readeeprom Tdday , 5 'EEPROM (5) Day End If ' ' Enable Interrupts Enable Timer2 Enable Compare1a ' ' * Power On -> "TimeSet A" Key On Check * ' If Pinb.3 = 0 Then Goto Scnsps 'If Scanning Speed Setting? Then ' ' ' *************************** ' * Program Version Display * ' *************************** ' Prgvds: Digsup = &H3C 'Digit Suppress Flag Temp1 = Prgverl 'Digit 3.4 = Lower Data Display Temp2 = &H03 Gosub Segcvw Temp1 = Prgveru 'Digit 5.6 = Upper Data Display Temp2 = &H05 Gosub Segcvw Gosub Dpset1 'Decimal Point 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 T100ms2 'If Days Passed? Else ' Tdday = 1 Tdmonth = Tdmonth + 1 'Month is Counted If Tdmonth < 13 Then Goto T100ms2 'If 12 Months Passed? Else ' Tdmonth = 1 Tdyear = Tdyear + 1 'Year is Counted If Tdyear < 100 Then Goto T100ms2 'If 100 Years Passed? Else Tdyear = 0 ' T100ms2: Gosub Eepwrs2 'EEPROM Writing ' T100ms1: If Pinc.1 = 1 Then Goto Adconv 'If Speed Display mode? Then ' ' * Hour 12/24 Display Select * ' If Kf1224 = 1 Then Goto K1224s1 'If 12/24 Select Key Off Check? Then If Pinb.1 = 1 Then Goto Segdts 'If 12/24 Select Key On? Else Kf1224 = 1 If Mf1224 = 0 Then 'If Hour Display 12 or 24? Mf1224 = 1 Else Mf1224 = 0 End If Goto Segdts ' K1224s1: '12/24 Select Key Off Check If Pinb.1 = 0 Then Goto Segdts 'If 12/24 Select Key On? Then Kf1224 = 0 ' ' * 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 = 1 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 Tempw1 = Getadc(0) 'A/D Conversion Takes for 300 Micro Seconds Stop Adc ' Tempw1 = Tempw1 / 4 'Spped Display 0-255 Km/h Temp8 = Tempw1 ' If Temp8 < 8 Then 'Noise is Removed (0-7 = 0) Temp8 = 0 Else Temp8 = Temp8 - 7 End If ' Gosub Dpreset 'Blink Bit Reset Reset Portb.2 'AM & PM Display Off Reset Portb.4 Reset Digsup.2 Temp9 = Temp8 / 100 If Temp8 > 99 Then Goto Adconv1 'If Spped >=100? Then ' Temp2 = &H84 'Spped 0-99 Km/h Reset Digsup.5 'Digit Suppress Flag Adconv2: Temp9 = Temp9 * 100 Temp1 = Temp8 - Temp9 Gosub Segcvw 'Digit 4.5 Lower Data Display Return ' Adconv1: 'Spped >=100 Km/h Temp1 = Temp9 Temp2 = &H06 'Digit 6 Upper Data Display Gosub Segcvw Temp2 = &H04 Goto Adconv2 ' ' **************************** ' * Time Setting Sub Routine * ' **************************** ' Timset: Temp3 = Pinb And &H28 If Temp3 = &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 = 1 'Time Set Mode Start Waitms 10 '10ms Wait Gosub Dpreset 'Decimal Point Reset Reset Portb.2 'AM & PM Display Off Reset Portb.4 ' ' 'Display Mode 8Time-2Month.Day Setting Segdt(5) = &H80 'Digit5 Decimal Point Set Segdt(6) = &H80 'Digit6 Decimal Point Set Temp1 = 82 Temp2 = &H05 'Digit 5.6 "8.2." Display Gosub Segcvw Temp1 = Mf82ds Temp2 = &H03 Keymax = 1 Keymin = 0 Gosub Keyin Mf82ds = Temp1 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 Temp1 = Tdyear Temp2 = &H03 Keymax = 99 Gosub Keyin Tdyear = Temp1 ' ' Temp1 = Tdday 'Month Setting Temp2 = &H83 Gosub Segcvw Temp1 = Tdmonth Temp2 = &H85 Keymax = 12 Keymin = 1 Gosub Keyin Tdmonth = Temp1 ' ' 'Day Setting Temp1 = Tdmonth Temp2 = &H85 Gosub Segcvw Temp1 = Tdday Temp2 = &H83 Gosub Monchk 'Month Maximum Value Checking Keymax = Temp3 Gosub Keyin Tdday = Temp1 ' ' 'Hour Setting Gosub Dpset1 'Decimal Point Set Temp1 = Tdmin Temp2 = &H03 Gosub Segcvw Temp1 = Tdhour Temp2 = &HA5 'Hour Display Mode Bit Setting Keymax = 23 Keymin = 0 Gosub Keyin Tdhour = Temp1 ' ' 'Minutes Setting Temp1 = Tdhour Temp2 = &H85 Gosub Hourcv Temp1 = Tdmin Temp2 = &H03 Keymax = 59 Gosub Keyin Tdmin = Temp1 ' ' Timset03: '"TimeSet A" Key Off Checking If Pinb.3 = 0 Then Goto Timset03 'If "TimeSet A" Key Off? Else Gosub Eepwrs1 'EEPROM Writing 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 Keyin7 'if "TimeSet Key Off Check? Then" If Keymod >= 2 Then Goto Keyin5 'If Repeat Check? Then Keyin8: 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 If Pinb.1 = 0 Then Goto Keyin3 'If "TimeSet C" Key On? Then Goto Keyin ' ' Keyin1: '"TimeSet A" Key On Keymod = 1 'Key Off Check Mode Set Keytim = 0 Return ' Keyin2: '"TimeSet B" Key On -> Data Increment If Temp1 >= Keymax Then 'If Set Data Maximum ? Then Temp1 = Keymin Else Temp1 = Temp1 + 1 End If Keyin4: If Temp2.4 = 1 Then Goto Keyin1 'If Direct Return Mode? Then If Keymod = 3 Then Goto Keyin 'If Auto Increment? Then Keymod = 2 'Repeat Check Mode Set Keytim = 0 Goto Keyin ' Keyin3: '"TimeSet C" Key On -> Data Decrement If Temp1 <= Keymin Then 'If Set Data Minimum ? Then Temp1 = Keymax Else Temp1 = Temp1 - 1 End If Goto Keyin4 ' Keyin5: 'Repeat Check Temp3 = Pinb And &H22 If Temp3 <> &H22 Then Goto Keyin6 'If "TimeSet B or C" Key On? Then Waitms 10 'Wait 10msec Keymod = 0 'Key Off -> Repeat Mode Off Goto Keyin ' Keyin6: 'Key On 1Sec pass Check If Keytim < 10 Then Goto Keyin 'If 1Sec passed Auto Increment? Else Keytim = 10 Keymod = 3 Waitms 100 'Wait 100msec Goto Keyin8 ' Keyin7: '"TimeSet Key Off Check" Waitms 10 'Wait 10msec Temp3 = Pinb And &H2A If Temp3 = &H2A Then 'If Key All Off? Then Keymod = 0 End If Goto Keyin ' ' ****************************** ' * 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) 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: Temp8 = Temp1 If Mf1224 = 0 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 = Temp8 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 Eepwrs2: Writeeeprom Tdyear , 3 Writeeeprom Tdmonth , 4 Writeeeprom Tdday , 5 Return ' ' ******************************* ' * Scanning Speed Setting Mode * ' ******************************* ' Scnsps: Digsup = &H3F Segdt(3) = &H80 'Digit3 Decimal Point Set Segdt(6) = &H80 'Digit6 Decimal Point Set Keymod = 1 ' Scnsps1: Temp3 = 256 - Scnspd Tempw1 = 3704 / Temp3 Tempw2 = Tempw1 / 100 Temp1 = Tempw2 Temp2 = &H05 'Digit 5.6 Upper Data Display Gosub Segcvw Tempw2 = Tempw2 * 100 Temp1 = Tempw1 - Tempw2 Temp2 = &H13 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