' ********************************************************************** ' ** Program name: RTCSEGF2.BAS - Version : 1.1 - 22 May 2000 ** ' ** Compiler : BASCOM 8051, (IDE V.1.0.0.20, LIB V.1.20) ** ' ** Board : K51-AVR and GPC F2 ** ' ** Firm: grifo(r) ITALIAN TECHNOLOGY ** ' ** Via Dell' Artigiano 8/6 40016 San Giorgio di Piano (BO) ** ' ** Tel.+39 051 892 052 Fax +39 051 893 661 ** ' ** http://www.grifo.com http://www.grifo.it ** ' ** sales@grifo.it tech@grifo.it grifo@grifo.it ** ' ** ** ' ** Written by: Adriano Pedrielli ** ' ********************************************************************** ' ' This program allows to show the RTC or Real Time Clock on IC7 (PCF8583) ' to the four 7 segments displays through 2 TTL lines driven by the GPC F2 ' board which uses a family 51 microcontroller. ' To set the RTC values keys 2 and 3 on PC keyboard are used, in detail key 2 ' increments the hours and 3 increments the minutes. ' Whenever one of the two keys is pressed the seconds are reset. ' Key 1 switches between visualization of seconds and hours. ' Whenever a key is pressed, an acoustic signal is emitted. ' This program is controlled through the RS 232 serial line so it is essential ' to connect a free COM port on the PC to the connector CN3 of GPC(r) F2. ' Configure the BASCOM 8051 terminal using menu Option/Communication, select ' the COM port and set baud rate to 9600, parity to none, databits to 8 and ' stopbits to 1. ' ' Perform the follozing connections: ' GPC F2 K51 AVR ' +5Vdc (pin15 CN3) ----> +5Vdc (pin1 CN6) ' Gnd (pin16 CN3) ----> Gnd (pin2 CN6) ' T0 P3.4 (pin3 CN3) ----> SD (pin7 CN6) ' T1 P3.5 (pin1 CN3) ----> SC (pin8 CN6) ' ' Before compiling set in menu Option/Compiler/Misc/ : ' Byte End 5F; ' '*********************************************************************** ' '********************** Compiler directives **************************** ' $regfile = "REG51.DAT" ' list of CPU registers $romstart = &H8050 ' code start address ' &H8050 for MO52 Rel.1.1 in RAM IC8 ' &H0000 for EPROM withput RAM IC8 $ramstart = &HD000 ' add. of variables external RAM $ramsize = &H2800 ' assign 10K of external RAM ' to variables $crystal = 11059200 ' CPU clock frequence $baud = 9600 ' RS-232 communication speed $large ' 16 bit addressing ' ' ******************************* 8xc51 PIN list *********************** ' Config Sda = P3.4 ' line P3.4 or T0 (pin 3 of CN3) ' on GPC(r) F2 is Datak signal. Config Scl = P3.5 ' line P3.5 or T1 (pin 1 of CN3) ' on GPC(r) F2 is Clock signal. Buz Alias P1.2 ' Pin 3 of GPC F2 microcontroller ' is connected to the on board ' buzzer. Const Cler = 12 ' clear screen code Const Bel = 7 ' Bell code ' '********************* Constants declaration *************************** ' Dim Saa1064 As Const &H38 ' Slave address SAA1064 Dim Wsaa1064 As Const &H70 ' Slave address SAA1064 in Write Dim Rsaa1064 As Const &H71 ' Slave address SAA1064 in Read '****************** Addresses list for Saa1064 ************************* Dim Ctb As Const 0 ' Address Control byte Dim Dig1 As Const 1 ' Address Digit 1 Dim Dig2 As Const 2 ' Address Digit 2 Dim Dig3 As Const 3 ' Address Digit 3 Dim Dig4 As Const 4 ' Address Digit 4 '*********************************************************************** ' Dim Rtc As Const &H50 ' Slave address RTC PCF8583 Dim Wrtc As Const &HA0 ' Slave address RTC PCF8583 in Write Dim Rrtc As Const &HA1 ' Slave address RTC PCF8583 in Read ' '*********************** Variables declaration ************************* ' Dim Valore As Byte ' value to write to or read from ' I2CBUS etc Dim Sm As Byte ' keeps value of seconds Dim S As Byte ' seconds Dim M As Byte ' minutes Dim Ho As Byte ' hours Dim Wm As Byte ' week and month Dim Yd As Byte ' year and day Dim Dig As Byte ' value of a digit Dim Cifd As Byte ' figure of decines Dim Cifu As Byte ' figure of units Dim N1 As Byte ' BCD number for DY1 and DY2 Dim N2 As Byte ' BCD number for DY3 and DY4 Dim Vsec As Bit ' tells whether seconds are shown Dim Xbit As Bit ' tells status of decimal point Dim T As Byte ' codice del tasto premuto Dim Tstr As String * 1 ' one character string ' '********************** Procedure declarations ************************* ' Declare Sub Iniz ' Peripherals initialization etc. Declare Sub Cifre (valore As Byte , Cifd As Byte , Cifu As Byte ) ' converts a bcd number in ' two figures Declare Sub Digit (dig As Byte ) ' converts a number from 0 to 9 ' in 7 segments Declare Sub Vis_2num (n1 As Byte , N2 As Byte) ' shows two BCD numbers Declare Sub Settime (ho As Byte , M As Byte , S As Byte) ' clock programming Declare Sub Gettime ' clock visualization ' '*************************** Main program ****************************** ' Main: ' Delay for signals settling Waitms 1 Call Iniz ' initializations Do Do Call Gettime ' visualize RTC T = Inkey ' read a char from serial port Loop Until T <> 0 ' exit if received a character Tstr = Chr(t) ' convert char in string Select Case Tstr ' according to received char Case "1" : Gosub Vis_sec ' display seconds and hours Case "2" : Gosub Inc_ore ' increment hours Case "3" : Gosub Inc_min ' increment minutes Case "4" : Ljmp 0 ' exit and restart monitor Case Else : Print Chr(bel); ' char non valid End Select Loop ' infinite loop ' ' ***************** Seconds visualization management ********************** Vis_sec: ' complement bit status, ' thus seconds visualization is ' turned on or off Waitms 50 ' delay Vsec = Not Vsec Sound Buz , 100 , 250 ' turn on buzzer Buz = 1 ' turn off buzzer Return ' ' ************* Increment hours whenever key "2" is pressed *************** Inc_ore: Call Cifre(ho , Cifd , Cifu) ' convert hours BCD --> decimal If Valore < 23 Then ' increment only if lower than 23 Incr Valore ' increment hours Else Valore = 0 ' reset if hours is 23 End If Ho = Valore ' store hours in variable Call Cifre(m , Cifd , Cifu) ' convert minutes BCD --> decimal M = Valore ' store minutes in variable Goto Pr_rtc ' ' ************* Increment minutes whenever key "3" is pressed ************* Inc_min: Call Cifre(ho , Cifd , Cifu) ' convert hours BCD --> decimal Ho = Valore ' store hours in variable Call Cifre(m , Cifd , Cifu) ' convert minutes BCD --> decimal If Valore < 59 Then ' increment only if lower than 59 Incr Valore ' increment minutes Else Valore = 0 ' reset if minutes is 59 End If M = Valore ' store minutes in variable Pr_rtc: If Vsec = 0 Then ' seconds are not visualized Waitms 50 ' delay Call Settime(ho , M , 0) ' program RTC, resetting seconds Sound Buz , 100 , 250 ' turn on buzzer Buz = 1 ' turn off buzzer End If Return End ' '**************************** Program end ****************************** ' ' '**************************** Procedures ******************************* ' ' ********************** Peripherals initialization ******************** ' This procedure performs all the system initializations. ' Parameters: ' Input : nothing ' Output : nothing ' ********************************************************************** ' Sub Iniz ' Peripherals initialization Print Chr(cler); ' clear screen Print "Demo K51-AVR for RTC IC7(PCF8583) through GPC F2 rel.1.1 22/05/2000" Print Print " 1) Show seconds or hours" Print " 2) Increment hours by 1" Print " 3) Increment minutes by 1" Print " 4) Exit" Print Print "Press one of the 4 keys on P.C. keyboard" Vsec = 0 ' do not visualize seconds Yd = 0 ' reset year plus day variable Wm = 0 ' reset week plus month variable Do I2creceive Rsaa1064 , Valore ' read status regoster Loop Until Valore = 0 ' wait for SAA1064 to turn on I2cstart ' Start sequence for I2CBUS I2cwbyte Wsaa1064 ' Communicate the Slave address I2cwbyte Ctb ' point to control register I2cwbyte &B00100111 ' bit0 =1 dynamic mode ' bit1 =1 digit 1+3 not blanked ' bit2 =1 digit 2+4 not blanked ' bit3 =0 no test segment ' bit4 =0 no 3mA segment current ' bit5 =1 6mA segment current ' bit6 =0 no 12mA segment current ' bit7 =0 indifferent I2cwbyte 0 ' sets DY1 off I2cwbyte 0 ' sets DY2 off I2cwbyte 0 ' sets DY3 off I2cwbyte 0 ' sets DY4 off I2cstop End Sub ' ' *********** Converts a figure in range from 0 to 9 in 7 segments ***** ' This procedure converts a figure in range from 0 to 9 in 7 segments ' format, if value is greater than 9 the display is off. ' Parameters: ' Input : dig as byte, value from 0 to 9 ' Output : dig as byte, value in 7 segments format. ' ********************************************************************** ' Sub Digit (dig As Byte ) ' Converts a number in range 0-9 ' in 7 segments If Dig < 10 Then ' number is lower than 10 Dig = Lookup(dig , Tab_7seg) ' read value from table Else Dig = 0 ' if = 10 or greater reset End If End Sub ' ' ******************* Converts a BCD number in two figures *************** ' This procedure converts a BCD number from 0 to 153 (DEC 0-99) in two ' separated figures and returns the decimal value, so the BCD can be ' shown. ' If the number is greater than 153 the two figures are assigned the value ' of ten that means 7 segments display off. ' Parameters: ' Input : Valore as byte, value from 0 to 153 BCD ( Decimal 0..99) ' Output : Cifd as byte, decines figure ' Cifu as byte, units figure ' Valore as byte, contains the decimal value of the BCD number ' ********************************************************************** ' Sub Cifre (valore As Byte , Cifd As Byte , Cifu As Byte ) ' Converts a BCD number ' in two figures If Valore < 154 Then ' if is lower than 154 BCD ' (100 in DEC) Cifd = Valore / 16 ' calculate decines figure Cifu = Cifd * 16 Cifu = Valore - Cifu ' calculate units figure Valore = Cifd * 10 Valore = Valore + Cifu ' calculate decimal value Else Cifd = 10 ' turn off decines figure Cifu = 10 ' turn off units figure Valore = 0 ' reset decimale value End If End Sub ' ' **************** Visualizes the hour stored in the RTC *************** ' Parameters: ' Input : nothing ' Output : nothing ' ********************************************************************** ' Sub Gettime I2cstart ' Start sequence for I2CBUS I2cwbyte Wrtc ' address to write to PCF8583 I2cwbyte 2 ' point to register 2 I2cstart ' repeat start sequence of I2CBUS I2cwbyte Rrtc ' point address to read I2crbyte S , Ack ' read seconds register 2 I2crbyte M , Ack ' read minutes register 3 I2crbyte Ho , Ack ' read hours register 4 I2crbyte Yd , Ack ' read year and day register 5 I2crbyte Wm , Nack ' write week and month register 6 I2cstop ' Stop sequence for I2CBUS If Vsec = 0 Then ' do not visualize seconds Call Vis_2num(ho , M) ' visualize hours and minutes Else Call Vis_2num(154 , S) ' turn off first 2 figures End If ' visualize 2 figures of seconds End Sub ' ' *********************** Visualizes 2 BCD numbers ************************ ' This procedure allows to visualize two BCD numbers that in decimal are ' made of two figures. E.g.: BCD 153= Dec. 99 ' As time goes, each variation of seconds turns on or off the decimal point ' of DY2. ' ' Parameters: ' Input : N1 as byte, value first number ' N2 as byte, value second number ' Output : nothing ' ************************************************************************ ' Sub Vis_2num (n1 As Byte , N2 As Byte) ' visualize 2 BCD numbers I2cstart ' Start sequence for I2CBUS I2cwbyte Wsaa1064 ' Communicate the Slave address I2cwbyte Dig1 ' point to display 1 (DY1) Call Cifre(n1 , Cifd , Cifu) ' convert number1 in 2 figures If Cifd = 0 Then ' if figure = 0 turn it off Cifd = 10 End If Call Digit(cifd) ' convert decines figure ' in 7 segments I2cwbyte Dig ' output to first display Call Digit(cifu) ' convert unites figure ' in 7 segments If Sm <> S Then ' if seconds changed CPL {XBIT} ' turn on decimal point Sm = S ' store seconds End If If Xbit = 1 Then ' if flag is on Dig = Dig Or 128 ' turn on decimal point End If ' normallly it is not visualized I2cwbyte Dig Call Cifre(n2 , Cifd , Cifu) ' convert number2 in 2 figures Call Digit(cifd) ' convert decines figure ' in 7 segments I2cwbyte Dig ' output to third display Call Digit(cifu) ' convert unites figure ' in 7 segments I2cwbyte Dig ' output to fourth display I2cstop ' Stop sequence for I2CBUS End Sub ' ' *********************** RTC PCF8583 programming ************************** ' This procedure sets the hour in the RTC. ' Values of variables are converted into BCD. ' Date and alarm are not managed. ' Parameters. ' Input : Ho as byte, value for hours ' M as byte, value for minutes ' S as byte, value for seconds ' Output : nothing ' ************************************************************************ ' Sub Settime(ho As Byte , M As Byte , S As Byte) S = Makebcd(s) ' seconds M = Makebcd(m) ' minutes Ho = Makebcd(ho) ' hours I2cstart ' Start sequence for I2CBUS I2cwbyte Wrtc ' address to write to PCF8583 I2cwbyte 0 ' selects control register ' in register 0 I2cwbyte 0 ' starts high bits read I2cstop ' Stop sequence for I2CBUS ' I2cstart ' Start sequence for I2CBUS I2cwbyte Wrtc ' address to read from PCF8583 I2cwbyte 2 ' point to register 2 I2cwbyte S ' writes seconds, register 2 I2cwbyte M ' writes minutes, register 3 I2cwbyte Ho ' writes hours, register 4 I2cstop ' Stop sequence for I2CBUS End Sub ' ' ** Conversion table for 7 segments figure in the range from 0 to 10 ** Tab_7seg: ' num. 0 1 2 3 4 5 6 7 8 9 Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F ' ********************************************************************** '