I2C Problems

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C Problems

702 Views
Murmele
Contributor I

Hi,

I made a programm for the MC9S08AW32 to read the temperature of a LM92. I send the first byte and then i got the Acknowledge. Then I send the second byte but then i don't get the second acknowledge. Does somebody know why this doesn't work? 

Labels (1)
0 Kudos
2 Replies

359 Views
Ingo_Michael
Contributor II

Hello Murele!

 

I seen that you choosed a wrong  SCL divider during your IIC initialisation.

 

Dec 64 seems to be not allowed as SCL divider. Please take a look in the Datasheet for

MC9S08AW60, MC9S08AW48, MC9S08AW32, MC9S08AW16 Rev 2 12/2006 on page 220 and 221.

 

Calculate the IIC Baudrate as follows

IIC baud rate = bus speed (Hz) / (mul x SCL divider)

 

Good Luck!

0 Kudos

359 Views
bigmac
Specialist III

Hello,

 

The baud rate divisor setting of 0xBF will set the divisor to 4*3840 = 15360.  Since the minimum allowable clock rate for the LM92 is 1kHz, this setting is potentially problematic for a MCU bus frequency below 15.36 MHz.

 

I am not sure of the position in the sequence where you perceive that there is a problem.  The IIC sequence to read a 16-bit register value should be as follows -

  1. Set master transmit mode & generate START
  2. Send LM92 address, write mode - error exit if no ACK from slave
  3. Send register pointer value ( zero for temperature register) - error exit if no ACK from slave
  4. Generate repeat START
  5. Send LM92 address, read mode - error exit if no ACK from slave
  6. Set master receive mode, with ACK returned to slave after next transfer
  7. Discard garbage read value - start read transfer for MS data byte
  8. Set master receive mode, with no ACK returned to slave after next transfer
  9. Read MS byte of returned data and store - start read transfer for LS data byte
  10. Generate STOP
  11. Read LS byte of returned data and store

 

Your code is very difficult to read, but may be deficient in the above marked areas.  If an ACK error is detected, a STOP should be generated so as to release the bus.

 

The following code snippet demonstrates how to improve code readability and efficiency.  The original code, shown first, requires 18 bytes of code.  This occurs in numerous places.

 

     lda   #ADRESS_SLAVE_WRITE
     sta   IIC1D
NoInterrupt_pending
     brset 1,IIC1S,Interrupt_pending
     jmp   NoInterrupt_pending
Interrupt_pending
     bset  1,IIC1S
NACK_4
     brclr 0,IIC1S,ACK_4
     jmp   NACK_4
ACK_4

This code could be directly replaced as follows, and would require smaller code (11 bytes).  The previously used jump instructions are unnecessary.  Maybe you were thinking of PIC branching limitations that do not apply here?  With bit manipulation and bit test operations, the individual bits should always be named, to provide readability.

 

      MOV    #ADRESS_SLAVE_WRITE,IIC1D ; Start data transfer
      BRCLR  IIC1S_IICIF,IIC1S,*       ; Wait until flag is set

      BSET   IIC1S_IICIF,IIC1S         ; Clear flag
      BRSET  IIC1S_RXAK,IIC1S,*        ; This does not provide an error exit

 

The last instruction above would then need to be altered to provide error exit -

 

      BRSET  IIC1S_RXAK,IIC1S,ERROR    ; Error exit if no ACK from slave

 

Regards,

Mac

0 Kudos