' ' ********************************************** ' * * ' * Digital Clock Control Program * ' * * ' * AVR Used is AT90S8535 * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2007. 1.18 * ' ********************************************** ' ' Ver 01.03 = Bug fix version. ' Ver 01.04 = Bug fixed - Decimal Mode Display. ' Ver 01.05 = Specification change of Decimal point. ' $regfile = "8535DEF.DAT" $crystal = 8000000 ' Const Prgver = &H0105 'Program Version ' ' Dim Segdt(6) As Byte 'Segment Data Buffer Dim Bindt(6) As Byte 'Binary 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 Ptatmp As Byte 'Port A Temporary Dim Ptdtmp As Byte 'Port D Temporary Dim Scnspd As Word 'DMA Scanning Speed Dim Digsup As Byte 'Digit Suppress Flag Dim T100msf As Byte '100mSec Interrupt Flag Dim T1scun As Byte '1Second Counter 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 ' ' ' ' ****************** ' * Initialization * ' ****************** ' Config Porta = Input 'Define PORT A Config Porta.0 = Output 'Bit 0-5 OUTPUT Config Porta.1 = Output Config Porta.2 = Output Config Porta.3 = Output Config Porta.4 = Output Config Porta.5 = Output Ptatmp = &H40 'PORT A Bit6 Pull-up Porta = Ptatmp If Pina.6 = 0 Then 'If Scanning Speed Fixation? Then Ptatmp = &HC0 Porta = Ptatmp End If ' Config Portb = Input 'Define PORT B Portb = &B11111111 'PORT B All Pull-up ' Config Portc = Output 'Define PORT C ' Config Portd = Input 'Define PORT D Config Portd.0 = Output 'Bit 0-6 OUTPUT Config Portd.1 = Output Config Portd.2 = Output Config Portd.3 = Output Config Portd.4 = Output Config Portd.5 = Output Portd = &B11000000 'PORT D Bit6,7 Pull-up ' Config Timer2 = Timer , Prescale = 64 'Timer2 = Clk/64=125,000Hz On Timer2 Dmaint 'Timer2 = DMA Interrupt ' Config Timer1 = Timer , Prescale = 256 'Timer1 = Clk/256=31,250Hz Compare1a = 3125 'Timer1 Compare = 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 Ptdtmp = &HC0 'Port D Temporary Digsup = &H3F 'Digit Suppress Flag Scnspd = 233 'DMA Scanning Speed (100Hz) 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 ' Gosub Segdts 'Segment Data Setting ' Enable Interrupts Enable Timer2 Enable Compare1a ' If Pinb.0 = 0 Then Goto Prgvds 'If Program Version Display? Then ' ' ' ' **************** ' * 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 ' If Pinb.2 = 0 Then Goto T100ms1 'If "HOLD" Switch ON? Then ' 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: ' ' * Processing of A/D Conversion * ' Adconv: If T1scun.0 = 0 Then Goto Segdts 'A/D Conversion Every 200m Sec ' If Pina.6 = 1 Then 'If Scanning Speed Fixation? Else Start Adc 'Volume Data A/D Conversion Temp = Getadc(7) 'A/D Conversion Takes for 300 Micro Seconds Temp = Temp / 16 Scnspd = Temp + 190 'DMA Scanning Speed Setting Stop Adc Else Scnspd = 245 'Scanning Speed 200Hz Fixation End If ' ' * Segment Data Setting * ' Segdts: Temp1 = Pinb And &H03 If Temp1 = &H02 Then Goto Segdts2 'If "Timset B" 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 Temp1 = &H01 Then Goto Segdts3 'If "Timset A" Key On? Then ' Segdts1: Temp1 = Tdsec 'Digit 1.2 = Second Display Temp2 = &H01 Gosub Segcvw 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 B" Key On Gosub Dpreset 'Blink Bit Reset Ptdtmp = &HC0 'AM & PM Display Off Digsup = Digsup And &HFC 'Digit 1.2 = Display is erased Temp1 = Tdday 'Digit 3.4 = Day Display Temp2 = &H43 Gosub Segcvw Temp1 = Tdmonth 'Digit 5.6 = Month Display Temp2 = &H45 Gosub Segcvw Return ' Segdts3: '"Timset A" Key On Ptdtmp = &HC0 'AM & PM Display Off If Pinb.4 = 1 Then Goto Segdts4 'If 6 Digit mode? Then Temp1 = Tdsec 'Digit 3.4 = Second Display Temp2 = &H03 Gosub Segcvw Temp1 = Tdmin 'Digit 5.6 = Minutes Display Temp2 = &H05 Gosub Segcvw Return ' Segdts4: '"Year" Display Gosub Dpreset 'Blink Bit Reset Digsup = Digsup And &HFC 'Digit 1.2 = Display is erase Temp1 = 20 'Digit 5.6 = "20" Display Temp2 = &H05 Gosub Segcvw Temp1 = Tdyear 'Digit 3.4 = Year Display Temp2 = &H03 Gosub Segcvw Return ' ' **************************** ' * Time Setting Sub Routine * ' **************************** ' Timset: Temp1 = Pinb And &H03 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 'Blink Bit Reset Ptdtmp = &HC0 'AM & PM Display Off Digsup = Digsup And &HFC 'Digit 1.2 = Display is erase ' Temp1 = 20 'Year Setting Temp2 = &H05 'Digit 5.6 Year "20" Display Gosub Segcvw Timset11: Temp1 = Tdyear Temp2 = &H03 Gosub Keyin If Pinb.0 = 0 Then Goto Timset21 'If "TimeSet A" Key On? Then Tdyear = Tdyear + 1 'Year Count Up If Tdyear > 99 Then Tdyear = 0 'Year Counter Overflowed? then Goto Timset11 ' Timset21: 'Month Setting Temp1 = Tdday Temp2 = &H43 Gosub Segcvw Timset22: Temp1 = Tdmonth Temp2 = &H45 Gosub Keyin If Pinb.0 = 0 Then Goto Timset31 'If "TimeSet A" Key On? Then Tdmonth = Tdmonth + 1 'Month Count Up If Tdmonth > 12 Then Tdmonth = 1 'Month Counter Overflowed? then Goto Timset22 ' Timset31: 'Day Setting Temp1 = Tdmonth Temp2 = &H45 Gosub Segcvw Timset32: Temp1 = Tdday Temp2 = &H43 Gosub Keyin If Pinb.0 = 0 Then Goto Timset41 '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 Timset32 ' Timset41: 'Hour Setting Gosub Dpset1 'Blink Bit Set Temp1 = Tdmin Temp2 = &H03 Gosub Segcvw Timset42: Temp1 = Tdhour Temp2 = &HA5 'Hour Display Mode Bit Setting Gosub Keyin If Pinb.0 = 0 Then Goto Timset51 'If "TimeSet A" Key On? Then Tdhour = Tdhour + 1 'Hour Count Up If Tdhour > 23 Then Tdhour = 0 'Hour Counter Overflowed? then Goto Timset42 ' Timset51: 'Minutes Setting Temp1 = Tdhour Temp2 = &H85 Gosub Hourcv Timset52: Temp1 = Tdmin Temp2 = &H03 Gosub Keyin If Pinb.0 = 0 Then Goto Timset61 'If "TimeSet A" Key On? Then Tdmin = Tdmin + 1 'Minutes Count Up If Tdmin > 59 Then Tdmin = 0 'Minutes Counter Overflowed? then Goto Timset52 ' Timset61: Temp1 = Pinb And &H03 '"TimeSet A&B" Key Off Checking If Temp1 <> &H03 Then Goto Timset61 '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 Keyin3 'If Repeat Mode? Then If Keymod = 2 Then Goto Keyin2 'If "TimeSet AorB" Key Off Check? Then If Pinb.0 = 0 Then Goto Keyin1 'If "TimeSet A" Key On? Then If Pinb.1 = 0 Then Goto Keyin1 'If "TimeSet B" Key On? Then Goto Keyin ' ' Keyin1: '"TimeSet AorB" Key On If Pinb.0 = 0 Then Keymod = 2 '"TimeSet A" Key On ' Else Keymod = 1 '"TimeSet B" Key On End If Waitms 10 Keytim = 0 'Wait 10msec Return ' Keyin2: '"TimeSet AorB" Key Off Check Waitms 10 'Wait 10msec If Pinb.0 = 0 Then Goto Keyin 'If "TimeSet A" Key Off? Else If Pinb.1 = 0 Then Goto Keyin 'If "TimeSet B" Key Off? Else Keymod = 0 Goto Keyin ' Keyin3: 'Repeat Mode If Pinb.1 = 0 Then Goto Keyin4 'If "TimeSet B" Key On? Then Waitms 10 'Wait 10msec Keymod = 0 Goto Keyin ' Keyin4: 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) ' *********************************** (Temp2 Bit6=1 Compulsorily 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 = Last Time Lower Data Temp7 = Segdt(temp5 + 1) And &H80 'Temp7 = Last Time Upper Data ' If Temp2.6 = 1 Then Goto Segcvw4 'If Compulsorily Zero Suppress? Then If Temp2.7 = 0 Then Goto Segcvw1 'If Non Zero Suppress? Then If Pind.7 = 1 Then Goto Segcvw4 'If Zero Suppress SW Off? Then ' Segcvw1: Set Digsup.temp5 'Upper Digit On Segcvw2: Temp5 = Temp5 - 1 'Lower Digit On Set Digsup.temp5 Temp5 = Temp5 + 1 If Pind.6 = 0 Then Goto Segcvw3 'If Display is Decimal Mode? Then ' Bindt(temp5) = Temp3 'Lower Data is Written Segdt(temp5) = Segcvt(temp3 + 1) Or Temp6 Bindt(temp5 + 1) = Temp4 'Upper Data is Written Segdt(temp5 + 1) = Segcvt(temp4 + 1) Or Temp7 Return ' ' 'Decimal Mode Display Segcvw3: 'Lower Data is Written If Temp3 < 4 Then 'If Display Data is 0-3? Then Segdt(temp5) = Temp6 '0-3 Temp6 = 0 Set Temp6.temp3 Bindt(temp5) = Temp6 Else Temp3 = Temp3 - 4 '4-9 Set Temp6.temp3 Segdt(temp5) = Temp6 Bindt(temp5) = 0 End If ' 'Upper Data is Written If Temp4 < 4 Then 'If Display Data is 0-3? Then Segdt(temp5 + 1) = Temp7 '0-3 Temp7 = 0 Set Temp7.temp4 Bindt(temp5 + 1) = Temp7 Else Temp4 = Temp4 - 4 '4-9 Set Temp7.temp4 Segdt(temp5 + 1) = Temp7 Bindt(temp5 + 1) = 0 End If 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.3 = 0 Then Goto Hourcv1 'If Hour Display 12Hour Mode? Then Ptdtmp = &HC0 '24Hour Mode Hourcv2: Gosub Segcvw Temp1 = Tdhour Return ' Hourcv1: '12Hour Mode If Temp1 < 12 Then 'If AM or PM? Ptdtmp = &B11010000 'AM Set Else Ptdtmp = &B11100000 'PM Set 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: If Pinb.4 = 0 Then Goto Dpset1 'If Display Digit 4? Then Segdt(3) = Segdt(3) Or &H80 '*** There is a BASCOM Bug ** Dpset1: 'Set Segdt(3).7 == Error! Segdt(5) = Segdt(5) Or &H80 Return ' ' ********************************************** ' * Decimal Point Blink Bit Reset Sub Routine * ' ********************************************** ' Dpreset: Segdt(3) = Segdt(3) And &H7F Segdt(5) = Segdt(5) And &H7F Return ' ' ' ' *************************** ' * Program Version Display * ' *************************** ' Prgvds: Digsup = Digsup And &HFC 'Digit 1.2 = Display is erased 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.0 = 0 Then Goto Prgvds1 'If "Timset A" Key On? Then Goto Main End ' ' ' ' ************************* ' * DMA Display Interrupt * ' ************************* ' Dmaint: Timer2 = Scnspd 'Timer2 = DMA Scanning Speed Setting Select Case Dmablc Case 0 : 'Segment Data Change Portc = Segdt(digno + 1) Portd = Bindt(digno + 1) Or Ptdtmp Case 1 : 'Digit Bit ON (H Level) Set Ptatmp.digno Porta = Ptatmp And Digsup Case 7 : Ptatmp = Ptatmp And &HC0 'Digit Bit OFF (L Level) Porta = Ptatmp Digno = Digno + 1 If Digno > 5 Then If Pinb.4 = 1 Then 'If Display Digit 4or6? Digno = 0 Else Digno = 2 End If 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