PDA

View Full Version : Working with indivividual bytes of an array



J_norrie
- 29th December 2006, 20:06
I am writing this routine in picbsic pro to set a variable say Hours and then send it as part of a array of time and date variables to a 1307 RTC chip.

I domt seem to get it to work If I allocate the variable values at the beginning of the program and then call the settime routine then it works. I have included the code can someone explain why it dos not work.

kind regards John

'************************************************* ***************
'* Name : 1307_clock_Pad.BAS *
'* Author : John Norrie *
'* Notice : Copyright (c) John Norrie *
'* : All Rights Reserved *
'* Date : 22/12/2006 *
'* Version : 1.0 Digital Clock w/ Time *
'* Notes : for the 16 x2 LED *
'* : clock display module, DS1307 RTC *
'************************************************* ***************
' PIC16F877A @ 4MHz
DEFINE OSC 4
'DEFINE LOADER_USED 1 ' Comment out if not using boot-loader
INCLUDE "modedefs.bas"

' Set up 16x2 LCD Display

output PortE.2
output PortC.0
output PortC.1
output PortC.2
output PortC.3
output PortC.4

DEFINE LCD_DREG PORTC 'Set LCD Data port
DEFINE LCD_DBIT 0 'set start data bit 0 or 4
DEFINE LCD_RSREG PORTC 'set LCD Register select port
DEFINE LCD_RSBIT 4 'set LCD Register select bit
DEFINE LCD_EREG PORTE 'LCD Enable port
DEFINE LCD_EBIT 2 'LCD enable bit
DEFINE LCD_BITS 4 'set LCD BUS size 4 or 8
DEFINE LCD_COMMANDUS 2000 ' set command delay time us
DEFINE LCD_ DATAUS 50 'set data delay time us

' Note: use 10K pull-up resistors on both SDA and SCL i2C lines
' DS1307 control pins
SDA VAR PORTB.0 ' DS1307 SDA pin #5
SCL VAR PORTB.1 ' DS1307 SCL pin #6

' Variables
DB0 VAR BYTE[8] ' time date , data byte array
keypress var byte
Countvalue var byte
Countvalue1 var byte
Countvalue2 var byte
Countvalue3 var byte
Countvalue4 var byte
Year var BYTE

'Alias
Hours var DB0[2] 'hours
Mins var DB0[1] 'minutes
Secs var DB0[0] 'seconds
Day var DB0[3] 'day of week 0 = Sunday
Days var DB0[4] 'day of month
Months var DB0[5] 'month
Years var DB0[6] 'year starting at 0 (2000)
Square var DB0[7] '= $90 Square wave output control byte

'Symbols
Symbol row1 = PortD.0
Symbol row2 = PortD.1
Symbol row3 = PortD.2
Symbol row4 = PortD.3
Symbol col1 = PortD.4
Symbol col2 = PortD.5
Symbol col3 = PortD.6
Symbol col4 = PortD.7
SyMbol Print = PortB.3
SyMbol Auto = PortB.4
SyMbol Tare = PortB.5
SyMbol Trip1 = PortB.2
SyMbol Trip2 = PortB.6

' Port configuration
TRISC = %00000000
TRISB = 0
TRISA = 0
CMCON = %00000111 ' Comparators = off
input portb.4
input portb.3
input portb.2
input portD.0
input portD.1
input portD.2
input portD.3
high PortD.4
high PortD.5
high PortD.6
high PortD.7
low PortB.2
Low PortB.6
Countvalue1 = 0
Countvalue2 = 0
Countvalue = 15
Hours = 21
Mins = 59
Secs = 38
Days = 22
Months = 5
Year = 0
Years = 6


PAUSE 1000 ' Allow power to stabilize on power-up

' 24-hour clock routine for the DS1307 RTC w/SLED4C clock display
Main:
Gosub get_button
lcdout $fe,1, #keypress
lcdout $fe,$C0,hex keypress
pause 1000
'gosub SetTimeHrs
' if keypress = 12 then gosub SetTimeHrs
GOSUB Write_First_1307 ' Write time & date on entry coment out after setting initial time
' or if using keypad to set time
'goto main
Read_1307:

' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control
I2CREAD SDA,SCL,$D0,$00,[STR DB0\8] ' Read 8 bytes from DS1307
Gosub get_button
if tare = 0 then gosub tareval
IF auto = 1 then gosub trip_off
'lcdout $fe,1,#DB0[2],#DB0[1],#DB0[0]
'lcdout $fe,$C0,#DB0[4],#DB0[5],#DB0[6]

GOSUb Year_Table
lcdout $fe,1,"TIME=",dec DB0[2],".",dec DB0[1],".",dec DB0[0]
'lcdout $fe,$C0,"DATE=",hex DB0[4],".",hex DB0[5],".20",dec year ,dec DB0[6]
lcdout $fe,$C0,"DATE=",dec DB0[4],".",dec DB0[5],".20",dec year,dec DB0[6]
if KeyPress = 4 then SetTimeMins
if KeyPress = 5 then SetTimeHrs
if KeyPress = 6 then SetTimeDays
if KeyPress = 7 then SetTimeMonths
if KeyPress = 8 then SetTimeYears
PAUSE 2000 ' Display time for 2 seconds

GOTO Read_1307 ' Read & display Time

Write_First_1307:

I2CWRITE SDA,SCL,$D0,$00,[STR DB0\8]
I2CWRITE SDA,SCL,$D0,$00,[$00,Mins,Hours,$0,Days,Months,Years,$90] ' Write to DS1307
RETURN ' Sec Min Hr Day D M Y Control
END
tareval: high Trip1
high trip2
lcdout $fe,1, " Trips on "
return
trip_off: LOW Trip1
LOW trip2
lcdout $fe,1, " Trips off "
return
SetTimeHrs:

Gosub get_button
if KeyPress = 10 then Hours = Hours + 1
if KeyPress = 13 then Hours = Hours - 1
If Hours > 24 then Hours = 0
If Hours < 0 then Hours = 24
'Hours = Countvalue
lcdout $fe,1, "Set Hours 0-24" ' top line text
lcdout $fe,$C0, "Hours =", dec Hours ' bottom line text
SEROUT PortC.6,T9600,[#Hours,13,10]
If Keypress = 12 then Gosub Write_1307
pause 1000
If Keypress = 11 then return
goto SetTimeHrs

SetTimeMins:

Gosub get_button
if KeyPress = 10 then Countvalue = Countvalue + 1
if KeyPress = 13 then Countvalue = Countvalue - 1
If countvalue = 60 then Countvalue = 0
If countvalue < 0 then Countvalue = 0
Mins = Countvalue
lcdout $fe,1, "Set Mins 0-60" ' top line text
lcdout $fe,$C0, "Minutes =", dec Countvalue ' bottom line text
SEROUT PortC.6,T9600,[#countvalue,13,10]
If Keypress = 11 then Gosub Write_1307
pause 100
If Keypress = 11 then return
goto SetTimeMins

SetTimeDays:

Gosub get_button
if KeyPress = 10 then Countvalue = Countvalue + 1
if KeyPress = 13 then Countvalue = Countvalue - 1
If countvalue = 31 then Countvalue = 0
If countvalue < 0 then Countvalue = 31
Days = Countvalue
lcdout $fe,1, "Set Day 1-31" ' top line text
lcdout $fe,$C0, "Day =", dec Countvalue ' bottom line text
SEROUT PortC.6,T9600,[#countvalue,13,10]
If Keypress = 11 then Gosub Write_1307
pause 100
If Keypress = 11 then return
goto SetTimeDays

SetTimeMonths:

Gosub get_button
if KeyPress = 10 then Countvalue = Countvalue + 1
if KeyPress = 13 then Countvalue = Countvalue - 1
If countvalue = 12 then Countvalue = 0
If countvalue < 0 then Countvalue = 12
Months = Countvalue
lcdout $fe,1, "Set Month 1-12" ' top line text
lcdout $fe,$C0, "Month =", dec Countvalue ' bottom line text
SEROUT PortC.6,T9600,[#countvalue,13,10]
If Keypress = 11 then Gosub Write_1307
pause 100
If Keypress = 11 then return
goto SetTimeMonths

SetTimeYears:

Gosub get_button
if KeyPress = 10 then Countvalue = Countvalue + 1
if KeyPress = 13 then Countvalue = Countvalue - 1
If countvalue = 25 then Countvalue = 0
If countvalue < 0 then Countvalue = 25
Years = Countvalue
gosub year_table
lcdout $fe,1, "Set Year 7-25" ' top line text
lcdout $fe,$C0, "Year = 20",dec year, dec Countvalue ' bottom line text
SEROUT PortC.6,T9600,[#countvalue,13,10]
If Keypress = 11 then Gosub Write_1307
pause 100
If Keypress = 11 then return
goto SetTimeYears
Write_1307:

'I2CWRITE SDA,SCL,$D0,$00,[STR DB0\8]
I2CWRITE SDA,SCL,$D0,$00,[$00,Mins,Hours,$0,Days,Months,Years,$90] ' Write to DS1307
RETURN ' Sec Min Hr Day D M Y Control

get_button:

KeyPress = 0
col1 = 1
If row1 = 1 Then KeyPress = 1
If row2 = 1 Then KeyPress = 4
If row3 = 1 Then KeyPress = 7
If row4 = 1 Then KeyPress = 0
col1 = 0
col2 = 1
If row1 = 1 Then KeyPress = 2
If row2 = 1 Then KeyPress = 5
If row3 = 1 Then KeyPress = 8
If row4 = 1 Then KeyPress = 15 'F
col2 = 0
col3 = 1
If row1 = 1 Then KeyPress = 3
If row2 = 1 Then KeyPress = 6
If row3 = 1 Then KeyPress = 9
If row4 = 1 Then KeyPress = 14 'E
col3 = 0
col4 = 1
If row1 = 1 Then KeyPress = 10 'A
If row2 = 1 Then KeyPress = 11 'B
If row3 = 1 Then KeyPress = 12 'C
If row4 = 1 Then KeyPress = 13 'D
col4 = 0
Return

year_table:

if DB0[6] = 7 then year = $0
if DB0[6] = 8 then year = $0
if DB0[6] = 9 then year = $0

return

sayzer
- 29th December 2006, 20:27
In your code, where do you convert your values to HEX?

I could not find it, or see it.

(May be it is me...ohh these days I am feeling older (and elder) every passing second. )

-----------------

J_norrie
- 29th December 2006, 23:13
good point I what is the best way to convert it Hours = #Hours ?
would that work?

I apologise for my ignorance but I have just started with picbasic pro.

kind regards John

sougata
- 30th December 2006, 08:18
Hi,

As far as I remember the RTC holds the time in packed BCD format. That is the upper nibble is the tens and the lower nibble is the unit. So the formula to convert it would be
Real_Hours = (10* hour_tens)+ hour_units
In PBP this would be :


CLOCK_TMP1 = (HOURS >> 4) * 10 ' PROCESS 10s BCD
HOURS = HOURS & %00001111 ' PROCESS 1s BCD
HOURS = CLOCK_TMP1+ HOURS ' ADD BOTH TO GET BINARY

Where CLOCK_TMP1 is a temporary variable. You can do it in one line to. I broke up the thing to make it more readable

While working on a PCF8563 RTC chip I noticed that the unused bits in the memory map are not always "zero". Thus it is good idea to shred off the bits not used and make them zero manually. Like:


HOURS = HOURS & %00111111 ' clear unused bits
MINUTES = MINUTES & %01111111 ' clear unused bits


Happy New Year

sayzer
- 30th December 2006, 09:59
In addition to sougata's, here is a conversion from Melanie's.
You need to convert your decimal values to HEX values and then you can write the HEX values to your RTC chip.





DecVal = HOUR
GOSUB ConvertBCD
HOUR = HEXVal

'Now you set your RTC chip with this new HOUR variable (which is now in HEX).


ConvertBCD:
HEXVal = DecVal DIG 1
HEXVal = HEXVal <<4
HEXVal = HEXVal + DecVal DIG 0
RETURN





----------------

Edit: also take a look at this post here: http://www.picbasic.co.uk/forum/showthread.php?t=110

J_norrie
- 22nd January 2007, 20:16
Thanks again Guy's got the clock working fine writing and reading from the RTC chip.