在通常的情况下,我们所所用的显示器件多是数码管、液晶屏、OLED屏及TFT屏。但在公共场合要显示信息,就要有较大尺寸以便观察。
通常多使用半板来拼接成较大的广告牌,这里使用的是一款P4.75的红色点阵板,其显示分辨率为16*64像素点。
图1 点阵屏外观
该点阵屏采用的接口方式为HUB08,各引脚的名称如图2所示。
图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;
- }
图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;
- }
图3 汉字显示效果