求助,i2c驱动的oled字符重叠

2019-08-30 10:24发布

RT,驱动是网上找来自己改一改的。
OLED_ShowStr(0,0,str1,1);
OLED_ShowStr(0,16,str2,1);
OLED_ShowStr(0,32,str3,1);
OLED_ShowStr(0,48,str4,1);

主函数里是这样设置显示的,y轴上分别有16个像素的偏移,可是效果却是4个字符串重叠在一起,全部在(0,0)的位置,反复切换显示,可以在图片上看到字符有重影。
希望有大神帮忙解答一下啊
另外oled的驱动:
void SCL_OUT(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = SCL;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void SDA_OUT(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = SDA;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void SDA_IN(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_InitStruct.GPIO_Pin = SDA;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void Delay_nus(unsigned int n)
{
        uint16_t i=0;
        uint16_t timer = n;
        while(timer--)
         {
                i=15;
                while(i--);
   }
}

void OLED_Start()
{
        SDA_OUT();
  GPIO_SetBits(GPIOA, SCL);                    
  GPIO_SetBits(GPIOA, SDA);                  
  Delay_nus(5);                 
  GPIO_ResetBits(GPIOA, SDA);                    
  Delay_nus(5);                 
  GPIO_ResetBits(GPIOA, SCL);         
        Delay_nus(5);       
}

void OLED_Stop()
{
        SDA_OUT();
        SCL_OUT();
  GPIO_ResetBits(GPIOA, SDA);                  
  GPIO_SetBits(GPIOA, SCL);                     
  Delay_nus(5);                 
  GPIO_SetBits(GPIOA, SDA);                    
  Delay_nus(5);                 
}

u8 OLED_Wait_Ask(void)
{
  int count=0;
  SDA_IN();
  GPIO_SetBits(GPIOA, SCL);  
  Delay_nus(5);
  while(GPIO_ReadInputDataBit(GPIOA, SDA))
  {
    count++;
    if(count>250)
    {
      OLED_Stop();
      return 1;
     }   
   }
  GPIO_ResetBits(GPIOA, SCL);
  Delay_nus(5);
  return 0;
}

void OLED_WriteByte(u8 data)
{
    u8 i;
    SDA_OUT();
    for(i=0;i<8;i++)
    {
        GPIO_ResetBits(GPIOA, SCL);
        Delay_nus(5);
        if(data & 0x80)     
            GPIO_SetBits(GPIOA, SDA);
        else
            GPIO_ResetBits(GPIOA, SDA);
        GPIO_SetBits(GPIOA, SCL);
        Delay_nus(5);
        GPIO_ResetBits(GPIOA, SCL);
        data<<=1;
    }
}

void WriteCmd(u8 command)
{
    OLED_Start();
    OLED_WriteByte(0x78);          //地址
    OLED_Wait_Ask();
    OLED_WriteByte(0x00);          //寄存器
    OLED_Wait_Ask();
    OLED_WriteByte(command);
    OLED_Wait_Ask();
    OLED_Stop();
}

void WriteDat(u8 data)
{
    OLED_Start();
    OLED_WriteByte(0x78);                                                //地址
    OLED_Wait_Ask();                                                               
    OLED_WriteByte(0x40);                                                //寄存器
    OLED_Wait_Ask();
    OLED_WriteByte(data);
    OLED_Wait_Ask();
    OLED_Stop();
}

void OLED_Init(void)
{
    Delay_nus(10000); //10ms

    WriteCmd(0xAE); //display off
    WriteCmd(0x20); //Set Memory Addressing Mode   
    WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
    WriteCmd(0xc8); //Set COM Output Scan Direction
    WriteCmd(0x00); //---set low column address
    WriteCmd(0x10); //---set high column address
    WriteCmd(0x40); //--set start line address
    WriteCmd(0x81); //--set contrast control register
    WriteCmd(0xff); //亮度调节 0x00~0xff
    WriteCmd(0xa1); //--set segment re-map 0 to 127
    WriteCmd(0xa6); //--set normal display
    WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
    WriteCmd(0x3F); //
    WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    WriteCmd(0xd3); //-set display offset
    WriteCmd(0x00); //-not offset
    WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
    WriteCmd(0xf0); //--set divide ratio
    WriteCmd(0xd9); //--set pre-charge period
    WriteCmd(0x22); //
    WriteCmd(0xda); //--set com pins hardware configuration
    WriteCmd(0x12);
    WriteCmd(0xdb); //--set vcomh
    WriteCmd(0x20); //0x20,0.77xVcc
    WriteCmd(0x8d); //--set DC-DC enable
    WriteCmd(0x14); //
    WriteCmd(0xaf); //--turn on oled panel
}

void OLED_ON(void)
{
    WriteCmd(0X8D);  //设置电源泵
    WriteCmd(0X14);  //开启电源泵
    WriteCmd(0XAF);  //OLED唤醒
}

void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{
//    WriteCmd(0xb0|y);
                WriteCmd(0xb0|y);
                WriteCmd(((x&0xf0)>>4)|0x10);
                WriteCmd((x&0x0f)|0x01);

//    WriteCmd(((x&0xf0)>>4)|0x10);
//    WriteCmd((x&0x0f)|0x01);
}

void OLED_Fill(unsigned char fill_Data)//全屏填充
{
    unsigned char m,n;
    for(m=0;m<8;m++)
    {
        WriteCmd(0xb0+m);       //page0-page1
        WriteCmd(0x00);     //low column start address
        WriteCmd(0x10);     //high column start address
        for(n=0;n<128;n++)
        {
           WriteDat(fill_Data);
        }
    }
}

void OLED_CLS(void)      //清屏
{
    OLED_Fill(0x00);
}

void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)               
{
    unsigned char c = 0,i = 0,j = 0;
                switch(TextSize)                //1:6*8 ; 2:8*16
    {
        case 1:
        {
            while(ch[j] != '')
            {
                c = ch[j] - 32;
                if(x > 126)
                {
                    x = 0;
                    y++;
                }
                OLED_SetPos(x,y);
                for(i=0;i<6;i++)
                    WriteDat(F6x8[c][i]);
                x += 6;
                j++;
            }
        }break;
        case 2:
        {
            while(ch[j] != '')
            {
                c = ch[j] - 32;
                if(x > 120)
                {
                    x = 0;
                    y++;
                }
                OLED_SetPos(x,y);
                for(i=0;i<8;i++)
                    WriteDat(F8X16[c*16+i]);
                OLED_SetPos(x,y+1);
                for(i=0;i<8;i++)
                    WriteDat(F8X16[c*16+i+8]);
                x += 8;
                j++;
            }
        }break;
    }
}

RT,驱动是网上找来自己改一改的。
OLED_ShowStr(0,0,str1,1);
OLED_ShowStr(0,16,str2,1);
OLED_ShowStr(0,32,str3,1);
OLED_ShowStr(0,48,str4,1);

主函数里是这样设置显示的,y轴上分别有16个像素的偏移,可是效果却是4个字符串重叠在一起,全部在(0,0)的位置,反复切换显示,可以在图片上看到字符有重影。
希望有大神帮忙解答一下啊
另外oled的驱动:
void SCL_OUT(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = SCL;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void SDA_OUT(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = SDA;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void SDA_IN(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_InitStruct.GPIO_Pin = SDA;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void Delay_nus(unsigned int n)
{
        uint16_t i=0;
        uint16_t timer = n;
        while(timer--)
         {
                i=15;
                while(i--);
   }
}

void OLED_Start()
{
        SDA_OUT();
  GPIO_SetBits(GPIOA, SCL);                    
  GPIO_SetBits(GPIOA, SDA);                  
  Delay_nus(5);                 
  GPIO_ResetBits(GPIOA, SDA);                    
  Delay_nus(5);                 
  GPIO_ResetBits(GPIOA, SCL);         
        Delay_nus(5);       
}

void OLED_Stop()
{
        SDA_OUT();
        SCL_OUT();
  GPIO_ResetBits(GPIOA, SDA);                  
  GPIO_SetBits(GPIOA, SCL);                     
  Delay_nus(5);                 
  GPIO_SetBits(GPIOA, SDA);                    
  Delay_nus(5);                 
}

u8 OLED_Wait_Ask(void)
{
  int count=0;
  SDA_IN();
  GPIO_SetBits(GPIOA, SCL);  
  Delay_nus(5);
  while(GPIO_ReadInputDataBit(GPIOA, SDA))
  {
    count++;
    if(count>250)
    {
      OLED_Stop();
      return 1;
     }   
   }
  GPIO_ResetBits(GPIOA, SCL);
  Delay_nus(5);
  return 0;
}

void OLED_WriteByte(u8 data)
{
    u8 i;
    SDA_OUT();
    for(i=0;i<8;i++)
    {
        GPIO_ResetBits(GPIOA, SCL);
        Delay_nus(5);
        if(data & 0x80)     
            GPIO_SetBits(GPIOA, SDA);
        else
            GPIO_ResetBits(GPIOA, SDA);
        GPIO_SetBits(GPIOA, SCL);
        Delay_nus(5);
        GPIO_ResetBits(GPIOA, SCL);
        data<<=1;
    }
}

void WriteCmd(u8 command)
{
    OLED_Start();
    OLED_WriteByte(0x78);          //地址
    OLED_Wait_Ask();
    OLED_WriteByte(0x00);          //寄存器
    OLED_Wait_Ask();
    OLED_WriteByte(command);
    OLED_Wait_Ask();
    OLED_Stop();
}

void WriteDat(u8 data)
{
    OLED_Start();
    OLED_WriteByte(0x78);                                                //地址
    OLED_Wait_Ask();                                                               
    OLED_WriteByte(0x40);                                                //寄存器
    OLED_Wait_Ask();
    OLED_WriteByte(data);
    OLED_Wait_Ask();
    OLED_Stop();
}

void OLED_Init(void)
{
    Delay_nus(10000); //10ms

    WriteCmd(0xAE); //display off
    WriteCmd(0x20); //Set Memory Addressing Mode   
    WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
    WriteCmd(0xc8); //Set COM Output Scan Direction
    WriteCmd(0x00); //---set low column address
    WriteCmd(0x10); //---set high column address
    WriteCmd(0x40); //--set start line address
    WriteCmd(0x81); //--set contrast control register
    WriteCmd(0xff); //亮度调节 0x00~0xff
    WriteCmd(0xa1); //--set segment re-map 0 to 127
    WriteCmd(0xa6); //--set normal display
    WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
    WriteCmd(0x3F); //
    WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    WriteCmd(0xd3); //-set display offset
    WriteCmd(0x00); //-not offset
    WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
    WriteCmd(0xf0); //--set divide ratio
    WriteCmd(0xd9); //--set pre-charge period
    WriteCmd(0x22); //
    WriteCmd(0xda); //--set com pins hardware configuration
    WriteCmd(0x12);
    WriteCmd(0xdb); //--set vcomh
    WriteCmd(0x20); //0x20,0.77xVcc
    WriteCmd(0x8d); //--set DC-DC enable
    WriteCmd(0x14); //
    WriteCmd(0xaf); //--turn on oled panel
}

void OLED_ON(void)
{
    WriteCmd(0X8D);  //设置电源泵
    WriteCmd(0X14);  //开启电源泵
    WriteCmd(0XAF);  //OLED唤醒
}

void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{
//    WriteCmd(0xb0|y);
                WriteCmd(0xb0|y);
                WriteCmd(((x&0xf0)>>4)|0x10);
                WriteCmd((x&0x0f)|0x01);

//    WriteCmd(((x&0xf0)>>4)|0x10);
//    WriteCmd((x&0x0f)|0x01);
}

void OLED_Fill(unsigned char fill_Data)//全屏填充
{
    unsigned char m,n;
    for(m=0;m<8;m++)
    {
        WriteCmd(0xb0+m);       //page0-page1
        WriteCmd(0x00);     //low column start address
        WriteCmd(0x10);     //high column start address
        for(n=0;n<128;n++)
        {
           WriteDat(fill_Data);
        }
    }
}

void OLED_CLS(void)      //清屏
{
    OLED_Fill(0x00);
}

void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)               
{
    unsigned char c = 0,i = 0,j = 0;
                switch(TextSize)                //1:6*8 ; 2:8*16
    {
        case 1:
        {
            while(ch[j] != '')
            {
                c = ch[j] - 32;
                if(x > 126)
                {
                    x = 0;
                    y++;
                }
                OLED_SetPos(x,y);
                for(i=0;i<6;i++)
                    WriteDat(F6x8[c][i]);
                x += 6;
                j++;
            }
        }break;
        case 2:
        {
            while(ch[j] != '')
            {
                c = ch[j] - 32;
                if(x > 120)
                {
                    x = 0;
                    y++;
                }
                OLED_SetPos(x,y);
                for(i=0;i<8;i++)
                    WriteDat(F8X16[c*16+i]);
                OLED_SetPos(x,y+1);
                for(i=0;i<8;i++)
                    WriteDat(F8X16[c*16+i+8]);
                x += 8;
                j++;
            }
        }break;
    }
}