This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

430f5529关于ucb的iic模式的问题,一直无法正常使用,求助



连的设备是淘宝随便买的一个oled的屏幕

连线为UCB1的两个口

代码是照着官方例程改的,但就是跑不通,只进入过一次tx的中断,后来就卡住了,再也进不了第二个tx中断了,一直弄不懂是什么原因,用模拟iic就没问题

希望有用过5529的大神帮助一下

#include "driverlib.h"
#include "liblist.h"
#define OLED_ADDRESS  (0x78)
#define OLED_CMD  0
#define OLED_DATA 1
void fill_picture(unsigned char fill_Data);
void OLED_Init(void);
void OLED_WR_Byte(unsigned char dat,unsigned char cmd);

unsigned char iicfinish=0;
unsigned char iicdata[10];
unsigned char iiccounter=0;
unsigned int kk=0;
int main(void) {
    WDT_A_hold(WDT_A_BASE);     //关闭看门狗
    SYSCLK_hfinitclock();     //配置系统时钟
              //MCLK  24MHz SMCLK 1MHz
              //ACLK 32.768KHz
    P4SEL |= BIT1+BIT2;      //设置P4.1与P4.2为特殊功能寄存器
    P4REN |= BIT1+BIT2;
    P4OUT |= BIT1+BIT2;
   // P3SEL |= 0x03;
    UCB1CTL1 |= UCSWRST;        //允许UCB1配置被修改
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;   // I2C 主机, 同步模式
    UCB1CTL1 = UCSSEL_2 + UCSWRST;          // 选择SMCLK, 保持 SW 重置状态
    UCB1BR0 = 12;                           // fSCL = SMCLK/10 = ~100kHz
    UCB1BR1 = 0;
    UCB1I2CSA = OLED_ADDRESS;               // 从机地址,默认初始化为oled地址
    UCB1CTL1 &= ~UCSWRST;                   // 清除SW重置,完成操作
    OLED_Init();
    fill_picture(1);
    while(1)
     ;
}
void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{
    UCB1CTL1 |= UCTR;
    USCI_B_I2C_clearInterrupt(USCI_B1_BASE,USCI_B_I2C_TRANSMIT_INTERRUPT);
    UCB1IE &= ~UCRXIE;                        // Disable RX interrupt
    UCB1IE |= UCTXIE;                         // Enable TX interrupt
    while(UCB1STAT & UCBBUSY);
 kk++;
 iiccounter=2;
 if(cmd)
  iicdata[1]=0x40;
 else
  iicdata[1]=0x00;
 iicdata[0]=dat;
 UCB1CTL1 |= UCTXSTT;
 __bis_SR_register(LPM0_bits + GIE);
 while (UCB1CTL1 & UCTXSTP);
}
void OLED_Init(void)
{
    OLED_WR_Byte(0xAE,OLED_CMD);
 OLED_WR_Byte(0x00,OLED_CMD);
 OLED_WR_Byte(0x10,OLED_CMD);
 OLED_WR_Byte(0x40,OLED_CMD);
 OLED_WR_Byte(0xB0,OLED_CMD);
 OLED_WR_Byte(0x81,OLED_CMD);
 OLED_WR_Byte(0xFF,OLED_CMD);
 OLED_WR_Byte(0xA1,OLED_CMD);
 OLED_WR_Byte(0xA6,OLED_CMD);
 OLED_WR_Byte(0xA8,OLED_CMD);
 OLED_WR_Byte(0x3F,OLED_CMD);
 OLED_WR_Byte(0xC8,OLED_CMD);
 OLED_WR_Byte(0xD3,OLED_CMD);
 OLED_WR_Byte(0x00,OLED_CMD);
 OLED_WR_Byte(0xD5,OLED_CMD);
 OLED_WR_Byte(0x80,OLED_CMD);
 OLED_WR_Byte(0xD8,OLED_CMD);
 OLED_WR_Byte(0x05,OLED_CMD);
 OLED_WR_Byte(0xD9,OLED_CMD);
 OLED_WR_Byte(0xF1,OLED_CMD);
 OLED_WR_Byte(0xDA,OLED_CMD);
 OLED_WR_Byte(0x12,OLED_CMD);
 OLED_WR_Byte(0xDB,OLED_CMD);
 OLED_WR_Byte(0x30,OLED_CMD);
 OLED_WR_Byte(0x8D,OLED_CMD);
 OLED_WR_Byte(0x14,OLED_CMD);
 OLED_WR_Byte(0xAF,OLED_CMD);
}
void fill_picture(unsigned char fill_Data)
{
 unsigned char m,n;
 for(m=0;m<8;m++)
 {
  OLED_WR_Byte(0xb0+m,0);
  OLED_WR_Byte(0x00,0);
  OLED_WR_Byte(0x10,0);
  for(n=0;n<128;n++)
   {
    OLED_WR_Byte(fill_Data,1);
   }
 }
}
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
   switch(UCB1IV)
   {
   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(iiccounter)                             // Check TX byte counter
     {
      UCB1TXBUF=iicdata[iiccounter-1];
      iiccounter--;
     }
     else
     {
      iicfinish=1;
         UCB1CTL1 |= UCTXSTP;
         UCB1IFG &= ~UCTXIFG;
         __bic_SR_register_on_exit(LPM0_bits);
     }
     break;
   default: break;
   }
}
  • 建议参考下官网提供的例程

    http://dev.ti.com/tirex/#/Package/MSPWare?link=MSPWare%2FDevices%2FMSP430F5XX_6XX%2FMSP430F5529%2FPeripheral%20Examples%2FRegister%20Level

  • Jiaxin Su 说:

    连的设备是淘宝随便买的一个oled的屏幕

    连线为UCB1的两个口

    代码是照着官方例程改的,但就是跑不通,只进入过一次tx的中断,后来就卡住了,再也进不了第二个tx中断了,一直弄不懂是什么原因,用模拟iic就没问题

    希望有用过5529的大神帮助一下

    #include "driverlib.h"
    #include "liblist.h"
    #define OLED_ADDRESS  (0x78)
    #define OLED_CMD  0
    #define OLED_DATA 1
    void fill_picture(unsigned char fill_Data);
    void OLED_Init(void);
    void OLED_WR_Byte(unsigned char dat,unsigned char cmd);

    unsigned char iicfinish=0;
    unsigned char iicdata[10];
    unsigned char iiccounter=0;
    unsigned int kk=0;
    int main(void) {
        WDT_A_hold(WDT_A_BASE);     //关闭看门狗
        SYSCLK_hfinitclock();     //配置系统时钟
                  //MCLK  24MHz SMCLK 1MHz
                  //ACLK 32.768KHz
        P4SEL |= BIT1+BIT2;      //设置P4.1与P4.2为特殊功能寄存器
        P4REN |= BIT1+BIT2;
        P4OUT |= BIT1+BIT2;
       // P3SEL |= 0x03;
        UCB1CTL1 |= UCSWRST;        //允许UCB1配置被修改
        UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;   // I2C 主机, 同步模式
        UCB1CTL1 = UCSSEL_2 + UCSWRST;          // 选择SMCLK, 保持 SW 重置状态
        UCB1BR0 = 12;                           // fSCL = SMCLK/10 = ~100kHz
        UCB1BR1 = 0;
        UCB1I2CSA = OLED_ADDRESS;               // 从机地址,默认初始化为oled地址
        UCB1CTL1 &= ~UCSWRST;                   // 清除SW重置,完成操作
        OLED_Init();
        fill_picture(1);
        while(1)
         ;
    }
    void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
    {
        UCB1CTL1 |= UCTR;
        USCI_B_I2C_clearInterrupt(USCI_B1_BASE,USCI_B_I2C_TRANSMIT_INTERRUPT);
        UCB1IE &= ~UCRXIE;                        // Disable RX interrupt
        UCB1IE |= UCTXIE;                         // Enable TX interrupt
        while(UCB1STAT & UCBBUSY);
     kk++;
     iiccounter=2;
     if(cmd)
      iicdata[1]=0x40;
     else
      iicdata[1]=0x00;
     iicdata[0]=dat;
     UCB1CTL1 |= UCTXSTT;
     __bis_SR_register(LPM0_bits + GIE);
     while (UCB1CTL1 & UCTXSTP);
    }
    void OLED_Init(void)
    {
        OLED_WR_Byte(0xAE,OLED_CMD);
     OLED_WR_Byte(0x00,OLED_CMD);
     OLED_WR_Byte(0x10,OLED_CMD);
     OLED_WR_Byte(0x40,OLED_CMD);
     OLED_WR_Byte(0xB0,OLED_CMD);
     OLED_WR_Byte(0x81,OLED_CMD);
     OLED_WR_Byte(0xFF,OLED_CMD);
     OLED_WR_Byte(0xA1,OLED_CMD);
     OLED_WR_Byte(0xA6,OLED_CMD);
     OLED_WR_Byte(0xA8,OLED_CMD);
     OLED_WR_Byte(0x3F,OLED_CMD);
     OLED_WR_Byte(0xC8,OLED_CMD);
     OLED_WR_Byte(0xD3,OLED_CMD);
     OLED_WR_Byte(0x00,OLED_CMD);
     OLED_WR_Byte(0xD5,OLED_CMD);
     OLED_WR_Byte(0x80,OLED_CMD);
     OLED_WR_Byte(0xD8,OLED_CMD);
     OLED_WR_Byte(0x05,OLED_CMD);
     OLED_WR_Byte(0xD9,OLED_CMD);
     OLED_WR_Byte(0xF1,OLED_CMD);
     OLED_WR_Byte(0xDA,OLED_CMD);
     OLED_WR_Byte(0x12,OLED_CMD);
     OLED_WR_Byte(0xDB,OLED_CMD);
     OLED_WR_Byte(0x30,OLED_CMD);
     OLED_WR_Byte(0x8D,OLED_CMD);
     OLED_WR_Byte(0x14,OLED_CMD);
     OLED_WR_Byte(0xAF,OLED_CMD);
    }
    void fill_picture(unsigned char fill_Data)
    {
     unsigned char m,n;
     for(m=0;m<8;m++)
     {
      OLED_WR_Byte(0xb0+m,0);
      OLED_WR_Byte(0x00,0);
      OLED_WR_Byte(0x10,0);
      for(n=0;n<128;n++)
       {
        OLED_WR_Byte(fill_Data,1);
       }
     }
    }
    #pragma vector = USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    {
       switch(UCB1IV)
       {
       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(iiccounter)                             // Check TX byte counter
         {
          UCB1TXBUF=iicdata[iiccounter-1];
          iiccounter--;
         }
         else
         {
          iicfinish=1;
             UCB1CTL1 |= UCTXSTP;
             UCB1IFG &= ~UCTXIFG;
             __bic_SR_register_on_exit(LPM0_bits);
         }
         break;
       default: break;
       }
    }

    有没有示波器,抓个波形分析一下原因。