I really appreciate your help.
And I have one question about register UCB0I2CSA.
If I attend to receive data from my slave sensor, the operation protocol is like
this.
MASTER : ST SAD+W SUB SR SAD+R MAK....
SLAVE : SAK SAK SAK DATA .......
I think master should send SAD+W, SUB and SAD+R before slave send DATA. But I
don't know the function of UCB0I2CSA.
If I assign slave's address SAD+W to UCB0I2CSA, sending SAD+W to
slave(UCB0TXBUF = SAD+W) is not needed? Should I just use UCTXSTT and send SUB,
SAD+R?
Render it down, I wonder to know when I to do something through I2C, UCB0I2CSA
is sent automatically to slave??
Thank you.
--- In m..., "gymb321" wrote:
>
> #include unsigned int RxByteCtr;
> unsigned int RxWord;
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> P1DIR |= 0x01; // P1.0 output
> P3SEL |= 0x06; // 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 = 12; // fSCL = SMCLK/12 = ~100kHz
> UCB0BR1 = 0;
> UCB0I2CSA = 0x21; // Set slave address
> UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume
> operation
> IE2 |= UCB0RXIE; // Enable RX interrupt
> TACTL = TASSEL_2 + MC_2; // SMCLK, contmode
>
> while (1)
> {
> RxByteCtr = 2; // Load RX byte counter
> UCB0CTL1 |= UCTXSTT; // I2C start condition
> __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable
> interrupts
> // Remain in LPM0 until all
> data
> // is RX'd
> if (RxWord > 200)
> P1OUT |= 0x01;
> else
> P1OUT &= ~0x01;
>
> __disable_interrupt();
> TACCTL0 |= CCIE; // TACCR0 interrupt enabled
> __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable
> interrupts
> // Remain in LPM0 until
> TACCR0
> // interrupt occurs
> TACCTL0 &= ~CCIE; // TACCR0 interrupt disabled
> }
> }
>
> #pragma vector = TIMERA0_VECTOR
> __interrupt void TA0_ISR(void)
> {
> __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
> }
>
> // The USCIAB0TX_ISR is structured such that it can be used to receive
> any
> // 2+ number of bytes by pre-loading RxByteCtr with the byte count.
> #pragma vector = USCIAB0TX_VECTOR
> __interrupt void USCIAB0TX_ISR(void)
> {
> RxByteCtr--; // Decrement RX byte counter
>
> if (RxByteCtr)
> {
> RxWord = (unsigned int)UCB0RXBUF << 8; // Get received byte
> if (RxByteCtr == 1) // Only one byte left?
> UCB0CTL1 |= UCTXSTP; // Generate I2C stop
> condition
> }
> else
> {
> RxWord |= UCB0RXBUF; // Get final received byte,
> // Combine MSB and LSB
> __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
> }
> }
> Essentially, you send a command to your slave device using an address
> and then wait for the response from the slave device. In order to do
> this, you must setup timers, control registers, the I2c protocol, etc as
> done in the the main loop. This is setup in Master sync mode so that
> one device (the master) can control many other devices (slaves). The
> slave address used in this example is UCB0I2CSA = 0x21. So once
> everything is setup, it's time to actually use the I2c protocol.
> UCB0CTL1 |= UCTXSTT; will start the i2c by calling the slave address
> stored in UCB0I2CSA. Now it's up to the slave to recognize that it is
> being called and send the appropriate response. The accelerometer will
> layout what needs to be sent to it to whatever data you need (x, y, or z
> axis measurements) . This program will remain in lpm until data is
> received. Once everything is received, then a stop condition is set.
>
> To really understand how to use your micro, checkout the TI datasheet.
> It will go through each thing in detail and tell you exactly what
> registers to set. It really is the only way to learn this stuff.
>
> --- In m..., "Songsongsong" wrote:
> >
> > Hi group,
> >
> > I have to receive data from slave sensor(LSM303DLM:Accelerometer) by
> I2C. However I don't know well how I make code of trasmit & receive.
> >
> > Here is my code of I2C register setting. But I don't know how to
> approach next of this code. I just want to transmit slave address,
> register address and data. And then receive data from slave sensor
> continuously. There are many example codes in online, but I cannot
> understand them... Please let me know example codes or some diretions..
> Thank you.
> >
> >
> > void SetI2C (void)
> > {
> > UCB0CTL1 |= UCSWRST; // **Put state machine in reset**
> > UCB0CTL0 |= UCMST | UCSYNC | UCMODE_3;
> > // Master mode, 7 bit address,I2C mode
> >
> > UCB0CTL1 |= UCSSEL_2; // SMCLK
> > UCB0BR0 = 0x04; // /4 --- 2.304 MHz
> > UCB0BR1 = 0;
> > UCB0I2CSA = ACC_ADDRESS_W;
> > UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
> > UCB0IE = UCNACKIE;
> > }
>