屏幕是标准40pin的RGB接口屏,频率22.1184Mhz,用DE模式驱动,本来单纯想学学这种屏幕的时序,没想到显示个汉字啥的,还能接受,因为是用24位RGB,所以用的32bit模式,8位対long的兼容不好,程序写的不好,希望大家指正。
为了显示汉字,数字之类的,实在不知道怎么写这个函数,因为每次都要全屏刷新像素,就用了最粗暴的方式,建立整屏缓存,然后把需要显示的汉字或者数字数组,替换掉全屏缓存内对应的字节。
#include <AI8051U.H>
#include "intrins.h"
// 引脚定义
sbit CLK = P5^7;
sbit DE = P4^0;
//sbit DISP = P1^5;
sbit LED = P5^6;
#define port_r P1
#define port_g P0
#define port_b P2
// 屏幕参数
#define H_ACTIVE 480 // 水平有效像素
#define V_ACTIVE 272 // 垂直有效行数
#define H_BLANK 45 // 水平消隐期(前廊+同步+后廊)
#define V_BLANK 14 // 垂直消隐期(前廊+同步+后廊)
#define H_TOTAL (H_ACTIVE + H_BLANK)
#define V_TOTAL (V_ACTIVE + V_BLANK)
#define FOSC 22118400UL
#define BRT (65536 - FOSC / 115200 / 4)
#define bai 0xffffff
#define hong 0xff0000
#define lv 0x00ff00
#define huang 0xffff00
#define hei 0x000000
#define qianhuang 0xffffbe
#define lan 0x0000ff
unsigned char xdata full[16320]={0};
unsigned char xdata shan[128]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x10,0x18,0x00, /* 0 */
0x0f,0xf8,0x18,0x00,0x0c,0x30,0x18,0x00,0x0c,0x20,0x18,0x60,0x0c,0x67,0xff,0xf0,
0x0c,0x40,0x18,0x00,0x04,0x40,0x18,0x00,0x04,0x82,0x18,0xc0,0x04,0x83,0x10,0xc0,
0x04,0x83,0x10,0x80,0x04,0x41,0x91,0x00,0x04,0x21,0x91,0x00,0x04,0x11,0x12,0x00,
0x04,0x10,0x10,0x10,0x04,0x1f,0xff,0xf8,0x04,0x18,0x34,0x00,0x04,0x18,0x34,0x00,
0x07,0xf0,0x24,0x00,0x04,0xe0,0x62,0x00,0x0c,0x00,0x43,0x00,0x0c,0x00,0xc1,0x00,
0x0c,0x01,0x81,0xc0,0x0c,0x03,0x00,0xe0,0x0c,0x06,0x00,0x78,0x0c,0x18,0x00,0x30,
0x08,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
unsigned char xdata xi[128]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, /* 1 */
0x1f,0xff,0xff,0xf0,0x00,0x0c,0x30,0x00,0x00,0x0c,0x30,0x00,0x00,0x0c,0x30,0x00,
0x00,0x0c,0x30,0x00,0x04,0x0c,0x30,0x40,0x07,0xff,0xff,0xf0,0x06,0x0c,0x30,0x60,
0x06,0x0c,0x30,0x60,0x06,0x0c,0x30,0x60,0x06,0x0c,0x30,0x60,0x06,0x08,0x30,0x60,
0x06,0x08,0x30,0x60,0x06,0x18,0x30,0x60,0x06,0x10,0x31,0x60,0x06,0x30,0x1f,0xe0,
0x06,0x20,0x00,0x60,0x06,0x40,0x00,0x60,0x06,0x80,0x00,0x60,0x06,0x00,0x00,0x60,
0x07,0xff,0xff,0xe0,0x06,0x00,0x00,0x60,0x06,0x00,0x00,0x60,0x04,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
unsigned char xdata sheng[128]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x80,0x00, /* 2 */
0x00,0x41,0x00,0x00,0x00,0x71,0x03,0x80,0x00,0xc1,0x00,0xc0,0x01,0x81,0x0c,0x70,
0x01,0x81,0x1c,0x30,0x03,0x01,0x30,0x30,0x06,0x02,0xe0,0x10,0x08,0x01,0xc0,0x00,
0x10,0x03,0x00,0x00,0x00,0x0e,0x01,0x00,0x00,0x3f,0xff,0x80,0x00,0x70,0x03,0x00,
0x00,0xe0,0x03,0x00,0x07,0x20,0x03,0x00,0x08,0x3f,0xff,0x00,0x00,0x20,0x03,0x00,
0x00,0x20,0x03,0x00,0x00,0x20,0x03,0x00,0x00,0x3f,0xff,0x00,0x00,0x20,0x03,0x00,
0x00,0x20,0x03,0x00,0x00,0x3f,0xff,0x00,0x00,0x20,0x03,0x00,0x00,0x20,0x03,0x00,
0x00,0x20,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
unsigned char xdata shuzi1632[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xc0,0x0e,0x60,0x1c,0x70, /* 0 */
0x38,0x38,0x38,0x38,0x38,0x18,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,
0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x30,0x18,0x38,0x38,0x38,0x38,0x1c,0x70,
0x0e,0x60,0x07,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xc0,0x0f,0xc0, /* 1 */
0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
0x01,0xe0,0x0f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x0c,0x78,0x18,0x38, /* 2 */
0x30,0x1c,0x30,0x1c,0x38,0x1c,0x38,0x1c,0x00,0x1c,0x00,0x38,0x00,0x30,0x00,0x70,
0x00,0xe0,0x01,0xc0,0x03,0x80,0x07,0x00,0x0e,0x00,0x0c,0x0c,0x18,0x0c,0x30,0x1c,
0x3f,0xfc,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0x18,0xf0,0x38,0x70, /* 3 */
0x38,0x38,0x38,0x38,0x38,0x38,0x00,0x38,0x00,0x70,0x00,0xe0,0x03,0xc0,0x00,0x70,
0x00,0x38,0x00,0x18,0x00,0x1c,0x00,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x38,
0x18,0x70,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0xf0, /* 4 */
0x00,0xf0,0x01,0xf0,0x03,0x70,0x03,0x70,0x06,0x70,0x0e,0x70,0x0c,0x70,0x18,0x70,
0x18,0x70,0x30,0x70,0x60,0x70,0x7f,0xfe,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,
0x00,0x70,0x03,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x1f,0xfc,0x18,0x00, /* 5 */
0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x1b,0xe0,0x1e,0x78,0x1c,0x38,
0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x38,0x1c,0x38,0x1c,0x30,0x38,0x30,0x38,
0x1c,0x70,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xe0,0x0e,0x38,0x1c,0x38, /* 6 */
0x18,0x38,0x38,0x00,0x30,0x00,0x30,0x00,0x70,0x00,0x77,0xe0,0x7e,0x70,0x78,0x38,
0x78,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x38,0x1c,0x38,0x18,0x1c,0x38,
0x1e,0x70,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xfc,0x1f,0xfc,0x38,0x18, /* 7 */
0x30,0x30,0x30,0x30,0x00,0x60,0x00,0x60,0x00,0xc0,0x00,0xc0,0x01,0x80,0x01,0x80,
0x01,0x80,0x03,0x00,0x03,0x00,0x03,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x1c,0x70,0x38,0x38, /* 8 */
0x70,0x1c,0x70,0x1c,0x70,0x1c,0x78,0x1c,0x3c,0x38,0x1e,0x30,0x0f,0xe0,0x0f,0xe0,
0x18,0xf0,0x38,0x78,0x70,0x3c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x38,0x38,
0x1c,0x70,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0x1c,0x70,0x38,0x30, /* 9 */
0x38,0x38,0x70,0x18,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x3c,0x38,0x3c,
0x3c,0xfc,0x0f,0xdc,0x00,0x1c,0x00,0x38,0x00,0x38,0x00,0x38,0x38,0x70,0x38,0x70,
0x38,0xe0,0x1f,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
void Delayms(unsigned int x) //@22.1184MHz
{
unsigned long edata i;
while(x--)
{
_nop_();
i = 5528UL;
while (i) i--;
}
}
void UartInit() //定时器1(模式0)做串口1波特率发生器
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = BRT; //设置定时初始值
TH1 = BRT >> 8; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES = 1; //打开串口中断
EA = 1; //打开总中断
}
void UartSend(unsigned char dat) //单片机发送一个字节
{
SBUF = dat;
while(TI==0);
TI=0;
}
void CheckCustomCmd(unsigned char dat) //检测命令序列:"@STCISP#"
{
unsigned char bStage;
switch (bStage++)
{
default:
L_Check1st:
case 0: //检测命令头
bStage = (dat == '@');
break;
case 1:
if (dat != 'S') goto L_Check1st;
break;
case 2:
if (dat != 'T') goto L_Check1st;
break;
case 3:
if (dat != 'C') goto L_Check1st;
break;
case 4:
if (dat != 'I') goto L_Check1st;
break;
case 5:
if (dat != 'S') goto L_Check1st;
break;
case 6:
if (dat != 'P') goto L_Check1st;
break;
case 7:
if (dat != '#') goto L_Check1st;
Delayms(5); //检测到正确的命令序列后复位到系统区,此处的延时可省去
IAP_CONTR = 0x60; //复位到系统区
break;
}
}
void UartSendStr(unsigned char *p)//单片机发送字符串
{
while (*p)
{
UartSend(*p++);
}
}
void Delayus(unsigned int x) //@20.000MHz
{
unsigned long edata i;
while(x--)
{
_nop_();
_nop_();
_nop_();
i = 3UL;
while (i) i--;
}
}
void Full_RGB_Display(unsigned long color)
{
unsigned int line, pixel;
for(line = 0; line < V_ACTIVE; line++) // 逐行显示 272
{
DE = 1; // 行有效期开始
for(pixel = 0; pixel < H_ACTIVE; pixel++) // 生成一行像素时钟 480
{
// Delayus(100);
port_r=color>>16;
port_g=color>>8;
port_b=color;
CLK = 1;
CLK = 0;
}
DE = 0; // 行有效期结束
for(pixel = 0; pixel < H_BLANK; pixel++) // 行消隐期
{
CLK = 1;
CLK = 0;
}
}
// 帧消隐期
for(line = 0; line < V_BLANK; line++)
{
for(pixel = 0; pixel < H_TOTAL; pixel++)
{
CLK = 1;
CLK = 0;
}
}
}
void Simple_RGB_Display(unsigned long x,unsigned long y) //竖向条文
{
unsigned int line, pixel;
unsigned char i;
for(line = 0; line < V_ACTIVE; line++) // 逐行显示 272
{
DE = 1; // 行有效期开始
for(pixel = 0; pixel < 10; pixel++) // 生成一行像素时钟 480
{
for(i = 0; i < 24; i++)
{
port_r=x>>16;
port_g=x>>8;
port_b=x;
CLK = 1;
CLK = 0;
}
for(i = 0; i < 24; i++)
{
port_r=y>>16;
port_g=y>>8;
port_b=y;
CLK = 1;
CLK = 0;
}
}
DE = 0; // 行有效期结束
for(pixel = 0; pixel < H_BLANK; pixel++) // 行消隐期
{
CLK = 1;
CLK = 0;
}
}
// 帧消隐期
for(line = 0; line < V_BLANK; line++)
{
for(pixel = 0; pixel < H_TOTAL; pixel++)
{
CLK = 1;
CLK = 0;
}
}
}
void pic480272(unsigned long x,unsigned long y) //图片
{
unsigned int line, pixel;
unsigned char a,b,i;
for(line = 0; line < V_ACTIVE; line++) // 逐行显示 272
{
DE = 1; // 行有效期开始
for(pixel = 0; pixel < 60; pixel++) // 生成一行像素时钟 480
{
a=full[pixel+(long)(60*line)];
for(i=0;i<8;i++)
{
b=a&0x80;
if(b==0)
{
port_r=y>>16;
port_g=y>>8;
port_b=y;
CLK = 1;
CLK = 0;
}
else
{
port_r=x>>16;
port_g=x>>8;
port_b=x;
CLK = 1;
CLK = 0;
}
a=a<<1;
}
}
DE = 0; // 行有效期结束
for(pixel = 0; pixel < H_BLANK; pixel++) // 行消隐期
{
CLK = 1;
CLK = 0;
}
}
// 帧消隐期
for(line = 0; line < V_BLANK; line++)
{
for(pixel = 0; pixel < H_TOTAL; pixel++)
{
CLK = 1;
CLK = 0;
}
}
}
//void display_3232 (unsigned char x,unsigned char y,unsigned char *p,unsigned long bfcolor, unsigned long bhcolor) //x的范围0-272 y的范围0-60
void display_3232 (unsigned char y,unsigned char x,unsigned char *p)
{
unsigned char i,j;
for(i=0;i<32;i++) //一行480/8个字节
{
for(j=0;j<4;j++) //32*32汉字,汉字一行32/4个字节
{
full[(y*60+x)+(j+i*60)]=p[j+i*4];
}
}
// pic480272(bfcolor,bhcolor);
}
void displayNum_1632 (unsigned char y,unsigned char x,unsigned char a)
{
unsigned char i,j;
unsigned char num;
num=a/100;
for(i=0;i<32;i++) //一行480/8个字节
{
for(j=0;j<2;j++) //16*32数字,数字一行16/8 2个字节
{
full[(y*60+x)+(j+i*60)]=shuzi1632[64*num+j+i*2];
}
}
x=x+2;
num=(a % 100) / 10;
for(i=0;i<32;i++) //一行480/8个字节
{
for(j=0;j<2;j++) //16*32数字,数字一行16/8 2个字节
{
full[(y*60+x)+(j+i*60)]=shuzi1632[64*num+j+i*2];
}
}
x=x+2;
num=a%10;
for(i=0;i<32;i++) //一行480/8个字节
{
for(j=0;j<2;j++) //16*32数字,数字一行16/8 2个字节
{
full[(y*60+x)+(j+i*60)]=shuzi1632[64*num+j+i*2];
}
}
// pic480272(bfcolor,bhcolor);
}
// 主函数
void main(void)
{
unsigned char a;
// P0P1P2口推挽输出
P0M0 = 0xff; //不推挽输出也行
P0M1 = 0x00;
P1M0 = 0xff;
P1M1 = 0x00;
P2M0 = 0xff;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0xc0;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
UartInit();
Delayms(5);
// DISP = 1; // 打开显示 直接接3.3v的时候,可以不要这句
while(1)
{
// 主循环空闲,所有工作由中断处理
// 可以在这里添加其他功能
Full_RGB_Display(hong);
Delayms(300); //整屏显示后,大概可以维持800ms,等待时间再长图像就失真了
Full_RGB_Display(huang); //刷一次屏大概170ms
Delayms(300);
Full_RGB_Display(lan);
Delayms(300);
for(a=0;a<25;a++)
{
display_3232 (10,10,shan);
display_3232 (10,10+4,xi);
display_3232 (10,10+4+4,sheng);
displayNum_1632(10,10+4+4+4,a);
pic480272(huang,hei);
}
LED=~LED;
}
}
void UartIsr() interrupt 4 //串口1中断函数
{
// unsigned char i=0;
if (RI) //接收
{
RI = 0;
CheckCustomCmd(SBUF); //检测串口为指定命令函数
}
// if (TI)
// {
// TI = 0;
// }
} 复制代码
现在有个问题:为啥22MHz左右的频率可以正常显示,30Mhz以上频率就花屏,感觉clk翻转是不是太快了,我在clk=1和clk=0中加入延时,还是不行。
Your browser does not support the video tag