PDA

View Full Version : Problem with I2C



syryus
- 3rd May 2012, 18:26
Hello to everyone!

I attempt to read temperature from a DS1621. The program is really simple, but I have a short experience programming and it doesn't work. I hope you can help me. Here is my code:



@__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
@__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
@__CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_ON_2L & _BORV_3_2L & _VREGEN_ON_2L
@__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
@__CONFIG _CONFIG3H, _CCP2MX_ON_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_OFF_3H
@__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L


'LCD
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 2


'I2C
CMCON = 7
ADCON1 = 7
SCL VAR PORTA.0
SDA VAR PORTA.1
WO var WORD
T1 var WO.byte0
T2 var WO.byte1
main:
i2cwrite SDA,SCL,%10010000
Pause 10
i2cwrite SDA,SCL,$90,$AC,[0]
Pause 10
i2cwrite SDA,SCL,$90,$EE
Pause 50
i2cwrite SDA,SCL,$90,$AA
pause 10
i2cread SDA,SCL,$91,[T1,T2]
pause 10
LCDout $FE,1
LCDout $FE,1, #WO
goto main




I only want to show in an LCD the data from the DS1621

Thank you!

syryus
- 6th May 2012, 13:09
I updated the code with things I have learned from internet but it doesn't work yet.



@__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
@__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
@__CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_ON_2L & _BORV_3_2L & _VREGEN_ON_2L
@__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
@__CONFIG _CONFIG3H, _CCP2MX_ON_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_OFF_3H
@__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L


'LCD
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 2


'I2C
CMCON = 7
ADCON1 = 7
SCL VAR PORTA.2
SDA VAR PORTA.3
i2c_read CON 1 'R/W configuration bit (1 = read)
i2c_write CON 0 'R/W configuration bit (0 = write)
i2c_out VAR BYTE 'data to sent over I2C bus
i2c_in VAR BYTE[2] 'data received over I2C bus
i2c_ack VAR BIT 'acknowledgement bit
temp VAR WORD


GOSUB Config_Register 'Set Configuration
GOSUB Start_Convert 'Start continuous conversion


TOP:
PAUSE 2000
GOSUB Read_Temp
i2c_in[2] = i2c_in[1] >> 3
temp = (i2c_in[1]*1000)
LCDout $FE,1,#temp
GOTO TOP


Config_Register:
GOSUB I2C_START
i2c_out = %10010000
GOSUB I2C_TX
i2c_out = $AC
GOSUB I2C_TX
i2c_out = $00
GOSUB I2C_TX
GOSUB I2C_STOP
RETURN

Start_Convert:
GOSUB I2C_START
i2c_out = %10010000
GOSUB I2C_TX
i2c_out = $EE
GOSUB I2C_TX
GOSUB I2C_STOP
RETURN

Read_Temp:
GOSUB I2C_START
i2c_out = %10010000
GOSUB I2C_TX
i2c_out = $AA
GOSUB I2C_TX
GOSUB I2C_START
i2c_out = %10010001
GOSUB I2C_TX
GOSUB I2C_RX
GOSUB I2C_STOP
RETURN


I2C_START:
HIGH SDA
HIGH SCL
LOW SDA
LOW SCL
RETURN

I2C_STOP:
LOW SDA
HIGH SCL
HIGH SDA
PAUSE 1
RETURN

I2C_RX:
SHIFTIN SDA,SCL,0,[i2c_in[0]]
SHIFTOUT SDA,SCL,1,[%0\1]
SHIFTIN SDA,SCL,0,[i2c_in[1]]
SHIFTOUT SDA,SCL,1,[%1\1]
RETURN

I2C_TX:
SHIFTOUT SDA,SCL,1,[i2c_out]
SHIFTIN SDA,SCL,0,[i2c_ack\1]
RETURN

syryus
- 6th May 2012, 13:12
6473
Here you can see the circuit

mackrackit
- 6th May 2012, 13:23
You do not have
DEFINE OSC XX
in your code

What speed is the OSC source?

It is best to set up an LED and make it blink at a known rate before you jump into anything else to be sure of your setup.

syryus
- 6th May 2012, 15:59
I set the speed and it still don't work. The configuration is good because I tested it before with a more simple circuit

mackrackit
- 6th May 2012, 16:23
Sorry that I did not see this before
Try
ADCON1 = %00001111

You have AN0 - AN7 as analog.

AN0 - AN4 on the 2550

syryus
- 6th May 2012, 17:54
Thank you so much for your help Mackrackit =D, but it still don't work. I don't know why because the code is not difficult, but I can't find the mistakes

Darrel Taylor
- 6th May 2012, 18:38
I got a good laugh out of this one.
When the code doesn't work, rewrite PBP's I2C commands ... :onthego:

Try this ...

DEFINE OSC 48
CLEAR

#config
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
__CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_ON_2L & _BORV_3_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _CCP2MX_ON_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_OFF_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L
#endconfig

;----[LCD definitions]--------------------------------------------------------
DEFINE LCD_DREG PORTB ; LCD Data port
DEFINE LCD_DBIT 4 ; starting Data bit (0 or 4)
DEFINE LCD_EREG PORTB ; LCD Enable port
DEFINE LCD_EBIT 2 ; Enable bit
DEFINE LCD_RSREG PORTB ; LCD Register Select port
DEFINE LCD_RSBIT 1 ; Register Select bit
DEFINE LCD_BITS 4 ; LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 2 ; number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ; Command delay time in us
DEFINE LCD_DATAUS 50 ; Data delay time in us

SCL VAR PORTA.2 ; I2C Clock
SDA VAR PORTA.3 ; I2C Data

TempHigh CON 28 ; DS1621 High Temp Limit
TempLow CON 24 ; DS1621 Low Temp Limit
DS1621 CON $90 ; DS1621 Slave Address
ConfigReg VAR BYTE
TempC VAR WORD

;----[Initialization]-----------------------------------------------------------
CMCON = 7
ADCON1 = 15

I2CREAD SDA,SCL,DS1621,$AC,[ConfigReg] ; Read the configuration
IF ConfigReg.0 = 1 THEN ; if in Polling Mode?
I2CWRITE SDA,SCL,DS1621,$AC,[0] ; Set it to Continuous Mode
GOSUB WaitForEE
ENDIF

I2CREAD SDA,SCL,DS1621,$A1,[TempC.LowByte] ; Read the High Temp Limit
IF TempC != TempHigh THEN ; if High limit is incorrect
I2CWRITE SDA,SCL,DS1621,$A1,[TempHigh] ; Write High Limit
GOSUB WaitForEE
ENDIF

I2CREAD SDA,SCL,DS1621,$A2,[TempC.LowByte] ; Read the Low Temp Limit
IF TempC != TempLow THEN ; if Low limit is incorrect
I2CWRITE SDA,SCL,DS1621,$A2,[TempLow] ; Write Low Limit
GOSUB WaitForEE
ENDIF

I2CWRITE SDA,SCL,DS1621,$EE,[0] ; Start Conversions

;----[Main Program Loop]--------------------------------------------------------
Main:
PAUSE 900
I2CREAD SDA,SCL,DS1621,$AC,[ConfigReg] ; Read the configuration
LCDOUT $FE,$80,"CONFIG=",IBIN8 ConfigReg
; Read the Temperature
I2CREAD SDA,SCL,DS1621,$AA,[TempC.HighByte, TempC.LowByte]
LCDOUT $FE,$C0," Temp="
GOSUB ShowTemp

I2CREAD SDA,SCL,DS1621,$A1,[TempC.HighByte, TempC.LowByte]
LCDOUT $FE,$94," TH="
GOSUB ShowTemp

I2CREAD SDA,SCL,DS1621,$A2,[TempC.HighByte, TempC.LowByte]
LCDOUT $FE,$D4," TL="
GOSUB ShowTemp

GOTO Main

;----[Show Temp on LCD]----------------------------------------------------------
ShowTemp:
LCDOUT DEC TempC.HighByte
IF TempC.7 THEN
LCDOUT ".5 "
ELSE
LCDOUT ".0 "
ENDIF
RETURN

;----[Wait for DS1621 EEPROM Write]----------------------------------------------
WaitForEE:
REPEAT ; Wait for EEPROM write
I2CREAD SDA,SCL,DS1621,$AC,[ConfigReg]
LCDOUT $FE,$80,"CONFIG=",IBIN8 ConfigReg
UNTIL ConfigReg.4 = 0
RETURN

http://support.melabs.com/DT/DS1621.jpg

mackrackit
- 7th May 2012, 09:26
I got a good laugh out of this one.
When the code doesn't work, rewrite PBP's I2C commands ... :onthego:

I do not think he was trying to rewrite the command, he was just trying to make his project work.
As he said, he tried something found on the internet. Might have been this.
http://www.rentron.com/PicBasic/i2c_communication.htm

syryus
- 9th May 2012, 13:52
Thank you so much for your help!. As I said I have a really short experience programming so I have a lot of mistakes...