Autor Tema: PIC16F877, comunicacion I2C y sensor TC74  (Leído 2808 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Pigwedeon

  • PIC10
  • *
  • Mensajes: 5
PIC16F877, comunicacion I2C y sensor TC74
« en: 30 de Marzo de 2011, 15:44:10 »
Hola a todos, estoy trabajando en un proyecto y ando algo atascado en un punto, a ver si pueden echarme una mano!

Estoy trabajando con el compilador High Tech C (MPLAB) y Proteus.

El Pic (16F877A) tiene un reloj externo de 20MHZ, el sensor TC74 de temperatura I2C está conectado al PIC por el respectivo puerto RC3/SCK/SCL y RC4/SDI/SDA. Los datos deben salir por el puerto serie (RC6 clock y RC7 datos).

Éste es mi código:
Código: [Seleccionar]
#include <pic.h>
#include "i2c.h"
 
__CONFIG (WDTDIS & HS & LVPDIS); 


void main()
{
  INTCON= 0;     //Disable Interrupts
  SPBRG = 129;  //Set the baudrate for 9600 @ 20 MHz
  TXSTA = 0x24; //Set the serial port parameters (8b transm;Asincr.Mode;HighSpeed)
  RCSTA = 0x90; //Set the serial port parameters (Enable Rx and Tx and enable recieves)
  PORTC = 0;    //Clear PORTC pins
  TRISC = 0x80; //Set the PORTC pin directions i.e Tx and Rx
       
 
 int a; //Variables holds I2C Data 

while(1)         
  {
  i2c_Start();               
  i2c_SendByte(0x9B);      //Envía la dirección del sensor
  i2c_ReadAcknowledge();     
  __delay_us(2);
                       
                        a=i2c_ReadByte();         
    i2c_SendAcknowledge(1);             
  __delay_us(2);

(He omitido el codigo de envio de los datos al serial)

El programa recorre correctamente todo el código, pero sólo lee como datos FF o 00, según si la dirección que envía es 9A o 9B, respectivamente. ¿Alguno sabe que pasa? El sensor está programado con la dirección por defecto que indica el datasheet y con las resistencias de desacoplo.

¿Puede ser que haya que modificar algo del archivo de cabecera que facilita Phillips para la gestión de la comunicación I2C? Yo en ese archivo he modificado el reloj, como se indica. Según me han comentado tengo que configurar los registros SPCON, SPCON2, etc... del PIC, ¿pero no se supone que ya lo hace el archivo de cabecera? (#ifdef I2C_MODULE). Si lo tengo que modificar yo, ¿qué parametros hay que ajustar?

Indicar que el PIC es master ;)

Código: [Seleccionar]
#ifndef _I2C_H_
#define _I2C_H_

/*
 * SDA (data) and SCL (clock) bits
 *
 * Special note!!!
 *
 * If the clock and data lines are in the same port, you will need
 * to beware of the Read/Modify/Write issue in the PIC - since
 * a bit set or clear on any one bit in a port will read and write
 * back all other bits.
 */

#ifndef _XTAL_FREQ
 // Unless specified elsewhere, 4MHz system frequency is assumed
 #define _XTAL_FREQ 20000000
#endif

/* Uncomment the next line to use the PIC's SSP Module*/
//#define I2C_MODULE 1

#ifdef I2C_MODULE
/* I2C module uses PORT C */
#define SCL             RC3             /* clock on port C bit 2 */
#define SCL_DIR         TRISC3
#define SDA     RC4                     /* data on port C bit 1 */
#define SDA_DIR         TRISC4
#define I2CTRIS TRISC
#define MASTER_MODE     0B1011          /* I2C firmware controlled Master Mode (slave idle) */
#define SSPMode(val)   SSPCON &=0xF0; SSPCON|=(val & 0xf)

#else
/* Change port as required - defaults to port b */
#define SCL RB2 /* clock on port B bit 2 */
#define SCL_DIR TRISB2

#define SDA             RB1             /* data on port B bit 1 */
#define SDA_DIR TRISB1
#define I2CTRIS TRISB

#endif

#define M_SDA_INP 0x02
#define M_SDA_OUT   0xFD
#define M_SCL_INP   0x04
#define M_SCL_OUT 0xFB

#define I2C_INPUT 1 /* data direction input */
#define I2C_OUTPUT 0 /* data direction output */

#define I2C_READ 0x01 /* read bit used with address */
#define I2C_WRITE 0x00 /* write bit used with address */

#define FALSE 0
#define TRUE !FALSE

#define I2C_ERROR (-1)
#define I2C_LAST FALSE /* SendAck: no more bytes to send */
#define I2C_MORE TRUE /* SendAck: more bytes to send */

#define i2c_Start() i2c_Restart()
#define i2c_WriteTo(address) i2c_Open((address), I2C_WRITE)
#define i2c_ReadFrom(address) i2c_Open((address), I2C_READ)

#ifdef I2C_MODULE
#define SCL_HIGH() SCL_DIR = I2C_INPUT
#define SCL_LOW()  SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA_DIR = I2C_INPUT
#define SDA_LOW()  SDA_DIR = I2C_OUTPUT
#else
#define SCL_HIGH() SCL = 1; SCL_DIR = I2C_OUTPUT
#define SCL_LOW()  SCL = 0; SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA = 1; SDA_DIR = I2C_OUTPUT
#define SDA_LOW()  SDA = 0; SDA_DIR = I2C_OUTPUT
#endif

/*
 * Timings for the i2c bus. Times are rounded up to the nearest
 * micro second.
 */

#define I2C_TM_BUS_FREE 5
#define I2C_TM_START_SU 5
#define I2C_TM_START_HD 4
#define I2C_TM_SCL_LOW 5
#define I2C_TM_SCL_HIGH 4
#define I2C_TM_DATA_SU 1
#define I2C_TM_DATA_HD          0
#define I2C_TM_SCL_TO_DATA 4 /* SCL low to data valid */
#define I2C_TM_STOP_SU 4
#define I2C_TM_SCL_TMO 10 /* clock time out */

extern signed char i2c_ReadAcknowledge(void);
extern unsigned char i2c_SendAddress(unsigned char, unsigned char);
extern unsigned char i2c_SendByte(unsigned char);
extern int i2c_ReadByte(void);
extern void i2c_Restart(void);
extern void i2c_Stop(void);
extern void i2c_SendAcknowledge(unsigned char);
extern signed char i2c_PutByte(unsigned char);
extern int i2c_GetByte(unsigned char);
extern unsigned char i2c_Open(unsigned char, unsigned char);
extern unsigned char i2c_GetString(unsigned char *, unsigned char);
extern int i2c_PutString(const unsigned char *, unsigned char);
extern unsigned char i2c_WaitForSCL(void);
extern void i2c_Free(void);
extern unsigned char i2c_read(unsigned char);
#endif /* _I2C_H_ */

Muchas gracias por vuestros comentarios ;)


 

anything