点阵屏有多种构成形式,其中一种是以8x8的点阵块来构建,另一种这是采用点阵板来构成。相对于点阵块的构成方式,使用点阵板的方式应该在价格方面更划算。为此这里选用的是一款红色的P4.75点阵板,其显示规格为16*64点阵,它的外观如图1所示。
图1 点阵板外观
该点阵板采用的接口方式为HUB08,其引脚的名称与排列方式如图2所示。
图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();
}
图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();
}
图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};
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();
}
图5数值显示效果
由于这款多线程开发板并没有提供RTC这样的功能,故要实现电子时钟功能还需外挂相应的RTC功能模块。