Hello! I'm trying to use the MSP430F2274 ( EZ430-rf2500 ) I2c module (USCI B0) in a way that it doesn't need to use interrupts. My goal is to be able to read the registers of the accelerometer MPU-6050. What I need to do is exactly this: [Start Condition] - [Slave Address + W] -[Slave Ack] - [Bytes to be read] -[Many Acks...] - [Start Condition] - [Slave address + R] - [Ack] - [Slave send many bytes] - [Master Acks] - [slave NACK] - [STOP] However, in this code, I think I misconfigured something in USCI B0, because I can do start conditions in I2c, but I cannot see in my oscilloscope any SLAVE ADDRESS being transmitted after it!! Could you help me figure out what's happening? #include "msp430.h" #define SLAVE_ADDR 0x68 #define ACCX_ADDR 0x3B //Read 2 bytes. #define ACCY_ADDR 0x3D //Read 2 bytes. #define ACCZ_ADDR 0x3F //Read 2 Bytes. #define PRESCALER 0x03 //i2c speed must be max 400 khz // Since we are using 1Mhz, we need 333 khz. #define TERMINATION_STOP 0 //Tipos de terminadores para o i2c - stop condition #define TERMINATION_START 1 //Tipos de terminadores para o i2c - start condition #define __INTERRUPT_MODE typedef enum m_mode{ I2C_TRANSMITTER = 0, I2C_RECEIVER = 1 }Master_Mode; typedef enum m_condition{ I2C_START = 0, I2C_STOP = 1 }Master_Condition; void beVim_i2c_configure(unsigned char slave_address, unsigned char prescale){ P3SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0 UCB0CTL1 = UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = prescale; // set prescaler UCB0BR1 = 0; UCB0I2CSA = slave_address; // Set slave address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0I2CIE = UCNACKIE; #ifdef __INTERRUPT_MODE IE2 = UCB0TXIE + UCB0RXIE; // Enable TX ready interrupt #endif } void beVim_i2c_transmit_condition(Master_Mode mode, Master_Condition condition){ switch(mode){ case I2C_RECEIVER: UCB0CTL1 &= ~(UCTR); break; case I2C_TRANSMITTER: UCB0CTL1 |= UCTR; break; } switch(condition){ case I2C_STOP: UCB0CTL1 |= UCTXSTP; break; case I2C_START: UCB0CTL1 |= UCTXSTT; break; } } void beVim_i2c_write_bytes(unsigned char qty, unsigned char *c){ unsigned char bytesToSend = qty; //START + WRITE beVim_i2c_transmit_condition(I2C_TRANSMITTER, I2C_START); //A partir daqui, a máquina de estados escreveu //o endereço i2c e a flag WRITE no barramento. //Aguardamos o recebimento do primeiro ACK. while(!(IFG2 & UCB0RXIFG)); //Transmitimos os qty bytes até que acabe todo o buffer. while(bytesToSend){ UCB0TXBUF = *c; //Aguarda o recebimento de um ACK para prosseguir. while(!(IFG2 & UCB0RXIFG) ); if(UCNACKIFG) break; bytesToSend--; } } void beVim_i2c_read_bytes(unsigned char qty, unsigned char *c){ unsigned char bytesToRead = qty; unsigned char readBytes; //START + READ beVim_i2c_transmit_condition(I2C_RECEIVER, I2C_START); //Aguardamos o recebimento do primeiro ACK. while(!UCB0RXIFG); while(bytesToRead){ //Aguarda receber mensagem completa. while(!(IFG2 & UCB0RXIFG) || UCNACKIFG); *c = UCB0RXBUF; if(UCNACKIFG) break; c++; bytesToRead --; } } int main(void){ int i = 0; unsigned char c[2] = {ACCX_ADDR, ACCX_ADDR +1}; unsigned char result[2] = {0,0}; WDTCTL = WDTHOLD+WDTPW; //LEDs para indicar os status do programa. setDirection(1,0,output); setOutput(1,0,high); setDirection(1,1,output); setOutput(1,1,high); P3DIR |= 0x0F; //Portas de comunicação. setDirection(3,1,output); setDirection(3,2,output); P3SEL |= 0x06; //Inicializa o clock para MCLK e SMCLK e DCO beVim_Clock_Config(DCOCLK, _1MHZ); beVim_Mclk_Source(DCOCLK, 1); beVim_SMclk_Source(DCOCLK,1); //for (i =0; i<0x600; i++); //for (i =0; i<0x600; i++); setOutput(1,1,low); setOutput(1,0,low); __bis_SR_register(GIE); // Enable_int beVim_i2c_configure(SLAVE_ADDR, PRESCALER); while(1){ beVim_i2c_write_bytes(2, &c); beVim_i2c_read_bytes(2, &result); beVim_i2c_transmit_condition(I2C_RECEIVER, I2C_STOP); } } void __interrupt(USCIAB0RX_VECTOR) rx_ISR(void) { // IFG2 &= ~UCB0RXIFG; toggleOutput(1,1); } void __interrupt(USCIAB0TX_VECTOR) tx_ISR(void) { // IFG2 &= UCB0TXIFG ; toggleOutput(1,0); }
↧