24064液晶屏,控制芯片是T6963C,用以下程序驱动,超过16个汉字就不显示了是什么原因,还有就是怎么显示数字,麻烦大神帮忙修改一下,万分感谢
#include <C8051F020.h> // Register definition file.
#include <stdio.h>
#include<intrins.h>
#define SYSCLK 22118400 //定义系统时钟22.1184MHz
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long ulong;
uint text_size,graphic_size; //定义文本区和图形区宽度
uint text_startaddr,graphic_startaddr; //文本和图形土起始位
uint text_startaddr_l,text_startaddr_h; //定义文本区起始高位低位置
uchar code zk[]={
//*"我"*/
0x04,0x0E,0x78,0x08,0x08,0xFF,0x08,0x08,
0x0A,0x0C,0x18,0x68,0x09,0x0A,0x28,0x10,
0x80,0xA0,0x90,0x90,0x84,0xFE,0x80,0x90,
0x90,0x60,0x40,0xA0,0x20,0x14,0x14,0x0C,
//"爱",
0x00,0x3F,0x11,0x09,0x7F,0x42,0x82,0x7F,
0x04,0x07,0x0A,0x09,0x10,0x11,0x22,0x0C,
0x78,0x80,0x10,0x20,0xFE,0x02,0x04,0xF8,
0x00,0xF0,0x20,0x40,0x80,0x60,0x1C,0x08,
//"家",
0x02,0x01,0x7F,0x40,0x80,0x3F,0x04,0x1A,
0x63,0x05,0x19,0x63,0x05,0x19,0x65,0x02,
0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0x10,
0x30,0x40,0x80,0x40,0x30,0x0E,0x04,0x00,
//"开",
0x00,0x7F,0x08,0x08,0x08,0x08,0x08,0xFF,
0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,
0x08,0xFC,0x20,0x20,0x20,0x20,0x24,0xFE,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
//"心",
0x02,0x01,0x00,0x00,0x08,0x08,0x28,0x28,
0x28,0x48,0x88,0x08,0x08,0x08,0x07,0x00,
0x00,0x00,0x80,0xC0,0x80,0x00,0x08,0x04,
0x02,0x02,0x02,0x00,0x10,0x10,0xF0,0x00,
//"快",
0x10,0x10,0x10,0x10,0x5B,0x54,0x50,0x90,
0x10,0x1F,0x10,0x11,0x11,0x12,0x14,0x18,
0x80,0x80,0x80,0x88,0xFC,0x88,0x88,0x88,
0x88,0xFE,0x80,0x40,0x20,0x10,0x0E,0x04,
//"乐",
0x00,0x00,0x1F,0x10,0x11,0x11,0x21,0x7F,
0x01,0x01,0x09,0x09,0x11,0x21,0x45,0x02,
0x20,0xF0,0x00,0x00,0x00,0x00,0x04,0xFE,
0x00,0x00,0x20,0x10,0x08,0x0C,0x04,0x00,
//"每",
0x10,0x10,0x1F,0x20,0x5F,0x12,0x11,0x10,
0xFF,0x12,0x21,0x20,0x3F,0x00,0x00,0x00,
0x00,0x08,0xFC,0x10,0xF8,0x10,0x10,0x14,
0xFE,0x10,0x10,0x10,0xF8,0x20,0xA0,0x40,
//"一",
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFE,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
//"天",
0x00,0x7F,0x01,0x01,0x01,0x01,0xFF,0x01,
0x02,0x02,0x04,0x04,0x08,0x10,0x20,0xC0,
0x08,0xFC,0x00,0x00,0x00,0x04,0xFE,0x00,
0x80,0x80,0x40,0x40,0x20,0x10,0x0E,0x04,
//"测",
0x00,0x40,0x27,0x24,0x85,0x65,0x25,0x0D,
0x15,0x25,0xE5,0x21,0x22,0x24,0x28,0x20,
0x00,0x44,0xE4,0x54,0x54,0x54,0x54,0x54,
0x54,0x54,0x54,0x04,0x84,0x44,0x54,0x08,
//"试",
0x00,0x40,0x20,0x20,0x0F,0x00,0xE0,0x27,
0x21,0x21,0x21,0x21,0x29,0x37,0x22,0x00,
0x20,0x28,0x24,0x20,0xFE,0x20,0x20,0xE0,
0x20,0x10,0x10,0x10,0xD2,0x12,0x0A,0x04,
//"液",
0x00,0x40,0x37,0x10,0x81,0x61,0x22,0x0A,
0x16,0x2B,0xE2,0x22,0x22,0x22,0x23,0x22,
0x80,0x44,0xFE,0x20,0x20,0x3C,0x44,0x64,
0x98,0x48,0x50,0x20,0x50,0x8E,0x04,0x00,
//"晶",
0x0F,0x08,0x08,0x0F,0x08,0x08,0x0F,0x08,
0x7E,0x42,0x42,0x7E,0x42,0x42,0x7E,0x42,
0xE0,0x20,0x20,0xE0,0x20,0x20,0xE0,0x24,
0xFE,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,
//"程",
0x08,0x1D,0xF1,0x11,0x11,0xFF,0x11,0x38,
0x37,0x54,0x50,0x91,0x10,0x10,0x17,0x10,
0x04,0xFE,0x04,0x04,0x04,0x04,0xFC,0x00,
0xFE,0x20,0x28,0xFC,0x20,0x24,0xFE,0x00,
//"序",
0x01,0x00,0x3F,0x20,0x2F,0x20,0x21,0x20,
0x2F,0x20,0x20,0x20,0x40,0x40,0x82,0x01,
0x00,0x88,0xFC,0x00,0xF8,0x20,0x40,0x80,
0xFC,0x88,0x90,0x80,0x80,0x80,0x80,0x00,
//"非",
0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x7C,
0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,
0x40,0x40,0x44,0x7E,0x40,0x40,0x48,0x7C,
0x40,0x40,0x40,0x44,0x7E,0x40,0x40,0x40,
//"常",
0x01,0x11,0x09,0x7F,0x40,0x8F,0x08,0x0F,
0x01,0x1F,0x11,0x11,0x11,0x11,0x01,0x01,
0x00,0x10,0x20,0xFE,0x02,0xE4,0x20,0xE0,
0x10,0xF8,0x10,0x10,0x10,0x50,0x20,0x00,
//"感",
0x00,0x00,0x7F,0x40,0x7F,0x40,0x5F,0x51,
0x51,0x5F,0x90,0x02,0x29,0x28,0x48,0x07,
0x50,0x48,0xFC,0x40,0xC0,0x48,0x48,0x50,
0x22,0x52,0x8E,0x00,0x90,0xAC,0x24,0xE0,
//"谢",
0x02,0x44,0x2F,0x28,0x0F,0x08,0xEF,0x28,
0x28,0x3F,0x21,0x2A,0x34,0x28,0x12,0x01,
0x08,0x88,0xC8,0x88,0x88,0xFE,0x88,0x88,
0xC8,0xA8,0xA8,0x88,0x88,0x88,0xA8,0x10
};
//外部晶振初始化/////////////////////////////
void SYSCLK_Init ()
{
int i; // 延时计数器
OSCXCN = 0x67; // 开启外部振荡器22.1184MHz晶体
for (i=0; i < 256; i++) ; // 等待振荡器启振
while (!(OSCXCN & 0x80)); // 等待晶体振荡器稳定
OSCICN = 0x88; // 选择外部振荡器为系统时钟源并允许丢失时钟检测器
}
// 交叉开关配置,管脚输入输出配置
void XBR_Init()
{
XBR0 = 0x00; //不配置特殊功能
XBR1 = 0x00;
XBR2 = 0x40; //使能交叉开关,并且总体弱上拉
P74OUT=0xff;
}
/*********************延时函数************************************/
void delay(uint a)
{
uchar b;
for( ;a>0;a--)
for(b=100;b>0;b--);
}
/*******************写命令*****************************************/
void wrcomm(uchar comm)
{
P4=P4|0x01 <<1; //读高电平无效
delay(5);
P4=P4|0x01 <<3; //操作命令
delay(5);
P4=P4&~(0x01 <<0); //写使能
delay(5);
P5=comm; //把命令送给总线
delay(5); //延时
P4=P4|0x01 <<0; //拉高写
}
/*******************写数据******************************************/
void wrdate(uchar date)
{
//读无效
P4=P4|0x01 <<1;
delay(5);
P4=P4&~(0x01 <<3);//操作命令
delay(5);
P4=P4&~(0x01 <<0);//使能写
delay(5);
P5=date; //数据送给总线
delay(5);
P4=P4|0x01 <<0; //拉高写
}
/*******************测读写命令忙***********************************/
void check_sta01()
{
uchar a; //定义变量
P4=P4|0x01 <<0; //禁写
delay(5);
P4=P4|0x01 <<3; //命令有效
delay(5);
while(1)
{
P5=0xff;
delay(5);
P4=P4&~(0x01 <<1); //使能读
delay(5);
a=P5; //读总线状态
delay(5); //延时
P4=P4|0x01 <<1;//拉高读
delay(5);
if((a&0x03)==0x03)
return; //测试如果读写数据为不忙跳出循环
}
}
/*******************测试连续写忙************************************/
void check_sta03()
{
uchar a; //定义变量
P4=P4|0x01 <<0;//禁写
delay(50);
P4=P4|0x01 <<3; //命令有效
delay(5);
while(1)
{
P5=0xff;
delay(5);
P4=P4&~(0x01 <<1); //使能读
delay(5);
a=P5; //读总线状态
delay(5); //延时
P4=P4|0x01 <<1; //拉高读
delay(5);
if((a&0x08)==0x08)
return; //测试如果连续读为不忙跳出循环
}
}
/************************写无参数命令************************************/
void no_parameter(uchar comm)
{
check_sta01(); //测忙
wrcomm(comm); //写命令
}
/************************写双字节参数命令*********************************/
void double_parameter(uint a,uint b,uchar c)
{
check_sta01(); //测忙
wrdate(a); //写第一字节参数
check_sta01(); //测忙
wrdate(b); //写第二节节参数
check_sta01(); //测忙
wrcomm(c); //写命令
}
/************************清屏全亮或全灭***********************************/
void all_display(uchar state,uchar vlue)
{
uint i,k; //定义变量
if(state==0) //判断state是否为0
{
double_parameter(text_startaddr_l,text_startaddr_h,0x24); //文本区低位和高位起始地址
no_parameter(0xb0); //连续写命令
for(i=1;i<9;i++)
{
for(k=0;k<30;k++)
{
check_sta03(); //测忙
wrdate(vlue);
} //写入vlue值,0或1
}
check_sta03(); //测忙
wrcomm(0xb2); //关连续写
}
if(state==1) //判断state是否为1
{
no_parameter(0xb0); //连续写命令
for(i=30*64;i>0;i--) //循环
{
check_sta03(); //测连续写忙
wrdate(vlue); //写入vlue值
}
check_sta03(); //测忙
wrcomm(0xb2); // 关闭连续写
}
}
/****************************文本方式下写8*8字符******************************************/
void text_ascii(uchar *addr,uchar hang,uchar lie)
{
uchar temp;//定义变量
uchar low;
uchar high; //定义变量
temp=30*(hang-1)+(lie-1); //每行30字符乘行加列,计算写入起始位置
low=temp&0x00ff; //把结果低位赋给低变量
high=(temp>>8)&0x00ff; //把结果高位给高变量
double_parameter(low,high,0x24); //写入文本起始位置
no_parameter(0xb0); //连续写命令
check_sta03(); //测忙
wrdate(*addr); //写入字符地址指针
check_sta03(); //测连续写忙
wrcomm(0xb2); //关闭连续写
}
/************************text下显示16*16汉字**********************************************/
/***************text模式下是8*8字符,每个汉字要4个字符组成*********************************/
void hz_display(uchar addr,uchar hang,uchar lie)
{
uint temp; //定义变量
uchar low,high; //定义变量
temp=30*2*(hang-1)+(lie-1)*2; //把字的坐标地址赋给变量
low=temp&0x00ff; //取出坐标低位数值
high=(temp>>8)&0x00ff; //右移8位取出坐标高位数值
double_parameter(low,high,0x24); //写入汉字坐标
no_parameter(0xb0); //开连续写
check_sta03(); //测忙
wrdate(addr); //写入汉字左上4分之1
check_sta03(); //测试忙
wrdate(addr+2); //写入汉字右上4分之1
check_sta03(); //测忙
wrcomm(0xb2); //关闭连续写
delay(1);
temp=30*2*(hang-1)+30+(lie-1)*2; //重新计算汉字坐标也就是写下部份,地址加一行(8*8)
low=temp&0x00ff; //取出低位数值给变量
high=(temp>>8)&0x00ff; //右移8位取出高位给变量
double_parameter(low,high,0x24); //写入新起始地址(写汉字下部份)
no_parameter(0xb0); //连续写命令
check_sta03(); //测忙
wrdate(addr+1); //写入汉字左下4分之1
check_sta03(); //测忙
wrdate(addr+3); //写入汉字右下4分之1
check_sta03(); //测忙
wrcomm(0xb2); //关闭连续写
}
/******************************自定义汉字写入CGRAM***************************************/
void cgram()
{
uint m=0; //定义变量
double_parameter(0x07,0x00,0x22); //设定最高的1K为CGRAM 寄存器偏移设定
double_parameter(0x00,0x3c,0x24); //
no_parameter(0xb0); //开连续写
for(m=0;m<480+32;m++) //循环
{
check_sta03(); //测忙
wrdate(zk[m]); //写入数据
}
check_sta03(); //测忙
wrcomm(0xb2); //关闭连续写
}
/***************************主程序*******************************************************/
void main()
{
uchar i;
WDTCN = 0xde;
WDTCN = 0xad; //禁止看门狗定时器
XBR_Init();
SYSCLK_Init();
P4=P4&~(0x01 <<4); //拉低液晶屏复位脚
delay(10); //延时
P4=P4|0x01 <<4;
delay(10);
text_size=graphic_size=30*64; //文本和图形区宽度
text_startaddr=0x0000; //文本区首地址
text_startaddr_l=text_startaddr; //文本首地址低位
text_startaddr_h=text_startaddr>>8; //文本首地址高位
double_parameter(text_startaddr_l,text_startaddr_h,0x40); //写入文本首地址
double_parameter(30,0x00,0x41); //写入文本区长度(一行几个字节)
double_parameter(30,0x00,0x43); //写入图形区长度(一行几个字节)
// no_parameter(0xa7); //显示8行光标
no_parameter(0x94); //文本开图形关
cgram();
all_display(0,0x00); //清平
hz_display(0x80+(0)*4,4,2); //(第几个字,行地址,列地址)
hz_display(0x80+(1)*4,4,3);
hz_display(0x80+(2)*4,4,4);
hz_display(0x80+(3)*4,4,5);
hz_display(0x80+(4)*4,4,6);
hz_display(0x80+(5)*4,4,7);
hz_display(0x80+(6)*4,4,8);
hz_display(0x80+(7)*4,4,9);
hz_display(0x80+(8)*4,4,10);
hz_display(0x80+(9)*4,4,11);
hz_display(0x80+(10)*4,4,12);
hz_display(0x80+(11)*4,4,13);
hz_display(0x80+(12)*4,4,14);
hz_display(0x80+(13)*4,2,5);
hz_display(0x80+(14)*4,2,6);
hz_display(0x80+(15)*4,2,7);
hz_display(0x80+(16)*4,2,7); //下面这四行就不显示了
hz_display(0x78+(17)*4,2,9);
hz_display(0x76+(18)*4,2,10);
hz_display(0x76+(19)*4,2,11);
while(1);
}
显示效果如图
|