Estoy intentando desarrollar un controlador I2C para MSP432. A partir de ahora, estoy conectando un acelerómetro a través del módulo USCI B2_ en MSP432.
El problema al que me enfrento es que obtengo un NACK en el registro IFG cuando genero una condición de inicio.
- ¿Cuál podría ser el problema potencial en el código?
A continuación se adjunta el código. Indique cualquier error que haya cometido al desarrollar la función i2c_write_byte .
También:
- ¿Necesito tener resistencias adicionales en las líneas SDA y SCL?
No he agregado resistencias de pull-up externas adicionales ya que mi sensor ya tiene las resistencias de pull-up incluidas.
/**
* @file i2c.c
* @brief This file is to be used for the setting the I2C peripheral of the microcontroller.
* @author Vikrant Waje
* @date November 18, 2018
*
*/
//***********************************************************************************
// Include files
//***********************************************************************************
#include"main.h"
//***********************************************************************************
// Global variables
//***********************************************************************************
//***********************************************************************************
// Function implementation
//***********************************************************************************
/*------------------------------------------------------------------------------------------------------------------------------------*/
/*
@brief: Setup the I2C peripheral.
@param: None
@param:None
@return: None
*/
/*-----------------------------------------------------------------------------------------------------------------------------*/
void i2c_setup(){
i2c_gpio_setup();
i2c_set_parameters();
i2c_enable();
}
/*------------------------------------------------------------------------------------------------------------------------------------*/
/*
@brief: Assign GPIO to I2C peripherals.
SCL = P3.7 (UCSI B)(SEL1 =0 , SEL0 = 1 )
SDA = P3.6 (UCSI B)(SEL1 =0 , SEL1 = 1)
@param: None
@param:None
@return: None
*/
/*-----------------------------------------------------------------------------------------------------------------------------*/
void i2c_gpio_setup(){
// SCL->SEL1 |=BIT0;
P3->SEL0 |= (BIT6 | BIT7); //P3_SEL0.7 = 1 and P3_SEL0.6 = 1
}
/*------------------------------------------------------------------------------------------------------------------------------------*/
/*
@brief: Set the parameters for I2C peripherals.
@param: None
@param:None
@return: None
*/
/*-----------------------------------------------------------------------------------------------------------------------------*/
void i2c_set_parameters(){
/* I2C_Init_Typedef * i2c_struct = malloc(sizeof(I2C_Init_Typedef));
i2c_struct->enable = enable_false; // Enable Software reset
i2c_struct->mode = I2C; //Enable I2C mode
i2c_struct->master = master_mode; // Enable master mode
i2c_struct->sync_mode =sync_mode_enable; //Enable sync mode
i2c_struct->clock_source = smclk; //Use SMCLK as clock source
// i2c_struct->acknowledge = sw_ack_enable; //Software acknowledgement enabled
i2c_struct->bit_rate =8;*/
i2c_init();
}
/*------------------------------------------------------------------------------------------------------------------------------------*/
/*
@brief: Initialise I2c using the parameters set in the structure.
@param: i2c_struct: Pointer to initialisation structure
@param:None
@return: None
*/
/*-----------------------------------------------------------------------------------------------------------------------------*/
void i2c_init(/*I2C_Init_Typedef * i2c_struct*/){
EUSCI_B2->CTLW0 |=EUSCI_B_CTLW0_SWRST|EUSCI_B_CTLW0_MODE_3|EUSCI_B_CTLW0_MST|EUSCI_B_CTLW0_SYNC|EUSCI_B_CTLW0_SSEL__SMCLK;
EUSCI_B2->BRW = 0x0008;
/* EUSCI_B2->CTLW0 |= (i2c_struct->enable | i2c_struct->mode| i2c_struct->master | i2c_struct->sync_mode | i2c_struct->clock_source );
// EUSCI_B2->CTLW1 |= (i2c_struct->acknowledge);
EUSCI_B2->BRW = i2c_struct->bit_rate;*/
}
/*------------------------------------------------------------------------------------------------------------------------------------*/
/*
@brief: Enable i2c communication.
@param: None
@param:None
@return: None
*/
/*-----------------------------------------------------------------------------------------------------------------------------*/
void i2c_enable(){
EUSCI_B2->CTLW0 &= ~(EUSCI_B_CTLW0_SWRST); //Enable i2c communication
}
/*------------------------------------------------------------------------------------------------------------------------------------*/
/*
@brief: Write byte for I2C.
@param: data_byte: Data that is to be written
@param:None
@return: None
*/
/*-----------------------------------------------------------------------------------------------------------------------------*/
void i2c_write_byte(uint8_t slave_addr,uint8_t reg_addr,uint8_t data_byte){
while(EUSCI_B2->STATW & EUSCI_B_STATW_BBUSY);
EUSCI_B2->I2CSA = (slave_addr << 1); //Set slave address with write bit (LSB = 0)
EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_TR ; //Set as transmitter
EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_TXSTT ; // Send start condition
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG0) ); //Wait until start condition is transmitted
// EUSCI_B2->IFG &= ~(EUSCI_B_IFG_TXIFG0); //Clear the flag
EUSCI_B2->TXBUF = reg_addr; //Send the register address
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG0) ); //Wait until the data in TXBUF(register address) is transmitted
// EUSCI_B2->IFG &= ~(EUSCI_B_IFG_TXIFG0); //Clear the flag
EUSCI_B2->TXBUF = data_byte; //Send the data byte
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG0) ); //Wait until the data in TXBUF(register address) is transmitted
// EUSCI_B2->IFG &= ~(EUSCI_B_IFG_TXIFG0); //Clear the flag
EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_TXSTP; // Generate a stop condition
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG0) ); //Wait until the data in TXBUF(register address) is transmitted
EUSCI_B2->IFG &= ~(EUSCI_B_IFG_TXIFG0); //Clear the flag
}
/*------------------------------------------------------------------------------------------------------------------------------------*/
/*
@brief: Read byte for I2C.
@param: None
@param:None
@return: data_byte:Data that is read
*/
/*-----------------------------------------------------------------------------------------------------------------------------*/
uint8_t i2c_read_byte(uint8_t slave_addr,uint8_t reg_addr){
EUSCI_B2->I2CSA = (slave_addr << 1); //Set slave address with write bit (LSB = 0)
EUSCI_B2->CTLW0 &= ~(EUSCI_B_CTLW0_TR) ; //Set as Receiver
EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_TXSTT ; // Send start condition
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG0) ); //Wait until start condition is transmitted
EUSCI_B2->IFG &= ~(EUSCI_B_IFG_TXIFG0); //Clear the flag
while((EUSCI_B2->CTLW0 & EUSCI_B_CTLW0_TXSTT) ); //Wait for complete slave address to get transmitted
EUSCI_B2->TXBUF = reg_addr; //Send the register address
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG0) ); //Wait until the data in TXBUF(register address) is transmitted
EUSCI_B2->IFG &= ~(EUSCI_B_IFG_TXIFG0); //Clear the flag
EUSCI_B2->I2CSA = (slave_addr << 1) | (0x01); //Set slave address with write bit (LSB = 0)
EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_TXSTT ; // Send start condition
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG0) ); //Wait until start condition is transmitted
EUSCI_B2->IFG &= ~(EUSCI_B_IFG_TXIFG0); //Clear the flag
while((EUSCI_B2->CTLW0 & EUSCI_B_CTLW0_TXSTT) ); //Wait for complete slave address to get transmitted
while(!(EUSCI_B2->IFG & EUSCI_B_IFG_RXIFG) ); //Wait until start condition is transmitted
EUSCI_B2->IFG &= ~(EUSCI_B_IFG_RXIFG); //Clear the flag
EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_TXNACK; //Transmit a NACK
EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_TXSTP; // Generate a stop condition
return EUSCI_B2->RXBUF;
}