基于TI cc2541的I2C 的OLED应用,遇到一些问题

2019-07-24 16:28发布

最近在cc2541上,用到了I2C,并和OLED建立通信。
我尝试过使用硬件I2C,结果不理想,不知打哪里出问题了,
最后又使用了软件i2C,但OLED仍然没有显示。
只能又来发帖,请教各位经验之士了。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
19条回答
azq13158
2019-07-24 21:42
下面我贴上我软件i2c的代码,请各位指教。

#define STATE_MAX               0xFF
#define STATE_MIN               0x00
#define STATE_55                0x55
#define STATE_AA                0xAA
#define START_PAGE              0xB0
#define OLED_TOTAL_PAGE         2
//#define START_HIGH_BIT          0x12
//#define START_LOW_BIT           0x00
#define START_HIGH_BIT          0x10
#define START_LOW_BIT           0x00
#define FRAME_HIGH_ROW          0x01
#define FRAME_LOW_ROW           0x80

#define COLUMN_MIN              0
#define COLUMN_MAX              96
#define ROW_MAX                 16

// The address of SSD1306
#define        OLED_ADDR               0x78               
#define        OP_CMD                  0x00
#define        OP_DATA                 0x40


#define I2C_IO_ENABLE()       st( I2CWC =  0x83;)
#define I2C_SDA_HI()          st( I2CIO |= 0x01;)
#define I2C_SDA_LOW()         st( I2CIO &= ~(0x01);)
#define I2C_SDA_READ()        (I2CIO & 0x01)
#define I2C_SCL_HI()          st( I2CIO |= 0x02;)
#define I2C_SCL_LOW()         st( I2CIO &= ~(0x02);)
#define I2C_SCL_READ()        (I2CIO&0x02)




CONST uint8 num4x8[] =
{
   0x7C,0x82,0x82,0x7C,  // -- 0 --   num4x8[0]
   0x00,0x04,0xFE,0x00,  // -- 1 --   num4x8[4]
   0xCC,0xA2,0x92,0x8C,  // -- 2 --   num4x8[8]
   0x44,0x92,0x92,0x6C,  // -- 3 --   num4x8[12]
   0x78,0x44,0xFE,0x40,  // -- 4 --   num4x8[16]
   0x4E,0x8A,0x8A,0x72,  // -- 5 --   num4x8[20]
   0x7C,0x92,0x92,0x64,  // -- 6 --   num4x8[24]
   0x02,0xC2,0x32,0x0E,  // -- 7 --   num4x8[28]
   0x6C,0x92,0x92,0x6C,  // -- 8 --   num4x8[32]
   0x4C,0x92,0x92,0x7C,  // -- 9 --   num4x8[36]
   0xBC,0xC2,0x02,0xC2,0xBC, // -- O -- num4x8[40]
   0x3E,0x40,0x80,0x40,0x3E, // -- V -- num4x8[45]
};


static void Delay_I2C(void)
{
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
}

void Hal_HW_WaitUs(uint16 microSecs)
{
  while(microSecs--)
  {
    /* 32 NOPs == 1 usecs */
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop");
  }
}

static void Hal_IIC_Start(void)
{
   I2C_SDA_HI();
   I2C_SCL_HI();
   Delay_I2C();
   I2C_SDA_LOW();
   Delay_I2C();
   I2C_SCL_LOW();
}

static void Hal_IIC_Stop(void)
{
   I2C_SDA_LOW();
   Delay_I2C();
   I2C_SCL_HI();
   Delay_I2C();
   I2C_SDA_HI();
}

void IIC_Write_Data(uint8 Data)
{
    for(uint8 i = 0; i < 8; i++)               
    {
        if((Data<<i) & 0x80)
          I2C_SDA_HI();
        else
          I2C_SDA_LOW();

        Delay_I2C();
        I2C_SCL_HI();
        Delay_I2C();
        I2C_SCL_LOW();
    }
   
    I2C_SDA_HI(); //Release the I2C bus,and generates the signal of ack for master
    Delay_I2C();
    I2C_SCL_HI();
    Delay_I2C();
    I2C_SCL_LOW();       
}

void LCD_Write_Cmd(uint8 command)
{
   Hal_IIC_Start();
   IIC_Write_Data(OLED_ADDR);                // send the address of the OLED
   IIC_Write_Data(OP_CMD);                   // send the write command to the oled
   IIC_Write_Data(command);                  // send the command to the oled
   Hal_IIC_Stop();                          // stop the iic bus after send over
}

void LCD_Write_Dat_Start(void)
{
   Hal_IIC_Start();                        // Start-up the I2C bus
   IIC_Write_Data(OLED_ADDR);               // Send the Salve Adress
   IIC_Write_Data(OP_DATA);                 // Send the write command
}

static void OLED_Reset(void)
{
   OLED_NORMAL();
   Hal_HW_WaitUs(10000);
   OLED_RESET();
   Hal_HW_WaitUs(50000);
   OLED_NORMAL();
   Hal_HW_WaitUs(50000);
}

static void Init_OLED_IC()
{
   LCD_Write_Cmd(0xAE);       //Display OFF (sleep mode)
   LCD_Write_Cmd(0xD5);       //Set Display Clock Divide Ratio/Oscillator Frequency
   LCD_Write_Cmd(0xD0);       //0x71
   LCD_Write_Cmd(0xA8);       //Set Multiplex Ratio
   LCD_Write_Cmd(0x0F);       //32
   LCD_Write_Cmd(0xD3);       //Set Display Offset
   LCD_Write_Cmd(0x00);       //
   LCD_Write_Cmd(0x40);       //Set Display Start Line
   LCD_Write_Cmd(0x8D);       //Set Display Offset
   LCD_Write_Cmd(0x14);       //VCC Generated by Internal DC/DC circuit
   
   LCD_Write_Cmd(0xA1);              //¿ØÖÆSEGÏÔʾ×óÓÒ·­×ª         £¬A0H/A1H
   LCD_Write_Cmd(0xC8);              //¿ØÖÆcomÏÔʾÉÏÏ·­×ª         £¬C0H/C8H
   
   LCD_Write_Cmd(0xDA);       //Set COM Pins Hardware Configuration
   LCD_Write_Cmd(0x02);       //

   LCD_Write_Cmd(0x81);       //Set Contrast Control
   LCD_Write_Cmd(0x56);       //0x23

   LCD_Write_Cmd(0xD9);       //Set Pre-charge Period
   LCD_Write_Cmd(0xF1);       //VCC Generated by Internal DC/DC circuit
   LCD_Write_Cmd(0xDB);       //Set VCOMH Deselect Level
   LCD_Write_Cmd(0x20);       //0x3C
   LCD_Write_Cmd(0xA4);       //Output follows RAM content
   LCD_Write_Cmd(0xA6);       //Set Normal Display
   LCD_Write_Cmd(0xAF);       //Set Display ON
}

uint8 Display_Init(uint8 flip_set)
{
    if(flip_set)
    {       
      LCD_Write_Cmd(0xA0);            //控制SEG显示左右翻转         ,A0H/A1H
      LCD_Write_Cmd(0xC0);             //控制com显示上下翻转         ,C8H/C0H

    }
    else
    {
      //初始化时已经写过A0,C0
      LCD_Write_Cmd(0xA1);            //控制SEG显示左右翻转         ,A0H/A1H
      LCD_Write_Cmd(0xC8);            //控制com显示上下翻转         ,C8H/C0H
    }
   
    Clear_Screen(flip_set);
   
    return TRUE;
}

void HaloLedInit(void)
{
  
  OLED_RST_SEL &= ~OLED_RST_BIT;  // Config the reset pin
  OLED_RST_DDR |= OLED_RST_BIT;
  I2C_IO_ENABLE();               // Enable the pins of the I2C bus
  OLED_Reset();                  // Reset the oled
  Init_OLED_IC();                // initial the the register of the oled

}

void Clear_Screen(uint8 flip)
{  
   uint8 i,page_number,column_number;

   i = reversal_chk(flip);
   for(page_number=0;page_number<OLED_TOTAL_PAGE;page_number++)
   {
       LCD_Write_Cmd(START_PAGE+page_number);
       LCD_Write_Cmd(START_HIGH_BIT+i);
       LCD_Write_Cmd(START_LOW_BIT);
       LCD_Write_Dat_Start();
       for(column_number=COLUMN_MIN;column_number<COLUMN_MAX;column_number++)
       {
          IIC_Write_Data(STATE_MIN);
       }
           Hal_IIC_Stop();
   }
}

void Display_Number(uint8 flip,uint8 num,uint8 start_col,uint8 start_page,Num_Font_Def font)
{
    uint8 page_number,column_number,page_total,width_total;
    CONST uint8  *p;
    uint16 num_addr = 0;
    uint8 i = reversal_chk(flip);
    // select the type of the number
   
    switch(font)
    {
      // temporary needs is Font4x8
        case Font4x8 :
        {
            
            page_total = 1;
            if(num >= 10)
            {
               num_addr = 40 + (num-10)*5;
               p = &num4x8[num_addr];
               width_total = 5;
            }
            else if(num < 10)
            {
               width_total = 4;
               p = &num4x8[num*4];
            }
            
        }break;
        case Font8x16  :
        {
            page_total = 2;
            width_total = 8;
            if(num == 0)
              p = &num8x16[0];
            else if(num == 1)
            {
                p = &num8x16[16];
                width_total = 6;
            }
            else
            {
              num_addr = 28 + ((num-2)<<4);
               p = &num8x16[num_addr];
              if(num == WAT_UINT)
                width_total = 13;
            }

        }break;
      
        default: break;
    }
       
    // write the data to the OLED
    for(page_number=start_page;page_number<(start_page+page_total);page_number++)
    {
         LCD_Write_Cmd(START_PAGE+page_number);  // Set the page address
         LCD_Write_Cmd(START_HIGH_BIT + (start_col/15)+i);         // Set Higher Column Start Address for Page Addressing Mode
             LCD_Write_Cmd(START_LOW_BIT + (start_col%15));            // Set Lower Column Start Address for Page Addressing Mode
             LCD_Write_Dat_Start();                      // Start to write data

               
         for(column_number=0;column_number<width_total;column_number++)
         {
            IIC_Write_Data(*p++);
         }
        
    }
       
}


int main()
{
        Init_Pot();
        HaloLedInit();
        Display_Init(0);

        Clear_Screen(0);
        //不翻转  写入数字 1  在第0列,第0页开始写入  字体为Font4*8
        Display_Number(0,9,1,0,Font4x8);  
}

一周热门 更多>