A short video:
The master on the left, a 16F877 is telling the first 16F88 (on the top) to turn on/off the LED, and then reads 24 from it. After that, the master tells the second 16F88 (on the bottom) to turn on/off the LED, and then reads 12 from it.
It's in slow motion because I was testing everything, but I discovered that the I2C protocol is very fast!
Al, thanks a lot one more time!
Daniel.
Master 16f877 - External 4Mhz Crystal:
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
' Master
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
DEFINE OSC 4
'OPTION_REG.7 = 0
ADCON1 = 7
'------------------------------------------------------------------------------
DEFINE I2C_SLOW 1
TRISB.5 = 1
TRISB.7 = 1
'------------------------------------------------------------------------------
scl VAR PORTB.5 ' i2c clock input
sda VAR PORTB.7 ' i2c data input
'------------------------------------------------------------------------------
I2Caddress VAR BYTE
valor VAR BYTE
'------------------------------------------------------------------------------
' Set LCD Data port
DEFINE LCD_DREG PORTD
' Set starting Data BIT (0 OR 4) IF 4-BIT bus
DEFINE LCD_DBIT 4
' Set LCD Register Select port
DEFINE LCD_RSREG PORTC
' Set LCD Register Select BIT
DEFINE LCD_RSBIT 6
' Set LCD Enable port
DEFINE LCD_EREG PORTC
' Set LCD Enable BIT
DEFINE LCD_EBIT 7
' Set LCD bus size (4 OR 8 bits)
DEFINE LCD_BITS 4
' Set number of lines ON LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 2000
' Set Data delay time in us
DEFINE LCD_DATAUS 50
'------------------------------------------------------------------------------
Pause 500 ' Wait for LCD to startup
LCDOut $fe, 1
LCDOut $fe, "Daniel"
Pause 500 ' Wait for LCD to startup
valor = 0
'------------------------------------------------------------------------------
main:
I2Caddress = $3
LCDOut $fe, 1
LCDOut "Writting 1 - LED ON..."
Pause 500
I2CWrite SDA, SCL, I2Caddress, [6], bogus ' Write offset to slave
Pause 500
LCDOut $fe, 1
LCDOut "Writting 1 - LED OFF..."
Pause 500
I2CWrite SDA, SCL, I2Caddress, [8], bogus ' Write to slave
Pause 500
LCDOut $fe, 1
LCDOut "Reading 1..."
Pause 500
I2CRead SDA, SCL, I2Caddress, [valor], bogus ' Read from slave
LCDOut $fe, 1
LCDOut "Value: ", DEC valor
Pause 500
'--------
I2Caddress = $5
LCDOut $fe, 1
LCDOut "Writting 2 - LED ON..."
Pause 500
I2CWrite SDA, SCL, I2Caddress, [4], bogus ' Write to slave
Pause 500
LCDOut $fe, 1
LCDOut "Writting 2 - LED OFF..."
Pause 500
I2CWrite SDA, SCL, I2Caddress, [10], bogus ' Write to slave
Pause 500
LCDOut $fe, 1
LCDOut "Reading 2..."
Pause 500
I2CRead SDA, SCL, I2Caddress, [valor], bogus ' Read from slave
LCDOut $fe, 1
LCDOut "Value: ", DEC valor
Pause 500
'--------
GoTo main ' Do it forever
'-------------------------------------------------------------------------------
bogus:
LCDOut $fe,1, "Time out" ' I2C command timed out
Pause 500
GoTo main
'-------------------------------------------------------------------------------
End
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' Slave
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
@ device pic16f88, intrc_osc_noclkout ' system clock options
@ device pic16f88, wdt_on ' watchdog timer
@ device pic16f88, pwrt_on ' power-on timer
@ device pic16f88, mclr_off ' master clear options (internal)
@ device pic16f88, protect_off ' code protect off
'--- set device ---------------------------------------------------------------
DEFINE OSC 8
OSCCON = %01110001 '8mhz
'------------------------------------------------------------------------------
CMCON = 7
ADCON1 = 0 ' Disable A/D converter
ADCON0 = 0
ANSEL = 0 ' all analog pins to digital
'--- tris port config here (don't use SCL & SDA pins other than I2C) ----------
DEFINE I2C_HOLD 1
TRISB.1 = 1
TRISB.4 = 1
'--- Alias pins ---------------------------------------------------------------
SDADIR VAR TRISB.1
SCLDIR VAR TRISB.4
'--- Define here your variables and alias -------------------------------------
LEDT VAR PORTA.2
LEDL VAR PORTB.7
LEDM VAR PORTB.6
LEDR VAR PORTB.5
readcnt VAR BYTE
datain VAR BYTE
WrData VAR BYTE
'--- Define used register flags ------------------------------------------------
SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag
SSPIE VAR PIE1.3
BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
R_W VAR SSPSTAT.2 ' SSP (I2C) Read/Write
D_A VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKP VAR SSPCON.4 ' SSP (I2C) SCK Release Control
SSPEN VAR SSPCON.5 ' SSP (I2C) Enable
SSPOV VAR SSPCON.6 ' SSP (I2C) Receive Overflow Indicator
WCOL VAR SSPCON.7 ' SSP (I2C) Write Collision Detect
STAT_BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
STAT_RW VAR SSPSTAT.2 ' SSP (I2C) Read/Write
STAT_DA VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKE VAR SSPSTAT.6 ' SSP (I2C) Data/Address
'--- Rx Buffer defintion ------------------------------------------------------
RxBufferLEN CON 1
RxBuffer VAR BYTE[Rxbufferlen]
RxBufferIndex VAR BYTE
'--- Tx Buffer defintion ------------------------------------------------------
TxBufferLEN CON 1
TxBuffer VAR BYTE[txbufferlen]
TxBufferIndex VAR BYTE
'--- Define constants ---------------------------------------------------------
I2Caddress CON $3 ' Make address = 3
'--- Initialize I2C slave mode ------------------------------------------------
SCLDIR = 1 ' SCL must be an input before enabling interrupts
SDADIR = 1
SSPADD = I2Caddress ' Set our address
SSPCON = $36 ' Set to I2C slave with 7-bit address
SSPSTAT = 0
SSPIE = 1
SSPIF = 0
RxBufferIndex = 0
TxBufferIndex = 0
'--- Initialization Done! -----------------------------------------------------
GoTo main
'--- I2C subroutine ----------------------------------------------------------
i2cslave: ' I2C slave subroutine
SSPIF = 0 ' Clear interrupt flag
IF R_W = 1 Then i2crd ' Read data from us
IF BF = 0 Then i2cexit ' Nothing in buffer so exit
IF D_A = 1 Then i2cwr ' Data for us (not address)
IF SSPBUF != I2Caddress Then i2cexit ' Clear the address from the buffer
readcnt = 0 ' Mark as first read
GoTo i2cexit
i2cwr: ' I2C write data to us
datain = SSPBUF ' Put buffer data into array
Rxbuffer[Rxbufferindex]=datain
Rxbufferindex=rxbufferindex+1
IF rxbufferindex=RxBufferLEN Then ' end of buffer transfer
WrData=1
rxbufferindex=0
EndIF
GoTo i2cexit
i2crd: ' I2C read data from us
IF D_A = 0 Then
TxBufferIndex = 0
EndIF
While STAT_BF : Wend ' loop while buffer is full
wcol = 0 ' clear collision flag
SSPBUF = TxBuffer[TxBufferIndex]
While wcol
wcol = 0
SSPBUF = TxBuffer[TxBufferIndex]
Wend
CKP = 1 ' release clock, allowing read by master
TxBufferIndex = TxBufferIndex + 1 ' increment index
IF TxBufferIndex = TxBufferlen Then ' all bytes have been tx
TxBufferIndex = 0 ' reset index
EndIF
i2cexit:
Return
'--- End I2C subroutine ------------------------------------------------------
Main:
txbuffer = 12
IF SSPIF = 1 Then
GoSub i2cslave
EndIF
SSPOV = 0
WCOL = 0
Select Case RxBuffer[0]
Case 6
High LEDT
Case 8
Low LEDT
End Select
WrData=0
GoTo Main
'------------------------------------------------------------------------------
End
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' Slave
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
@ device pic16f88, intrc_osc_noclkout ' system clock options
@ device pic16f88, wdt_on ' watchdog timer
@ device pic16f88, pwrt_on ' power-on timer
@ device pic16f88, mclr_off ' master clear options (internal)
@ device pic16f88, protect_off ' code protect off
'--- set device ---------------------------------------------------------------
DEFINE OSC 8
OSCCON = %01110001 '8mhz
'------------------------------------------------------------------------------
CMCON = 7
ADCON1 = 0 ' Disable A/D converter
ADCON0 = 0
ANSEL = 0 ' all analog pins to digital
'--- tris port config here (don't use SCL & SDA pins other than I2C) ----------
DEFINE I2C_HOLD 1
TRISB.1 = 1
TRISB.4 = 1
'--- Alias pins ---------------------------------------------------------------
SDADIR VAR TRISB.1
SCLDIR VAR TRISB.4
'--- Define here your variables and alias -------------------------------------
LEDT VAR PORTA.2
LEDL VAR PORTB.7
LEDM VAR PORTB.6
LEDR VAR PORTB.5
readcnt VAR BYTE
datain VAR BYTE
WrData VAR BYTE
'--- Define used register flags ------------------------------------------------
SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag
SSPIE VAR PIE1.3
BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
R_W VAR SSPSTAT.2 ' SSP (I2C) Read/Write
D_A VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKP VAR SSPCON.4 ' SSP (I2C) SCK Release Control
SSPEN VAR SSPCON.5 ' SSP (I2C) Enable
SSPOV VAR SSPCON.6 ' SSP (I2C) Receive Overflow Indicator
WCOL VAR SSPCON.7 ' SSP (I2C) Write Collision Detect
STAT_BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
STAT_RW VAR SSPSTAT.2 ' SSP (I2C) Read/Write
STAT_DA VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKE VAR SSPSTAT.6 ' SSP (I2C) Data/Address
'--- Rx Buffer defintion ------------------------------------------------------
RxBufferLEN CON 1
RxBuffer VAR BYTE[Rxbufferlen]
RxBufferIndex VAR BYTE
'--- Tx Buffer defintion ------------------------------------------------------
TxBufferLEN CON 1
TxBuffer VAR BYTE[txbufferlen]
TxBufferIndex VAR BYTE
'--- Define constants ---------------------------------------------------------
I2Caddress CON $5 ' Make address = 5
'--- Initialize I2C slave mode ------------------------------------------------
SCLDIR = 1 ' SCL must be an input before enabling interrupts
SDADIR = 1
SSPADD = I2Caddress ' Set our address
SSPCON = $36 ' Set to I2C slave with 7-bit address
SSPSTAT = 0
SSPIE = 1
SSPIF = 0
RxBufferIndex = 0
TxBufferIndex = 0
'--- Initialization Done! -----------------------------------------------------
GoTo main
'--- I2C subroutine ----------------------------------------------------------
i2cslave: ' I2C slave subroutine
SSPIF = 0 ' Clear interrupt flag
IF R_W = 1 Then i2crd ' Read data from us
IF BF = 0 Then i2cexit ' Nothing in buffer so exit
IF D_A = 1 Then i2cwr ' Data for us (not address)
IF SSPBUF != I2Caddress Then i2cexit ' Clear the address from the buffer
readcnt = 0 ' Mark as first read
GoTo i2cexit
i2cwr: ' I2C write data to us
datain = SSPBUF ' Put buffer data into array
Rxbuffer[Rxbufferindex]=datain
Rxbufferindex=rxbufferindex+1
IF rxbufferindex=RxBufferLEN Then ' end of buffer transfer
WrData=1
rxbufferindex=0
EndIF
GoTo i2cexit
i2crd: ' I2C read data from us
IF D_A = 0 Then
TxBufferIndex = 0
EndIF
While STAT_BF : Wend ' loop while buffer is full
wcol = 0 ' clear collision flag
SSPBUF = TxBuffer[TxBufferIndex]
While wcol
wcol = 0
SSPBUF = TxBuffer[TxBufferIndex]
Wend
CKP = 1 ' release clock, allowing read by master
TxBufferIndex = TxBufferIndex + 1 ' increment index
IF TxBufferIndex = TxBufferlen Then ' all bytes have been tx
TxBufferIndex = 0 ' reset index
EndIF
i2cexit:
Return
'--- End I2C subroutine ------------------------------------------------------
Main:
txbuffer = 24
IF SSPIF = 1 Then
GoSub i2cslave
EndIF
SSPOV = 0
WCOL = 0
Select Case RxBuffer[0]
Case 4
High LEDT
Case 10
Low LEDT
End Select
WrData=0
GoTo Main
'------------------------------------------------------------------------------
End
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------


Menu

Re: Has anyone tried AI with PICBASIC
What I figured by myself and what actually helps is when asking AI to write picbasic pro code, if you specify write code for "PicBasic Pro 3", not only "PicBasic Pro", it will make far less errors in...
CuriousOne Yesterday, 10:07