[求助] msp430f5529 硬件i2c restart使用问题

小枫枫   2018-9-25 13:56 楼主
第一次在eeworld发帖求助,请前辈指教!提问题排版有什么问题我会改的!!
背景:
用MSP430f5529和时钟模块DS1307进行硬件i2c通讯。用Ti自带的例程“Master multiple bytes to Slave”进行修改(增加了时钟初始化USC_init、读模式read_mode,写模式write_mode)。
程序的流程大概是:初始化时钟、i2c,写第一组数据0x03和0x05并结束,写第二组数据0x04和0x06并restart再写0x04和0x06,结束。
目的是为了弄清楚restart的使用。

先放逻辑分析仪时序:
[size=0.83em]

问题:
1. 在写第一组数据(0x03,0x05)时序正确的前提下,写第二组数据(0x04,0x06)后进行restart,能看到restart条件产生(第三个绿点),也传输了slave address和读写位(restart条件后的0xD0),但是后续的scl和sda就没有变化了,请问这是哪里出了问题?

[size=0.83em]
2. (可能与问题1相关)进行单步调试,在运行到
  • UCB0CTL1 |= UCTXSTT;                                                //restart,全代码第 53 行


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

这一步的时候,按照user's guide中的说法,将UCTXSTT置位后,如果从机对起始信号有响应,将会把UCB0TXIFG置位。但是调试时没有置位,导致没有进入中断,请问哪里可能出现了问题?
[size=0.83em]
3. 如代码
  • UCB0CTL1 |=  UCTXSTT;
  •             __bis_SR_register(LPM0_bits);                                //LPM0
  •             __no_operation();

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

中,产生起始条件后总要直接进入低功耗模式。再如Tx中断里,代码
  • 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]复制代码

中,产生终止条件后总要退出中断时退出低功耗模式。请问这是如何对通讯产生影响的,应当在何时进入或退出低功耗模式。

下面附全代码:
  • #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]复制代码



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




回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复