PDA

View Full Version : I2c & Variable Size



Bill Legge
- 15th February 2008, 06:59
I'm using: PIC16F877A @ 20 MHz, an I2C RTC with PBP.

The story so far:

1. All works well - set the clock, read it and display the time.
2. I have a loop counter (VAR BYTE) in my software to do a job not connected with the RTC.
3. As long as the variable is a BYTE it works properly.
4. But if I make the loop counter a WORD - it will not increment (Variable = Variable + 1) fails to work. If I by-pass the RTC - it starts working!
5. The name of the loop counter is unique and not used in the RTC code.
6. I do need the variable to be word-sized.

Any ideas anyone?

Regards Bill Legge

skimask
- 15th February 2008, 07:11
I'm using: PIC16F877A @ 20 MHz, an I2C RTC with PBP.
The story so far:
1. All works well - set the clock, read it and display the time.
2. I have a loop counter (VAR BYTE) in my software to do a job not connected with the RTC.
3. As long as the variable is a BYTE it works properly.
4. But if I make the loop counter a WORD - it will not increment (Variable = Variable + 1) fails to work. If I by-pass the RTC - it starts working!
5. The name of the loop counter is unique and not used in the RTC code.
6. I do need the variable to be word-sized.
Any ideas anyone?
Regards Bill Legge

Use 2 nested byte size LOOP counter variables:
For temp1 = 1 to 10
for temp2 = 1 to 10
work work work work work
next temp2
next temp1

Individually, they count to 10, together they count to 100. Same thing if you've got 2 byte counters nested. Individually, they count to 256, together they count to 65536. Do the multiplication/shifting inside the routine as required to get the actual word variable.

Or, just post the code so we can all help you figure out why the WORD is failing...

Bill Legge
- 15th February 2008, 09:19
SkiMask - thanks for your speedy reply. The code is below. The problem variable is
called 'LoopCounter' and is set at WORD length. THe loop does not increment.

If LoopCounter is made a BYTE all works as it should. Help?

'File...... Test Program
'
' Philips PCF8583 I2C RTC gives the time/date
' PIC16F877A on Mikro board is run @ 20 MHz
' After amendment to pbppic14.lib - now works at 20 MHz
'
' PIC LCD RS232 RTC DS1820 EEPROM
' --- --- ----- --- ------ ------
' C3 SCL ' I2C device, TRC clock
' C4 SDA ' I2C device, RTC data
' D2 RS ' LCD reset
' D3 EBIT ' LCD enable
' D4 DB4 ' LCD data 4
' D5 DB5 ' LCD data 5
' D6 DB6 ' LCD data 6
' D7 DB7 ' LCD data 7
'
' ----[ Variables ]---------------------------------------------------
'
DataPin var PORTC.4 ' RTC data
ClockPin var PORTC.3 ' RTC clock
Mins var byte ' Minutes on RTC
Hours var byte ' Hours on RTC
Days var byte ' Days on TTC
Months var byte ' Months on RTC
Time var byte[3] ' Holds months,days,hours,mins read from RTC
Dtime var byte[3] ' Holds months,days,hours,mins in HEX format
Units var byte ' Derived from Time
Tens var byte ' Derived form Time
CControl var byte ' Control byte for RTC
'
LoopCounter var word ' The 'problem' loop counter
J var byte ' Loop counter for RTC read/write
'
' ----[ Includes / Defines ]------------------------------------------
'
define OSC 20 'Now works at 20 MHz
DEFINE LCD_DREG PORTD 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 4 'Define first pin of portb connected to LCD DB4
DEFINE LCD_RSREG PORTD 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 2 'Define Portb pin used for RS connection
DEFINE LCD_EREG PORTD 'Define PIC prot used for E line of LCD
DEFINE LCD_EBIT 3 'Define PortB pin used for E connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data
'
' -----[ Initialization ]--------------------------------------------------
'
LoopCounter = 0 'EEPROM address counter - when I get it working!!!
J = 0 'Time[x] loop counter
CControl = %10100000 'Control word for RTC
'
' -----[ Main Program ]----------------------------------------------------
Start:
lcdout $fe,1,"Test Program"
Pause 1000
lcdout $fe,1

' -----[ Set Time ]-------------------------------------------------------
TimeSet
i2cwrite DataPin, ClockPin, CControl, $0, [%00001000]
'Control register for RTC, sets bit 3 to mask unwanted bits in time/date registers
i2cwrite DataPin, ClockPin, CControl, $2, [%00000000,%01011001,%00100011,%00110000,%00010001]
'BCD code, sets time registers to 0 Sec, 59 Min, 23 Hr, 30 Day, Month 11

' -----[ Main Program ]-----------------------------------------------------
Run:

' Time Read
i2cread DataPin, ClockPin, %10100000, $3, [Time[0], Time[1], Time[2], Time[3]]
Pause 20
'Time[0] = Min, Time[1] = Hr, Time[2] = Day, Time[3] = Month

' Time Show
for J = 0 to 3 'this works because the 'mask' is set and Time[x] bytes are all in BCD format.
Tens = Time[J] & %11110000
Tens = Tens>>4
Tens = Tens * 10
Units = Time[J] & %00001111
DTime[J] = Tens + Units 'Dtime is used to "Display Time"
next j

LCDout $FE, 1, "Mth: ", Dec DTime[3], " Day: ", dec DTime[2]
lcdout $FE, $C0, "Hrs: ", dec Dtime[1], " Min: ", DEC Dtime[0]
pause 1000

' Loop Counter
lcdout $FE,1,"Loop Ctr: ", DEC LoopCounter
pause 1000

LoopCounter = LoopCounter + 1

goto run

END


Sorry - the code has come out in a rather messy layout?

skimask
- 15th February 2008, 17:26
DEFINEs before everything else...that's my theory...ALL CAPs for all DEFINEs

DEFINE OSC 20 'Now works at 20 MHz

No COLON : after TimeSet

Don't use the ' or " in the comments after a line, except for the character defining the comment itself. When you get into mixing assembly with PBP, it'll mess you up in the future.

Maybe somebody else has some good ideas, 'cause I'm out at the moment...

skimask
- 15th February 2008, 20:59
Does this work? (I know it's not formatted like you had it, just see if it works)


DEFINE OSC 20 'Now works at 20 MHz
DEFINE LCD_DREG PORTD 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 4 'Define first pin of portb connected to LCD DB4
DEFINE LCD_RSREG PORTD 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 2 'Define Portb pin used for RS connection
DEFINE LCD_EREG PORTD 'Define PIC prot used for E line of LCD
DEFINE LCD_EBIT 3 'Define PortB pin used for E connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data
sda var portc.4:scl var portc.3:min var byte:hour var byte:day var byte:month var byte
time var byte[3]:dtime var byte[3]:units var byte:tens var byte:control var byte
loopcounter var word:loopcnt1 var loopcounter.lowbyte:loopcnt2 var loopcounter.highbyte
j var byte:loopcnt1=0:loopcnt2=0:j=0:control=$a0
Start: lcdout $fe,1,"Test Program":Pause 1000:i2cwrite sda,scl,control,0,[8]
i2cwrite sda,scl,control,2,[0,$59,$23,$30,$11]
run: i2cread sda,scl,control,3,[Time[0],Time[1],Time[2],Time[3]]:Pause 20
for J=0 to 3:tens=((time[J] & $f0)>>4)*10:units=time[j] & $f:dtime[j]=tens+units:next j
lcdout $fe,1,"Mth: ",dec dtime[3]," Day: ",dec dtime[2]
lcdout $fe,$c0,"Hrs: ",dec dtime[1]," Min: ",dec dtime[0]:pause 1000
lcdout $fe,1,"Loop Ctr:",dec5 loopcounter:pause 1000 'might want to knock this down so the program runs a bit faster eh?
loopcnt1=loopcnt1+1:if loopcnt1 = 0 then loopcnt2=loopcnt2+1
goto run
END




(HCM strikes again!)

Archangel
- 15th February 2008, 21:52
I'm using: PIC16F877A @ 20 MHz, an I2C RTC with PBP.

The story so far:

1. All works well - set the clock, read it and display the time.
2. I have a loop counter (VAR BYTE) in my software to do a job not connected with the RTC.
3. As long as the variable is a BYTE it works properly.
4. But if I make the loop counter a WORD - it will not increment (Variable = Variable + 1) fails to work. If I by-pass the RTC - it starts working!
5. The name of the loop counter is unique and not used in the RTC code.
6. I do need the variable to be word-sized.

Any ideas anyone?

Regards Bill Legge
Hi Bill,
Without having a firm grasp on your code . . . It works with BYTE variable, but not WORD . . . don't you have to split the word into highbyte and lowbyte to use it?
ahhh: not : that : i: could: read: it: :) Looks like skimask said that already!

paul borgmeier
- 15th February 2008, 23:20
I have not studied your code but....

>>Time var byte[3] ' Holds months,days,hours,mins read from RTC

and then

>>Time[3] = Month

You are overwriting the LoopCounter LowByte here (see your LST file) - change the [3] to [4] in the VAR define.

Bill Legge
- 16th February 2008, 00:04
Thanks for your replies:

Skimask:
1. DEFINE OSC 20 was in caps in my code, I messed it up whilst trying to tidy up the post.
2. Colon after TimeSet. As above, another 'posting mistake on my part. Code was OK.
3. Don't use " or '. Point taken - I'll change the comments and try again.
4. Thanks for the code - I'll give it a go. What is HCM?

Joe S:
1. HighByte/LowByte split - agreed I could 'work around' the problem but it seems
important to me that I find out why a WORD won't increment around an I2C read.

Paul B:
1. I think the array size is OK; Time[3] has 4 elements: 0,1,2,3. I'll check with a bit of test code.

Thanks to you all

Regards Bill Legge

paul borgmeier
- 16th February 2008, 00:12
>>Paul B:
>>1. I think the array size is OK; Time[3] has 4 elements: 0,1,2,3. I'll check with a bit of test >>code.

Hi Bill,

Not OK- see your manual or your lst file

Bill Legge
- 16th February 2008, 01:54
Paul B,

Thanks - I agree. Time[3] would give me 3 elements 0,1,2.
I'll make the changes.

I've returned to electronics after a gap of 25 years and find my
main difficulty is with the easier bits that I think I already know
and don't bother to look them up - hence this sort of mistake.

Regards

Bill Legge

SteveB
- 16th February 2008, 05:50
Not just Time, but Dtime also needs to be dimensioned correctly. :)

Time var byte[4] ' Holds months,days,hours,mins read from RTC
Dtime var byte[4] ' Holds months,days,hours,mins in HEX format

SteveB

Bill Legge
- 16th February 2008, 07:41
Thanks, I've changed the arrays to the correct size and -IT WORKS.

Sorry to bang on about WORD/BYTE/I2C when I just got a variable format wrong.

regards

Bill Legge

skimask
- 16th February 2008, 08:08
Skimask:
4. Thanks for the code - I'll give it a go. What is HCM?
Regards Bill Legge

Somebody coined the phrase for me awhile back... the 'High Colonic Master'. I like to use colons in my coding to keep as much of it on the screen at one time, prevent as much vertical scrolling as I can. Most people hate it, but I'm not writing code for most people, I'm writing code for me, and the majority of what I post here (or modify), gets the same treatment 'cause I like it that way...
that's all, nothing much...

I totally missed the array variable dimensioning thing...oh well...