【感芯科技MC3172开发板体验】+点阵板的显示驱动 - RISC-V MCU技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

[文章]

【感芯科技MC3172开发板体验】+点阵板的显示驱动

点阵屏有多种构成形式,其中一种是以8x8的点阵块来构建,另一种这是采用点阵板来构成。相对于点阵块的构成方式,使用点阵板的方式应该在价格方面更划算。为此这里选用的是一款红色的P4.75点阵板,其显示规格为16*64点阵,它的外观如图1所示。

image.png

图1 点阵板外观

该点阵板采用的接口方式为HUB08,其引脚的名称与排列方式如图2所示。

image.png

图2 HUB08接口

该点阵板与开发板的连接关系为:

A---PA2

B---PA3

C---PA4

D---PA5

R1 ---PA0

OE ---PA6

LAT ---PA7

CLK---PA1

所用引脚输出高低电平的语句定义为:

#define LR1_high
GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN0)

#define LR1_low GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN0)

#define CLK_high
GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN1)

#define CLK_low
GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN1)

#define LA_high GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN2)

#define LA_low
GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN2)

#define LB_high
GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN3)

#define LB_low
GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN3)

#define LC_high GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN4)

#define LC_low
GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN4)

#define LD_high
GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN5)

#define LD_low
GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN5)

#define LEN_high
GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN6)

#define LEN_low
GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN6)

#define LSTB_high
GPIO_SET_OUTPUT_PIN_TO_1(GPIOA_BASE_ADDR,GPIO_PIN7)

#define LSTB_low GPIO_SET_OUTPUT_PIN_TO_0(GPIOA_BASE_ADDR,GPIO_PIN7)

对相关引脚的工作模式配置函数为:

void dzb_Init(void)
{  
INTDEV_SET_CLK_RST(GPIOA_BASE_ADDR,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV2));  
GPIO_SET_OUTPUT_EN_VALUE(GPIOA_BASE_ADDR,(GPIO_PIN_7_0),GPIO_SET_ENABLE);
}

点阵板发送16位数据的函数为:

void OutByte(uint16_t dat)
{   
uint8_t i=0 ;   
for(i=0;i<16;i++)
{       
CLK_low;       
if(dat&0x8000)       
{           
LR1_high;       
}       
else       
{           
LR1_low;       
}       
dat=dat<<1;       
CLK_high;
}
}

发送多列数据的函数为:

void DisCol(uint16_t dat,uint16_t len)
{   
while(len--)
{
       OutByte(dat); 
}
}

其行地址的输出函数为:

void SeleRow(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;
}

实现竖线绘制的检测函数为:

void Display(void)
{
           DisCol(0x5555,4);
           LEN_high;
           LSTB_high;
           LSTB_low;     
           SeleRow(ScanRow);     
           LEN_low;     
           ScanRow++;
           if(ScanRow>15)  ScanRow=0;
}

在线程0中,实现图3所示效果的程序为:

void thread0_main(void)
{   
ScanRow=0;   
dzb_Init();  
while(1){
        Display();   
}   
thread_end();
}

image.png

图3测试效果

有了前面的驱动测试结果,就可进行中文显示功能的添加了。

所配置的字库结构为:

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,/1/

0x00,0x02,0x00,0x01,0xFE,0x7F,0x42,0x44,0xF4,0x9F,0x40,0x04,0xF8,0x3F,0x40,0x04,

0xFE,0xFF,0x20,0x08,0x10,0x13,0x88,0x20,0x46,0xC0,0x00,0x06,0x80,0x01,0x40,0x00,/2/

0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,

0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0xF8,0x3F,0x08,0x00,0x00,0x00,/3/

...

}

发送多列数据的函数为:

void DisCol(uint16_t lenght)
{   
uint16_t dat;   
uint8_t m=0;  //  远上寒山石径斜白云深处有人家   
while(lenght--)   
{         
dat=(V[m*32+ScanRow*2+1]<<8)+V[m*32+ScanRow*2];         
OutByte(dat);         
m=m+1;   
}
}

实现相应汉字显示的函数为:

void Display(void)
{     
DisCol(4);     
LEN_high;     
LSTB_high;     
LSTB_low;     
SeleRow(ScanRow);     
LEN_low;     
ScanRow++;     
if(ScanRow>15)  ScanRow=0;
}

在线程0中,实现图4所示效果的程序为:

void thread0_main(void)
{   
ScanRow=0;   
dzb_Init();   
while(1){
        Display();   
}   
thread_end();
}

image.png

图4中文显示效果

为实现数字符号的显示,需配置相应的显示字模,其存储结构为:

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,0x3C,0x42,0x42,0x20,0x18,0x20,0x40,0x40,0x42,0x22,0x1C,0x00,0x00,/"3",3/

0x00,0x00,0x00,0x20,0x30,0x28,0x24,0x24,0x22,0x22,0x7E,0x20,0x20,0x78,0x00,0x00,/"4",4/

0x00,0x00,0x00,0x7E,0x02,0x02,0x02,0x1A,0x26,0x40,0x40,0x42,0x22,0x1C,0x00,0x00,/"5",5/

0x00,0x00,0x00,0x38,0x24,0x02,0x02,0x1A,0x26,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/"6",6/

0x00,0x00,0x00,0x7E,0x22,0x22,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,/"7",7/

0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,/"8",8/

0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x64,0x58,0x40,0x40,0x24,0x1C,0x00,0x00,/"9",9/

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,

};

发送16位数据的函数为:

void OutByte(u16 dat)
{
    u8 i=0 ;
    for(i=0;i<16;i++)
    {
        CLK_low;
        if(dat&0x0001)
        {
            LR1_high;
        }
        else
        {
            LR1_low;
        }
        dat=dat>>1;
        CLK_high;
    }
}

发送多列数据的函数为:

void DisCol(u16 lenght)
{
    u16 dat;
    u8 m=0;
    u8 sj[]={0x01,0x02,0x0A,0x03,0x00,0x0A,0x03,0x00}; // 存放显示内容 0~9:- a~zA~Z
    while(lenght--)
    {              
               dat=(S[sj[m+1]*16+ScanRow]<<8)+S[sj[m]*16+ScanRow];
               OutByte(dat);
               m=m+2;
    }
}

在线程0中,实现图5所示效果的程序为:

void thread0_main(void)
{   
ScanRow=0;   
dzb_Init();   
while(1){
        Display();   
}   
thread_end();
}

image.png

图5数值显示效果

由于这款多线程开发板并没有提供RTC这样的功能,故要实现电子时钟功能还需外挂相应的RTC功能模块。

更多回帖

×
发帖