jinglixixi 发表于 2020-11-1 00:10

【MM32 eMiniBoard测评】+OLED屏的驱动显示

本帖最后由 jinglixixi 于 2020-11-1 00:14 编辑

<p>1.使用GPIO口模拟I2C接口</p>

<p>在例程中提供了一个LED灯闪烁程序,通过它我们可以掌握控制GPIO口定义输出口及输出高低电平信号的方法,据此可用GPIO口来模拟I2C接口以控制该接口形式的OLED显示屏它该OLED显示屏具有占用引脚少,显示信息量较多的特点。</p>

<p>在引脚的分配上,用PB6来连接OLED屏的SCK引脚,用PB7来连接OLED屏的SDA引脚,为此其输出高低的定义为:</p>

<p>#define OLED_SCLK_Clr()&nbsp; GPIO_ResetBits(GPIOB,GPIO_Pin_13)</p>

<p>#define OLED_SCLK_Set()&nbsp; GPIO_SetBits(GPIOB,GPIO_Pin_13)</p>

<p>&nbsp;</p>

<p>#define OLED_SDIN_Clr()&nbsp; GPIO_ResetBits(GPIOB,GPIO_Pin_14)</p>

<p>#define OLED_SDIN_Set()&nbsp; GPIO_SetBits(GPIOB,GPIO_Pin_14)</p>

<p>&nbsp;</p>

<p>引脚输出功能的配置函数为:</p>

<pre>
<code class="language-cpp">void APP_OLED_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    GPIO_StructInit(&amp;GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13 | GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &amp;GPIO_InitStructure);
}</code></pre>

<p>相应的OLED显示屏的初始化函数为:</p>

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

<p>2. OLED屏显示驱动</p>

<p>在完成功能引脚定义及初始化的基础下,要实现具体的字符及数值的显示,需相关函数的配合,关键的函数为:</p>

<pre>
<code class="language-cpp">void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{
              unsigned char c=0,i=0;
              c=chr-' ';
             if(x&gt;Max_Column-1){x=0;y=y+2;}
             if(Char_Size ==16)
             {
                     OLED_Set_Pos(x,y);
                      for(i=0;i&lt;8;i++)
                        OLED_WR_Byte(F8X16,OLED_DATA);
                        OLED_Set_Pos(x,y+1);
                        for(i=0;i&lt;8;i++)
                        OLED_WR_Byte(F8X16,OLED_DATA);
               }
               else {

                      OLED_Set_Pos(x,y);
                      for(i=0;i&lt;6;i++)
                      OLED_WR_Byte(F6x8,OLED_DATA);
              }
}


uint32_t oled_pow(uint8_t m,uint8_t n)
{
        uint32_t result=1;
        while(n--)result*=m;
        return result;
}


void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
{
         uint8_t t,temp;
         uint8_t enshow=0;
         for(t=0;t&lt;len;t++)
         {
                   temp=(num/oled_pow(10,len-t-1))%10;
                   if(enshow==0&amp;&amp;t&lt;(len-1))
                   {
                            if(temp==0)
                            {
                                     OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
                                     continue;
                            }else enshow=1;
                   }
                   OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
         }
}


void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
        unsigned char j=0;
         while (chr!='\0')
         {              OLED_ShowChar(x,y,chr,Char_Size);
                        x+=8;
                        if(x&gt;120){x=0;y+=2;}
                        j++;
         }
}</code></pre>

<p>3.显示功能的测试</p>

<p>为了测试OLED屏的显示功能,其主函数如下:</p>

<pre>
<code class="language-cpp">s32 main(void)
{
              APP_OLED_Init();
              OLED_Init();
            OLED_Clear(); 
              OLED_ShowString(0,0,"MM32F0133 TEST",16);
              OLED_ShowString(0,2,"OLED Display",16);
             while(1);
}</code></pre>

<p>相应的显示效果如图所示,后面就可以为其添加具体的应用功能了。</p>

<p><i></i></p>

<p>&nbsp;显示效果图</p>

w494143467 发表于 2020-11-1 10:38

<p>刚好有类似的LED灯,到时候也驱动一下看看。<img height="52" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/pleased.gif" width="48" /></p>

jinglixixi 发表于 2020-11-1 17:54

w494143467 发表于 2020-11-1 10:38
刚好有类似的LED灯,到时候也驱动一下看看。

<p>这款OLED屏是最适合Arduino接口的</p>
页: [1]
查看完整版本: 【MM32 eMiniBoard测评】+OLED屏的驱动显示