PDA

View Full Version : Problems with I2CWRITE and the SAA1064 Seven-Segment Controller



triton99
- 24th November 2011, 16:39
I recently recieved a 4-digit seven-segment module that is controlled via I2C. The display has (4) seven-segment displays controlled by the SAA1064 4-digit LED-driver. The module has 4 pins, VCC, SDA, SCL, and GND. The display address is 0x70, which was selected by tieing the ADR pin of the SAA1064 to GND (This was already done on the module itself). I am new to using I2C devices and the corresponding commands in PICBASIC confuse me a bit. The SDA and SCL are both pulled high via 4.7Kohm resistors. If I understand correctly, you do not use constants in the I2CWRITE syntax; use variables only.

I cant for the life of me figure this out. What would be the correct form for I2CWRITE to utilize this display.
Any help would be greatly appreciated.

Thanks Sean Harmon


Here is a link (http://www.nxp.com/documents/data_sheet/SAA1064_CNV.pdf) to the datasheet for the SAA1064. http://www.nxp.com/documents/data_sheet/SAA1064_CNV.pdf

Here is some info from the datasheet:

6136
6137
6138

mackrackit
- 26th November 2011, 12:52
I have not used the part you are having trouble with, but this might help you understand the I2C commands better.
http://www.picbasic.co.uk/forum/content.php?r=165-Serial-EEPROM-Part-1

misamilanovic
- 27th November 2011, 09:28
SYMBOL SDA=PORTA.O 'this is just an example
SYMBOL SCL=PORTA.1 'you can use other ports

'---------------senging four digits to SAA1064--------------------------------------

I2CWRITE SDA,SCL,$70,0,$B7,[dig1,dig2,dig3,dig4]


$70 is adress byte, you allready have that fixed,
0 is instruction byte, by this you tell the chip that next byte is control byte (see datasheet, first line in subadressing),
and every following byte is written from this point.

$B7 is control byte or 10110111 and means:

0 bit determines are you in static (2 digits) or dynamic multiplex (4 digits) mode
1 bit turns off/on digits 1 and 3
2 bit turns off/on digits 2 and 4
3 bit is used for testing all segments, normally is 0
4 bit +3mA
5 bit +6mA
6 bit +12mA
7 bit not used, could be anything

So, $B7 would be: you are in dynamic mode, 4 digits on, not testing, 3+6=9mA into segments.
Or, it could be $77: you are in dynamic mode, 4 digits on, not testing, 3+6+12=21mA into segments.
You send digits in hex, for an example $7D is number 7.
You can send constants with I2CWRITE or use variables for control registers and change them wherever you want in program.

My english is not so good so....sorry if I made any mistakes.

triton99
- 28th November 2011, 00:21
Thanks mackrackit and misamilanovic for the replies. I did not succeed in using I2CWRITE but was successful using SHIFTIN/SHIFOUT.
Check out my blog post HERE (http://wp.me/p1QwT0-39) for more details.
But here is the PICBASIC code for a 16F88 that counts from 0-9 on all four digits.


'// for 4MHZ
DEFINE OSC 4
OSCCON=%01101000
'// for 8MHZ
'DEFINE OSC 8
'OSCCON=%01111000
While OSCCON.2=0:Wend
CMCON = 7 '// PORTA = digital I/O
'OPTION_REG.7 = 0 '// Enable PORTB pull-ups
ADCON1 = 7
ANSEL=%00000000 '// set all analog pins to digital
ANSEL = 0 '// disable ADCs
TRISB.3 = 0
TRISB.2 = 0
'----------------------------------------------------------------------------
led var PORTA.1
SDA VAR PORTB.3
SCL VAR PORTB.2
i2c_dev var byte 'I2C device Address
i2c_out VAR BYTE 'data to sent over I2C bus
i2c_ack VAR BIT 'acknowledgement bit
i var byte
segment VAR byte
seg_val var byte
'----------------------------------------------------------------------------
i2c_dev = %01110000 '(112 = %01110000 = $70)
gosub startup
GOSUB init_display 'initialize the display module
main:
GOSUB COUNTER
goto main
END

counter:
for i = 0 to 9
lookup i, [189,9,117,109,201,236,248,13,253,205],seg_val
for segment = 1 to 4
GOSUB I2C_START
if segment = 1 then
i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000001 : gosub i2C_tx
i2c_out = seg_val : gosub i2c_tx
gosub i2c_stop
endif
if segment = 2 then
i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000010 : gosub i2C_tx
i2c_out = seg_val : gosub i2c_tx
gosub i2c_stop
endif
if segment = 3 then
i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000011 : gosub i2C_tx
i2c_out = seg_val : gosub i2c_tx
gosub i2c_stop
endif
if segment = 4 then
i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000100 : gosub i2C_tx
i2c_out = seg_val : gosub i2c_tx
gosub i2c_stop
endif
next segment
pause 100
next i
return

bit_cycle:
for i = 0 to 255
gosub i2c_start
i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000001 : gosub i2C_tx
i2c_out = i
gosub i2C_tx
gosub i2c_stop
pause 20
next i

return
init_display: 'initialize the SAA1064 module and flash all segments
GOSUB I2C_START 'Start the I2C communication
i2c_out = %01110000 : GOSUB I2C_TX 'send device byte
i2c_out = %00000000 : GOSUB I2C_TX 'send instruction byte
i2c_out = %00011111 : GOSUB I2C_TX 'send control byte
GOSUB I2C_STOP 'Stop i2C transmission
pause 1000 ' leave segments on for 1 sec then turn off

GOSUB I2C_START
i2c_out = %01110000 : gosub i2C_tx
i2c_out = %00000000 : gosub i2C_tx
i2c_out = %00000001 : GOSUB I2C_TX
GOSUB I2C_STOP
pause 500

GOSUB I2C_START
i2c_out = %01110000 : gosub i2C_tx
i2c_out = %00000000 : gosub i2C_tx
i2c_out = %00010111 : GOSUB I2C_TX
GOSUB I2C_STOP
RETURN

I2C_START:
HIGH SDA
HIGH SCL
LOW SDA
RETURN

I2C_STOP: 'I2C stop (terminate communication on I2C bus)
HIGH SCL
HIGH SDA
PAUSE 1
RETURN

I2C_TX: 'I2C transmit -> send data to the slave
SHIFTOUT SDA,SCL,1,[i2c_out] 'Shift out “i2c_out” MSBfirst
SHIFTIN SDA,SCL,0,[i2c_ack\1] 'Receive ACK bit
RETURN
'// start-up led sequence
startup:
for i = 0 to 4
high led
pause 50
low led
pause 30
next i
pause 300
Return