跟上一篇的显示一行多个汉字差不多,只是多加了几行代码(彩色部分)和字模
#include <NXP/iolpc2148.h>
//管脚宏定义#define SCLK 0x01<<24 //595时钟端
#define MISO 0x01<<5 //数据输入端
#define MOSI 0x01<<6 //数据输出端
#define RCK 0x01<<7 //SO12864时钟输入端
//LCD Define
#define LCD_A 1<<30 //命令数据选择端,高电平:数据 低电平:命令
#define LCD_CLK 1<<4 //时钟端
#define LCD_DATA MOSI //数据端
#define B_LED 1<<13 //背光
#define Sclk_L() IO0CLR |=LCD_CLK //时钟高电平
#define Sclk_H() IO0SET |=LCD_CLK //时钟低电平
#define Res_L() HC595_DATA &=~(1<<2);Write595() //复位低电平
#define Res_H() HC595_DATA |=(1<<2); Write595() //复位高电平
#define Data_L() IO0CLR |=LCD_DATA //数据低电平
#define Data_H() IO0SET |=LCD_DATA //数据高电平
#define CS_L() HC595_DATA &=~1; Write595() //片选低电平
#define CS_H() HC595_DATA |=1; Write595() //片选高电平
#define Write_C() IO0CLR |=LCD_A //选择写命令
#define Write_D() IO0SET |=LCD_A //选择写数据
#define Writecommand
//#define pgm_read_byte
//#define LcdCls
//函数声明
void Delayn(unsigned long n);
void Write595();
void HC595_Init(void);
void Lcd_Init(void);
void Lcd_display_HZ(unsigned char x,unsigned char y,unsigned char *p);
void LcdCls(unsigned char data);
void Setxy(unsigned char x,unsigned char y);
void show_string1616(unsigned char x,unsigned char y,unsigned *string,unsigned char string_lenth);
//全局变量
unsigned int HC595_DATA=0xFFFFFFFF;
unsigned int title[]={6,5,0,7,2}; //"亚楠我爱你",取的值是由模中各个字所在的位置决定的
unsigned char HZ[][32]=
{{0x20,0x24,0x24,0x24,0xFE,0x23,0x22,0x20,0xFF,0x20,0x22,0xAC,0x20,0x30,0x20,0x00,
0x00,0x08,0x48,0x84,0x7F,0x02,0x21,0x10,0x09,0x06,0x1A,0x61,0x80,0xE0,0x00,0x00}, //"我"(0)
{0x00,0xFC,0xFC,0x84,0x84,0xFE,0xFE,0x14,0x90,0x10,0x10,0xFF,0xFF,0x10,0x18,0x00,
0x00,0x3F,0x1F,0x10,0x10,0x3F,0x3F,0x00,0x00,0x23,0x60,0xFF,0x7F,0x00,0x00,0x00}, //时(1)
{0x40,0x20,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,0x00,
0x00,0x00,0xFF,0x00,0x00,0x08,0x04,0x43,0x80,0x7F,0x00,0x01,0x06,0x0C,0x00,0x00}, //"你"(2)
{0x00,0x20,0x18,0xCF,0xC7,0x44,0x44,0xFC,0xFC,0x44,0x44,0x64,0x46,0x04,0x00,0x00,
0x04,0x04,0x04,0x07,0x07,0x04,0x04,0xFF,0xFF,0x04,0x04,0x04,0x04,0x06,0x04,0x00}, //年(3)
{0x00,0x00,0x00,0x00,0xFF,0xFE,0x22,0x22,0x22,0x22,0x22,0xFF,0xFE,0x04,0x00,0x00,
0x00,0x80,0x40,0x70,0x1F,0x07,0x02,0x02,0x02,0x42,0x42,0xFF,0x7F,0x00,0x00,0x00}, //月(4)
{0x10,0x90,0xFF,0x50,0x98,0xC8,0x48,0xC8,0x48,0x7F,0x48,0xC8,0x48,0xEC,0x48,0x00,
0x02,0x01,0xFF,0x00,0x00,0xFF,0x10,0x12,0x13,0x7E,0x13,0x52,0x90,0x7F,0x00,0x00}, //"楠"(5)
{0x00,0x42,0x82,0x02,0x02,0xFE,0x02,0x02,0x02,0xFE,0x02,0x02,0xC3,0x82,0x00,0x00,
0x40,0x40,0x41,0x46,0x40,0x7F,0x40,0x40,0x40,0x7F,0x44,0x43,0x40,0x60,0x40,0x00}, //"亚"(6)
{0x40,0xB0,0x92,0x96,0x9A,0x92,0xF2,0x9E,0x92,0x91,0x99,0x95,0x91,0x50,0x30,0x00,
0x00,0x00,0x40,0x30,0x8C,0x83,0x46,0x2A,0x12,0x2A,0x26,0x42,0xC0,0x40,0x00,0x00}, //"爱"(7)
{0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFF,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x7F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7F,0x00,0x00,0x00,0x00}, //"日"(8)
{0x00,0xFC,0x84,0x84,0x84,0xFE,0x14,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x23,0x40,0x80,0x7F,0x00,0x00,0x00}, //"时"(9)
{0x00,0x80,0x40,0x20,0x98,0x86,0x80,0x80,0x83,0x8C,0x90,0x20,0xC0,0x80,0x80,0x00,
0x01,0x00,0x80,0x40,0x20,0x1F,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x01,0x00,0x00}, //"分"(10)
{0x20,0x24,0x24,0xA4,0xFE,0xA3,0x22,0x80,0x70,0x00,0xFF,0x00,0x10,0x20,0x60,0x00,
0x10,0x08,0x06,0x01,0xFF,0x00,0x81,0x80,0x40,0x20,0x17,0x08,0x04,0x03,0x00,0x00}, //"秒"(11)
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, //"一"(12)
{0x40,0x48,0x48,0x48,0xFF,0x48,0x48,0x00,0xC4,0x44,0x44,0x44,0xFE,0x04,0x00,0x00,
0x40,0x20,0x1F,0x20,0x7F,0x42,0x42,0x40,0x47,0x48,0x48,0x48,0x48,0x6E,0x20,0x00}, //"起"(13)
{0x00,0x04,0x24,0x24,0x24,0x24,0x24,0xFC,0x22,0x22,0x22,0x33,0x22,0x00,0x00,0x00,
0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x00}, //"手"(14)
{0x10,0x10,0x10,0xFF,0x90,0x50,0x08,0xE8,0x09,0x0E,0x08,0x08,0xEC,0x08,0x00,0x00,
0x02,0x42,0x81,0x7F,0x00,0x40,0x40,0x40,0x4F,0x60,0x58,0x47,0x40,0x60,0x40,0x00}, //"拉"(15)
{0x40,0x20,0xF8,0x07,0x00,0xF8,0x02,0x04,0x08,0x04,0x04,0x04,0x04,0xFE,0x04,0x00,
0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00}, //"们"(16)
{0x40,0x40,0x48,0x48,0x48,0x48,0x7F,0xC8,0x4C,0x68,0x50,0x48,0x4C,0x60,0x40,0x00,
0x40,0x20,0x10,0x08,0x04,0x7E,0x91,0x90,0x88,0x88,0x84,0x86,0x80,0xE0,0x00,0x00}, //"老"(17)
{0x00,0x84,0xC9,0x22,0x06,0x80,0x7E,0x12,0x32,0x52,0x9F,0x52,0x32,0x0A,0x06,0x00,
0x04,0x04,0x87,0x84,0x4D,0x54,0x26,0x24,0x26,0x55,0x4C,0x85,0x06,0x06,0x04,0x00}, //"婆"(18)
};
//主函数
int main(void)
{
HC595_Init(); //初始化74HC595
IO0DIR |=LCD_A|B_LED|LCD_CLK; //初始化IO口
Lcd_Init(); //初始化液晶屏
LcdCls(0x00);//清屏
Delayn(10000000);
show_string1616(16,0,title,5);
Lcd_display_HZ(24,2,HZ[3]); //在第2页,第24列开始显示一个"年"
//Lcd_display_HZ(64,2,HZ[4]); //显示一个"月"
//Lcd_display_HZ(104,2,HZ[8]);//显示一个"日"
//Lcd_display_HZ(36,4,HZ[9]); //显示一个"时"
//Lcd_display_HZ(76,4,HZ[10]); //显示一个"分"
//Lcd_display_HZ(104,4,HZ[11]);//显示一个"秒"
Lcd_display_HZ(24,2,HZ[0]); //显示一个"我"
Lcd_display_HZ(40,2,HZ[16]); //显示一个"们"
Lcd_display_HZ(56,2,HZ[12]); //显示一个"一"
Lcd_display_HZ(72,2,HZ[13]); //显示一个"起"
Lcd_display_HZ(32,4,HZ[14]); //显示一个"手"
Lcd_display_HZ(48,4,HZ[15]); //显示一个"拉"
Lcd_display_HZ(64,4,HZ[14]); //显示一个"手"
while(1); //stop
}
//初始化595接口
void HC595_Init(void)
{
IO0DIR |= MOSI|RCK;
IO1DIR |= SCLK;
IO1CLR |= SCLK;
IO0DIR |= RCK;
HC595_DATA =0xFFFFFFFF;Write595();
}
//写字节
void WriteByte(unsigned char data)
{
unsigned char i;
//IO0CLR;
for(i=0;i<8;i++)
{
if(data&0x01) IO0SET=MOSI;
else IO0CLR =MOSI;
IO1SET=SCLK;
data>>=1;
IO1CLR=SCLK;
}
//IO0SET=RCK;
}
//刷新595的数据
void Write595()
{
IO0CLR=RCK;
WriteByte(HC595_DATA&0xff);
WriteByte((HC595_DATA&0xff00)>>8);
WriteByte((HC595_DATA&0xff0000)>>16);
WriteByte((HC595_DATA&0xff000000)>>24);
IO0SET=RCK;
}
//延时周期数
void Delayn(unsigned long n)
{
while(n--);
}
//向SPI总线上写一个字节的数据
void LCDWriteByte(unsigned char data)
{
unsigned char i,s;
s=data;
for(i=0;i<8;i++)
{ //Delayn(1000000); //自己加的
if(s&0x80) Data_H();
else Data_L();
Sclk_H();
s<<=1;
Sclk_L();
}
}
//向液晶屏写数据
void WriteData(unsigned char Data)
{
Write_D();
CS_L();
LCDWriteByte(Data);
CS_H();
}
//向液晶屏写命令
void WriteCommand(unsigned char Command)
{
Write_C();
CS_L();
LCDWriteByte(Command);
CS_H();
}
//打开液晶背光 0:关闭 1:打开
void Lcd_BackLed(unsigned char on)
{
if(on==1)
{
IO0CLR=B_LED; //打开背光
}
else if(on==0)
{
IO0SET=B_LED; //关闭背光
}
}
//液晶复位
void Lcd_Reset(void)
{
Res_L();
Delayn(10000000);
Res_H();
}
//列顺序翻转,左右翻转 0:正常 1:翻转
void Lcd_ColRev(unsigned char i)
{
WriteCommand(0xa0|(i&0x01));
}
//清屏
void LcdCls(unsigned char data)
{
unsigned char i,j;
for(i=0;i<9;i++)
{
Setxy(0,i);
for(j=0;j<128;j++)
{
WriteData(data);
}
}
}
//液晶初始化
void Lcd_Init(void)
{
Lcd_Reset(); //液晶复位
//Lcd_BackLed(0);
Lcd_BackLed(1); //打开液晶背光
WriteCommand(0xaf); //打开显示
WriteCommand(0x40); //指定显示RAM的行地址,起始行为:0然后63,62,....2,1依次减小
WriteCommand(0xa1); //ADC正常???
WriteCommand(0xa6); //没有反白,正常显示
WriteCommand(0xa4); //全屏显示
WriteCommand(0xa2); //设置LCD的偏压比
WriteCommand(0xc0); //正常:意思是下端为0,往上依次为63,62....
WriteCommand(0x2f); //电源设置
WriteCommand(0x24); //粗调对比度
WriteCommand(0x81); //
WriteCommand(0x24); //后两个相当于细调对比度
Lcd_ColRev(1); //左右翻转
}
//选择列x,页y
void Setxy(unsigned char x,unsigned char y)
{
unsigned char tmp=0;
y=y&0x0F; //把页号变换为0XB0……0XB7的页定位码
y=y|0xb0;
tmp=x;
tmp>>=4; //变换出列号的定位码高低4位
tmp|=0x10;
x&=0x0F;
WriteCommand(y); //写页定位码
WriteCommand(tmp);//写列定位码(高)
WriteCommand(x); //写列定位码(低)
}
//显示汉字 x是列,y是页,p指向字模数组
void Lcd_display_HZ(unsigned char x,unsigned char y,unsigned char *p) //p是汉字的首地址
{
unsigned char i;
WriteCommand(0xa4);
Setxy(x,y); //起始列,页
for(i=0;i<16;i++)
{
WriteData(*p++);//显示上半个汉字
}
y+=1;
Setxy(x,y); //到下页起点
for(i=16;i<32;i++)
{
WriteData(*p++); //显示下半个汉字
}
}
//16点阵字串显示string_lenth个HANZ[j]
void show_string1616(unsigned char x,unsigned char y,unsigned *string,unsigned char string_lenth)
{
unsigned char i,j;
for(i=0;i<string_lenth;i++)
{
j=*string;
Lcd_display_HZ(x,y,HZ[j]);
string++;
x+=16;
if(x>=128) //跳到下一页
{
x=0;
y+=1;
}
}
}