这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【PocketBeagle2】八,OLED

共1条 1/1 1 跳转至

【PocketBeagle2】八,OLED

菜鸟
2025-11-03 09:37:25     打赏
【PocketBeagle2】八,OLED

前几章我们的I2C驱动是基于内核的,这一次是基于用户态的,还是使用I2C2,接线实物图如下:

image-20251103082629391image.png

一,软件部分
  1. 探测地址

    i2cdetect -y -r 2

    image-20251103082649216image.png

  2. 源码

    oled.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    #include "oled.h"
    #include "codetab.h"

    int fd = -1;

    static uint8 oled_i2c_write(int fd, uint8 reg, uint8 val)
    {
       int retries;
       uint8 data[2];
       int write_error = 0;

       data[0] = reg;
       data[1] = val;
       
       ioctl(fd, I2C_SLAVE, OLED_ADDRESS);

       for (retries = 5; retries; retries--)
       {
           if (write(fd, data, 2) == 2)
           {
               return 0;
           }
           usleep(1000);
       }
       return -1;
    }

    void WriteCmd(unsigned char I2C_Command)
    {
    oled_i2c_write(fd, OLED_COMMEND_ADDR, I2C_Command);
    }

    void WriteDat(unsigned char I2C_Data)
    {
    oled_i2c_write(fd, OLED_DATA_ADDR, I2C_Data);
    }

    void OLED_Init(void)
    {
    fd = open("/dev/i2c-2", O_RDWR); // open file and enable read and  write

       if (fd < 0)
       {
           perror("Can't open /dev/i2c-2 \n"); // open i2c dev file fail
           exit(1);
       }

    if (ioctl(fd, I2C_SLAVE, OLED_ADDRESS) < 0)
       { //set i2c address
           printf("fail to set i2c device slave address!\n");
           close(fd);
       }

    usleep(100 * 1000);
    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_SetPos(unsigned char x, unsigned char y)
    {
    WriteCmd(0xb0+y);
    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(0xff);
    }

    void OLED_ON(void)
    {
    WriteCmd(0X8D);  //���õ�ɱ�
    WriteCmd(0X14);  //������ɱ�
    WriteCmd(0XAF);  //OLED����
    }

    void OLED_OFF(void)
    {
    WriteCmd(0X8D);  //���õ�ɱ�
    WriteCmd(0X10);  //�رյ�ɱ�
    WriteCmd(0XAE);  //OLED����
    }

    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)
    {
     case 1:
     {
      while(ch[j] != '\0')
      {
       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] != '\0')
      {
       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;
    }
    }

    void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
    {
    unsigned char wm=0;
    unsigned int  adder=32*N;
    OLED_SetPos(x , y);
    for(wm = 0;wm < 16;wm++)
    {
     WriteDat(F16x16[adder]);
     adder += 1;
    }
    OLED_SetPos(x,y + 1);
    for(wm = 0;wm < 16;wm++)
    {
     WriteDat(F16x16[adder]);
     adder += 1;
    }
    }

    void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
    {
    unsigned int j=0;
    unsigned char x,y;

     if(y1%8==0)
     y = y1/8;
     else
     y = y1/8 + 1;
    for(y=y0;y<y1;y++)
    {
     OLED_SetPos(x0,y);
       for(x=x0;x<x1;x++)
     {
      WriteDat(BMP[j++]);
     }
    }
    }

    main.c


    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/select.h>
    #include <sys/time.h>
    #include <errno.h>

    #include "oled.h"

    extern int fd;

    int main(int argc, char **argv)
    {
       OLED_Init();
    OLED_Fill(0x00);
    OLED_ShowStr(0,0,"pocketbeagle 2",2);

       while(1)
       {
     
       }
       close(fd);
       return 0;
    }
  3. 编译

     gcc oled.c main.c
  4. 运行

    ./a.out


二,演示

image.png



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]