这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 有奖活动 » 基于AG32VH407的串行数码管与OLED屏显示驱动

共5条 1/1 1 跳转至

基于AG32VH407的串行数码管与OLED屏显示驱动

助工
2026-04-07 00:32:01     打赏

先前受困于没有解决GPIO引脚正确输出高低电平的问题,故难以完成串行数码管显示模块的驱动,如今解决了GPIO的输出问题,自然就可以直面显示驱动啦

由于该显示模块以MAX7219为主控芯片,可显示8位数值,并支持级联使用,故显示数位可进行相应的扩展。在使用时,除电源外它只需3GPIO口,就可对其进行扩展,因此十分节省引脚资源。

image.png

1 串行数码管显示模块

该显示模块与开发板的连接关系为:

SCL---PIN_62

SDA---PIN_61

CS---PIN_57

为此在 VE文件中建立的映射关系如下:

GPIO5_0 PIN_62  #CLK

GPIO5_1 PIN_61  #SDA

GPIO5_4 PIN_57  #CS

为便于向串行数码管显示模块提供高低电平的输出,定义的语句为:

#define CLK_SetLow  GPIO_SetLow(GPIO5,GPIO_BIT0)

#define CLK_SetHigh GPIO_SetHigh(GPIO5,GPIO_BIT0)

#define DIN_SetLow  GPIO_SetLow(GPIO5,GPIO_BIT1)

#define DIN_SetHigh GPIO_SetHigh(GPIO5,GPIO_BIT1)

#define CS_SetLow   GPIO_SetLow(GPIO5,GPIO_BIT4)

#define CS_SetHigh  GPIO_SetHigh(GPIO5,GPIO_BIT4)

由于该串行数码管显示模块所使用的关键芯片为MAX7219,故为它配置了一个串行发送字节数据的函数,其内容为:

void Write_Max7219_byte(char DATA)
{
  char i;
  CS_SetLow;
  UTIL_IdleUs(10);
  for(i=8;i>=1;i--)
  {
      CLK_SetLow;
      if(DATA&0x80)
         DIN_SetHigh;
      else
         DIN_SetLow;
      UTIL_IdleUs(10);
      DATA=(char)(DATA<<1);
      CLK_SetHigh;
      UTIL_IdleUs(10); 
  }
}

以函数Write_Max7219_byte()为基础,向指定地址发送数据的函数为:

void Write_Max7219(char address,char dat)
{
  CS_SetLow;
  Write_Max7219_byte(address);
  Write_Max7219_byte(dat);
  CS_SetHigh;
}

对于串行数码管显示模块,其初始化函数为:

void Init_MAX7219(void)
{
   Write_Max7219(0x09, 0xff);
   Write_Max7219(0x0a, 0x02);
   Write_Max7219(0x0b, 0x07);
   Write_Max7219(0x0c, 0x01);
   Write_Max7219(0x0f, 0x00);
}

要实现串行数码管显示模块的驱动,相应的测试程序为:

void TestGpio()
{
  SYS_EnableAPBClock(APB_MASK_GPIO5);
   GPIO_SetOutput(GPIO5, GPIO_BIT0);
   GPIO_SetOutput(GPIO5, GPIO_BIT1);
   GPIO_SetOutput(GPIO5, GPIO_BIT4);
   GPIO_SetLow(GPIO5,GPIO_BIT0);
   GPIO_SetLow(GPIO5,GPIO_BIT1);
   GPIO_SetLow(GPIO5,GPIO_BIT4);
   Init_MAX7219();
   Write_Max7219(1,1);
   Write_Max7219(2,2);
   Write_Max7219(3,3);
   Write_Max7219(4,4);
   Write_Max7219(5,5);
   Write_Max7219(6,6);
   Write_Max7219(7,7);
   Write_Max7219(8,8);
   while (1);
}

经程序编译与烧录,其效果如图2所示。

image.png

2 显示效果图

解决了串行数码管的显示问题,就确定了模拟驱动方式的成功,接下来就可以模拟I2C的方式来驱动OLED显示屏了。

这里选配的是一款0.96寸的单色显示屏,以匹配AG32VH407开发板的小体型

OLED与开发板的连接关系为:

SCL---PIN_62

SDA---PIN_61

为此在 VE文件中建立的映射关系如下:

GPIO5_0 PIN_62  #CLK

GPIO5_1 PIN_61  #SDA

为便于向串行数码管显示模块提供高低电平的输出,定义的语句为:

#define CLK_SetLow  GPIO_SetLow(GPIO5,GPIO_BIT0)

#define CLK_SetHigh GPIO_SetHigh(GPIO5,GPIO_BIT0)

#define DIN_SetLow  GPIO_SetLow(GPIO5,GPIO_BIT1)

#define DIN_SetHigh GPIO_SetHigh(GPIO5,GPIO_BIT1) 

模拟I2C方式工作的辅助函数为:


void IIC_Start()
{
      CLK_SetHigh; 
      UTIL_IdleUs(3);
      DIN_SetHigh; 
      UTIL_IdleUs(3);
      DIN_SetLow; 
      UTIL_IdleUs(3);
      CLK_SetLow; 
      UTIL_IdleUs(3);
}
 
void IIC_Stop()
{
    CLK_SetHigh;
    UTIL_IdleUs(3);
    DIN_SetLow;
    UTIL_IdleUs(3);
    DIN_SetHigh;
    UTIL_IdleUs(3);
}
 
void IIC_Wait_Ack()
{
      CLK_SetHigh;
      UTIL_IdleUs(3);
      CLK_SetLow;
      UTIL_IdleUs(3);
}

模拟I2C方式发送字节数据的函数为:

void Write_IIC_Byte(unsigned char IIC_Byte)
{
    unsigned char i;
    unsigned char m,da;
    da=IIC_Byte;
    CLK_SetLow;
    for(i=0;i<8;i++)        
    {
        m=da;
        m=m&0x80;
        if(m==0x80) 
        {
           DIN_SetHigh;
        }
        else 
            DIN_SetLow;
        da=da<<1;
        UTIL_IdleUs(3);
        CLK_SetHigh;
        UTIL_IdleUs(3);
        CLK_SetLow;
        UTIL_IdleUs(3);
    }
}

清屏函数的内容为:

void OLED_Clear(void)  
{  
    uint8_t i,n;            
    for(i=0;i<8;i++)  
    {  
        OLED_WR_Byte (0xb0+i,OLED_CMD);    
        OLED_WR_Byte (0x00,OLED_CMD);      
        OLED_WR_Byte (0x10,OLED_CMD);       
        for(n=0;n<128;n++)  OLED_WR_Byte(0x0,OLED_DATA); 
    } 
}

OLED屏的初始化函数为:

void OLED_Init(void)
{
    Write_IIC_Command(0xAE);
    Write_IIC_Command(0x20);
    Write_IIC_Command(0x10);
    Write_IIC_Command(0xb0); 
    Write_IIC_Command(0xc8); 
    Write_IIC_Command(0x00);
    Write_IIC_Command(0x10); 
    Write_IIC_Command(0x40); 
    Write_IIC_Command(0x81); 
    Write_IIC_Command(0xdf);
    Write_IIC_Command(0xa1); 
    Write_IIC_Command(0xa6); 
    Write_IIC_Command(0xa8); 
    Write_IIC_Command(0x3F); 
    Write_IIC_Command(0xa4); 
    Write_IIC_Command(0xd3);
    Write_IIC_Command(0x00); 
    Write_IIC_Command(0xd5); 
    Write_IIC_Command(0xf0); 
    Write_IIC_Command(0xd9); 
    Write_IIC_Command(0x22); 
    Write_IIC_Command(0xda);
    Write_IIC_Command(0x12);
    Write_IIC_Command(0xdb); 
    Write_IIC_Command(0x20); 
    Write_IIC_Command(0x8d); 
    Write_IIC_Command(0x14);
    Write_IIC_Command(0xaf); 
}

字符串的显示函数为:

void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
    unsigned char j=0;
    while (chr[j]!='\0')
    {       OLED_ShowChar(x,y,chr[j],Char_Size);
            x+=8;
          if(x>120){x=0;y+=2;}
            j++;
    }
}

汉字的显示函数为:

void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{
    uint8_t t,adder=0;
    OLED_Set_Pos(x,y);
    for(t=0;t<16;t++)
    {
                OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
                adder+=1;
    }
    OLED_Set_Pos(x,y+1);
    for(t=0;t<16;t++)
    {
          OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
          adder+=1;
    }
}


实现驱动测试的主程序为:

int main(void)
{
   board_init();
     SYS_EnableAPBClock(APB_MASK_GPIO5);
   GPIO_SetOutput(GPIO5, GPIO_BIT0);
   GPIO_SetOutput(GPIO5, GPIO_BIT1);
   GPIO_SetOutput(GPIO5, GPIO_BIT4);
   GPIO_SetLow(GPIO5,GPIO_BIT0);
   GPIO_SetLow(GPIO5,GPIO_BIT1);
   GPIO_SetLow(GPIO5,GPIO_BIT4);
   OLED_Init();
   OLED_Clear(); 
   OLED_ShowString(0,0," HELLO WORLD !  ",16);
   OLED_ShowString(0,2,"                ",16);
   OLED_ShowCHinese(8,2,0);
   OLED_ShowCHinese(24,2,1);
   while (1);
}

程序的编译和下载其测试效果如图3所示。

image.png

图3 测试效果










关键词: AG32VH407    

高工
2026-04-14 07:37:07     打赏
2楼

image.png

内容高度重合。


高工
2026-04-15 08:05:31     打赏
3楼

鼓励原创首发


专家
2026-04-15 08:38:31     打赏
4楼

前两天拆机看到一个磨皮芯片,估计就是楼主说的这颗,学习了


专家
2026-04-15 10:09:00     打赏
5楼

楼主辛苦,谢谢分享!


共5条 1/1 1 跳转至

回复

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