2967 views|0 replies

1

Posts

0

Resources
The OP
 

msp430f5529 hardware i2c restart usage problem [Copy link]

This is my first time posting for help on eeworld. Please give me some advice! I will correct any problems with the formatting of the question! ! Background: Use MSP430f5529 and clock module DS1307 for hardware i2c communication. Use the routine "Master multiple bytes to Slave" that comes with Ti to modify (add clock initialization USC_init, read mode read_mode, write mode write_mode). The program flow is roughly: initialize the clock, i2c, write the first set of data 0x03 and 0x05 and end, write the second set of data 0x04 and 0x06 and restart, then write 0x04 and 0x06, and end. The purpose is to clarify the use of restart. First put the logic analyzer timing: [size=0.83em] Question: 1. Under the premise that the timing of writing the first set of data (0x03, 0x05) is correct, after restarting after writing the second set of data (0x04, 0x06), we can see that the restart condition is generated (the third green dot), and the slave address and read-write bit (0xD0 after the restart condition) are also transmitted, but the subsequent SCL and SDA do not change. What went wrong? 2. (May be related to question 1) Perform single-step debugging. When running to the step
  • UCB0CTL1 |= UCTXSTT; //restart, full code line 53
[color=rgb(51, 102, 153) !important]Copy code
, according to the user's guide, after UCTXSTT is set, if the slave responds to the start signal, UCB0TXIFG will be set. However, it is not set during debugging, resulting in no interrupt. Where might the problem be? 3. As shown in the code
  • UCB0CTL1 |= UCTXSTT;
  • __bis_SR_register(LPM0_bits); //LPM0
  • __no_operation();
[color=rgb(51, 102, 153) !important]Copy code
, it is always necessary to enter low power mode directly after the start condition is generated. For example, in the Tx interrupt, the code
  • UCB0CTL1 |= UCTXSTP; // I2C stop condition
  • UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
  • __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
[color=rgb(51, 102, 153) !important]Copy code
always exits the low power mode when the interrupt is exited after the termination condition is generated. How does this affect communication? When should we enter or exit the low power mode? The full code is attached below:
  • #include


  • #define SMCLK_FREQ 24000000
  • #define I2C_FREQ 100000
  • void USC_init(void);                                     //clock initialize
  • void initi2c(void);                                      //i2c initialize
  • void read_mode(void);                                    //read mode setting
  • void write_mode(void);                                   //write mode setting
  • unsigned char *PTxData;                                  // pointer to TX data
  • unsigned char TXByteCtr;                                 //number of data to transmit
  • unsigned char TxData[] =                                 // table of data to transmit
  • {
  •   0x03,
  •   0x05
  • };
  • int flag;                                                //restart flag
  • int main(void)
  • {
  •           unsigned int i;

  •             WDTCTL = WDTPW + WDTHOLD;                    // Stop WDT
  •             USC_init();
  •             initi2c();
  •             write_mode();                                //write
  •             PTxData = (unsigned char *)TxData;
  •             TXByteCtr = sizeof TxData;
  •             flag = 0;                                    //no restart
  •             UCB0CTL1 |=  UCTXSTT;
  •             __bis_SR_register(LPM0_bits);                //LPM0
  •             __no_operation();
  •             while (UCB0CTL1 & UCTXSTP);


  •             for(i=0;i<10;i++);                           // Delay required between transaction


  •             TxData[0]++;                                 //change the TxData
  •             TxData[1]++;
  •             write_mode();
  •             PTxData = (unsigned char *)TxData;
  •             TXByteCtr = sizeof TxData;
  •             flag = 1;                                    //restart required
  •             UCB0CTL1 |= UCTXSTT;
  •             __bis_SR_register(LPM0_bits);                //LPM0
  •             __no_operation();

  •             write_mode();                                //transmit data again
  •             PTxData = (unsigned char *)TxData;
  •             TXByteCtr = sizeof TxData;
  •             flag = 0;
  •             UCB0CTL1 |= UCTXSTT;                          //restart

  •             __bis_SR_register(LPM0_bits);                 //LPM0
  •             __no_operation();

  •                       while (UCB0CTL1 & UCTXSTP);
  •                       while(1);                           //finish
  • }

  • #pragma vector = USCI_B0_VECTOR
  • __interrupt void USCI_B0_ISR(void)
  • {
  •   switch(__even_in_range(UCB0IV,12))
  •   {
  •   case  0: break;                           // Vector  0: No interrupts
  •   case  2: break;                           // Vector  2: ALIFG
  •   case  4: break;                           // Vector  4: NACKIFG
  •   case  6: break;                           // Vector  6: STTIFG
  •   case  8: break;                           // Vector  8: STPIFG
  •   case 10: break;                           // Vector 10: RXIFG
  •   case 12:                                  // Vector 12: TXIFG
  •     if (TXByteCtr)                          // Check TX byte counter
  •     {
  •       UCB0TXBUF = *PTxData++;               // Load TX buffer
  •       TXByteCtr--;                          // Decrement TX byte counter
  •     }
  •     else
  •     {
  •             if (!flag)
  •       {
  •                     UCB0CTL1 |= UCTXSTP;                  // I2C stop condition
  •                     UCB0IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag
  •                     __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
  •       }
  •             else
  •             {
  •                     //UCB0IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag
  •                     __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
  •             }

  •     }
  •   default: break;
  •   }
  • }


  • void USC_init()
  • {
  •         P5SEL |= BIT4+BIT5;
  •         UCSCTL6 &= ~(XT1OFF);
  •         UCSCTL6 |= XCAP_3;
  •         UCSCTL4 |= SELA_0+SELS_3;

  •         UCSCTL0 = 0x0000;
  •         do
  •         {
  •                 UCSCTL7 &= ~XT1LFOFFG;
  •         }while         (UCSCTL7 & XT1LFOFFG);

  •         __bis_SR_register(SCG0);

  •         UCSCTL1 = DCORSEL_5;
  •         UCSCTL2 = FLLD_1 + 366;

  •         __bic_SR_register(SCG0);
  •         __delay_cycles(750000);
  • }


  • void initi2c()
  • {
  •         USC_init();
  •           P3SEL |= 0x03;                                // 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 = (SMCLK_FREQ/I2C_FREQ);
  •           UCB0BR1 = ((SMCLK_FREQ/I2C_FREQ)>>8) & 0xFF;
  •           UCB0I2CSA = (0xD0 >> 1);                      // Slave Address is 048h
  •           UCB0CTL1 &= ~UCSWRST;                         // Clear SW reset, resume operation
  •           __bis_SR_register(GIE);
  • }

  • void read_mode(void)
  • {
  •         UCB0CTL1 &= ~UCTR;
  •         UCB0IE |= UCRXIE;
  •         UCB0IE &= ~UCTXIE;
  • }
  • void write_mode(void)
  • {
  •         UCB0CTL1 |= UCTR;
  •         UCB0IE &= ~UCRXIE;
  •         UCB0IE |= UCTXIE;

  • }


[color=rgb(51, 102, 153) !important]复制代码



排版不好。。。
请各位前辈指教!!




This post is from Microcontroller MCU
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list