本帖最后由 jinglixixi_457498010 于 2023-7-13 09:21 编辑

在通常的情况下,我们所所用的显示器件多是数码管、液晶屏、OLED屏及TFT屏。但在公共场合要显示信息,就要有较大尺寸以便观察。
通常多使用半板来拼接成较大的广告牌,这里使用的是一款P4.75的红色点阵板,其显示分辨率为16*64像素点。

image.png
图1 点阵屏外观

该点阵屏采用的接口方式为HUB08,各引脚的名称如图2所示。
image.png
图2  HUB08接口

该点阵屏与开发板的连接关系为:
A---PB4
B---PB5
C---PA6
D---PB7
R1 ---PC2
OE ---PC3
LAT ---PC1
CLK---PC0

所用引脚输出高低电平的语句定义为:
#define LA_high   gpio_set_level(GPIO_PB4, 1) // A
#define LA_low    gpio_set_level(GPIO_PB4, 0)
#define LB_high   gpio_set_level(GPIO_PB5, 1) // B
#define LB_low    gpio_set_level(GPIO_PB5, 0)
#define LC_high   gpio_set_level(GPIO_PB6, 1) // C
#define LC_low    gpio_set_level(GPIO_PB6, 0)
#define LD_high   gpio_set_level(GPIO_PB7, 1) // D
#define LD_low    gpio_set_level(GPIO_PB7, 0)
#define LR1_high  gpio_set_level(GPIO_PC2, 1) // R1
#define LR1_low   gpio_set_level(GPIO_PC2, 0)
#define CLK_high  gpio_set_level(GPIO_PC0, 1) // CLK
#define CLK_low   gpio_set_level(GPIO_PC0, 0)
#define LEN_high  gpio_set_level(GPIO_PC3, 1) // CS
#define LEN_low   gpio_set_level(GPIO_PC3, 0)
#define LSTB_high  gpio_set_level(GPIO_PC1, 1) // STB
#define LSTB_low   gpio_set_level(GPIO_PC1, 0)

所用引脚的初始化函数为:
void gpio_init (void)
  • {
  •         gpio_function_en(GPIO_PB4);
  •         gpio_output_en(GPIO_PB4);
  •         gpio_function_en(GPIO_PB5);
  •         gpio_output_en(GPIO_PB5);
  •         gpio_function_en(GPIO_PB6);
  •         gpio_output_en(GPIO_PB6);
  •         gpio_function_en(GPIO_PB7);
  •         gpio_output_en(GPIO_PB7);
  •         gpio_function_en(GPIO_PC0);
  •         gpio_output_en(GPIO_PC0);
  •         gpio_function_en(GPIO_PC1);
  •         gpio_output_en(GPIO_PC1);
  •         gpio_function_en(GPIO_PC2);
  •         gpio_output_en(GPIO_PC2);
  •         gpio_function_en(GPIO_PC3);
  •         gpio_output_en(GPIO_PC3);
  • }
  • 复制代码
    1. 电子时钟为实现数字符号的显示,以字模提取软件所构建的字库存储结构为:
    uint8_t S[]={
  • 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"0",0*/
  • 0x00,0x00,0x00,0x08,0x0E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00,/*"1",1*/
  • 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x20,0x20,0x10,0x08,0x04,0x42,0x7E,0x00,0x00,/*"2",2*/
  • ...
  • 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,/*":",10*/
  • 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"-",11*/
  • 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  • };
  • 复制代码
    点阵板发送数据的函数为:
    voidOutByte (u16 dat)
  • {
  •     u8 i=0 ;
  •     for(i=0;i<16;i++)
  •     {
  •         CLK_low;
  •         if(dat&0x0001)
  •         {
  •             LR1_high;
  •         }
  •         else
  •         {
  •             LR1_low;
  •         }
  •         dat=dat>>1;
  •         delay_us(10);
  •         CLK_high;
  •         delay_us(10);
  •     }
  • }
  • 复制代码
    输出行地址的函数为:
    voidSeleRow(uint8_t Nd)
  • {
  •     uint8_t N;
  •     N=Nd;
  •     N=N%16;
  •     if(N&0x01)   LA_high;
  •     else  LA_low;
  •     if (N&0x02)  LB_high;
  •     else  LB_low;
  •     if (N&0x04)  LC_high;
  •     else  LC_low;
  •     if (N&0x08)  LD_high;
  •     else  LD_low;
  • }
  • 复制代码
    发送多列数据的函数为:
    voidDisCol (u16 lenght)
  • {
  •     u16 dat;
  •     uint8_t ml=0;
  •     while(lenght--)
  •     {
  •           dat=(S[sj[ml+1]*16+ScanRow]<<8)+S[sj[ml]*16+ScanRow];
  •           OutByte (dat);
  •           ml=ml+2;
  •     }
  • }
  • 复制代码
    实现显示输出的函数为:
    voidDisplay_B(void)
  • {
  •     DisCol_B(4);
  •     LEN_high;
  •     LSTB_high;
  •     LSTB_low;
  •     SeleRow(ScanRow);
  •     LEN_low;
  •     ScanRow++;
  •     if(ScanRow>15)  ScanRow=0;
  • }
  • 复制代码
    由于Telink B91没有专用的RTC计时器,故要在显示刷新中实现计时处理,只能通过计算显示的耗时来推算出一个秒计时器来替代RTC的作用。实现图2所示的计时效果,其主程序为:
    int main (void)
  • {
  •         unsignedint i=0,h=8,m=30,s=0;
  •         sys_init(LDO_1P4_LDO_1P8, VBAT_MAX_VALUE_GREATER_THAN_3V6);
  •         user_read_flash_value_calib();
  •         CCLK_24M_HCLK_24M_PCLK_24M;
  •         user_init();
  •         delay_ms(1000);
  •         ScanRow=0;
  •         gpio_init (void)
  •         delay_ms(100);
  •         while (1) {
  •         for(i=0;i<500;i++)
  •         {
  •                     Display ();
  •         }
  •         s=s+1;
  •         if(s==60)
  •         {
  •                  s=0;
  •                  m=m+1;
  •         }
  •         sj[6]=s/10;
  •         sj[7]=s%10;
  •         if(m==60)
  •         {
  •                  m=0;
  •                  h=h+1;
  •         }
  •         sj[3]=m/10;
  •         sj[4]=m%10;
  •         if(h==60)
  •         {
  •                  h=0;
  •         }
  •         sj[0]=h/10;
  •         sj[1]=h%10;
  •         }
  •         return 0;
  • }
  • 复制代码
    image.png
    图2 电子时钟


    2. 汉字显示为实现汉字的显示,以字模提取软件所构建的字库存储结构为:
    uint8_t V[]={
  • //远上寒山石径斜白云生处有人家...
  • 0x00,0x00,0xF8,0x23,0x00,0x10,0x00,0x10,0x00,0x00,0xFC,0x07,0x20,0xF1,0x20,0x11,
  • 0x20,0x11,0x20,0x11,0x24,0x11,0x24,0x12,0x24,0x12,0x1C,0x14,0x00,0x28,0xFE,0x47,// 0
  • 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0xF8,0x03,0x00,0x02,
  • 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0xFE,0xFF,0x00,0x00,
  • ...  
  • };
  • 复制代码
    点阵板发送数据的函数为:
    voidOutByte(uint16_t dat)
  • {
  •     uint8_t i=0 ;
  •     for(i=0;i<16;i++)
  •     {
  •         CLK_low;
  •         delay_us(10);
  •         if(dat&0x8000)
  •         {
  •             LR1_high;
  •         }
  •         else
  •         {
  •             LR1_low;
  •         }
  •         dat=dat<<1;
  •         delay_us(10);
  •         CLK_high;
  •     }
  • }
  • 复制代码
    发送多列数据的函数为:
    voidDisCol (uint16_t lenght)
  • {
  •     uint16_t dat;
  •     uint8_t m=8;
  •     m=mm;
  •     while(lenght--)
  •     {
  •           dat=(V[m*32+ScanRow*2+1]<<8)+V[m*32+ScanRow*2];
  •           OutByte(dat);
  •           m=m+1;
  •     }
  • }
  • 复制代码
    实现显示输出的函数为:
    voidDisplay (void)
  • {
  •     DisCol (4);
  •     LEN_high;
  •     LSTB_high;
  •     LSTB_low;
  •     SeleRow(ScanRow);
  •     LEN_low;
  •     ScanRow++;
  •     if(ScanRow>15)  ScanRow=0;
  • }
  • 复制代码
    受显示板显示规格的限制,要显示一首唐诗,必须通过分屏显示来完成,或通过屏幕滚动的方式来实现。这里采用的是多屏显示的方式,其实现图3所示效果的主程序为:
    int main (void)
  • {
  •         unsignedint i=0;
  •         sys_init(LDO_1P4_LDO_1P8, VBAT_MAX_VALUE_GREATER_THAN_3V6);
  •         user_read_flash_value_calib();
  •         CCLK_24M_HCLK_24M_PCLK_24M;
  •         user_init();
  •         delay_ms(100);
  •         ScanRow=0;
  •         delay_ms(100);
  •         while (1) {
  •         for(i=0;i<1500;i++)
  •         {
  •                     Display ();
  •         }
  •         mm=(mm+4)%32;
  •         }
  •         return 0;
  • }
  • 复制代码

    image.png
    图3 汉字显示效果