我的程序如下
/* 液晶演示程序JLX12864G-086,串行接口!
驱动IC是:UC1701X或兼容的IC,比如ST7565R
叶建人编写,6月27日,2012
晶联讯电子:网址 http://www.jlxlcd.cn;
*/
#include <REG51xD2.H>
#include <intrins.h>
#include <Ctype.h>
sbit Up = P1^0;
sbit Left = P1^2;
sbit Right = P1^3;
sbit cs1 = P0^0 ; //LCM片选信号端
sbit rs = P2^2; //数据命令选择端口
sbit reset = P2^3; //LCM复位
sbit SPISS = P1^1; //SPI总线的从机选择脚 MCU使用
sbit sclk = P1^6; // SCK
sbit sid = P1^7; //sid 就是 SDA,串行数据信号 端口MOSI
sbit LEDA = P0^1; //背光控制,低电平点亮
unsigned char column;
unsigned char page;
void delay(unsigned int i);
void clear_screen();
unsigned char code zhuang1[]={
/*-- 文字: 状 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x08,0x30,0x00,0xFF,0x20,0x20,0x20,0x20,0xFF,0x20,0xE1,0x26,0x2C,0x20,0x20,0x00,
0x04,0x02,0x01,0xFF,0x40,0x20,0x18,0x07,0x00,0x00,0x03,0x0C,0x30,0x60,0x20,0x00};
unsigned char code tai1[]={
/*-- 文字: 态 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x04,0x04,0x04,0x84,0x44,0x34,0x4F,0x94,0x24,0x44,0x84,0x84,0x04,0x00,0x00,
0x00,0x60,0x39,0x01,0x00,0x3C,0x40,0x42,0x4C,0x40,0x40,0x70,0x04,0x09,0x31,0x00};
unsigned char code shi1[]={
/*-- 文字: 使 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x40,0x20,0xF0,0x1C,0x07,0xF2,0x94,0x94,0x94,0xFF,0x94,0x94,0x94,0xF4,0x04,0x00,
0x00,0x00,0x7F,0x00,0x40,0x41,0x22,0x14,0x0C,0x13,0x10,0x30,0x20,0x61,0x20,0x00};
unsigned char code yong1[]={
/*-- 文字: 用 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0xFE,0x00,0x00,
0x80,0x40,0x30,0x0F,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x42,0x82,0x7F,0x00,0x00};
unsigned char code mao_hao[]={
/*-- 文字: : (冒号) --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00};
unsigned char code num0[]={
/*-- 文字: 0 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00
};
char code num1[]={
/*-- 文字: 1 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00
};
char code num2[]={
/*-- 文字: 2 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00
};
unsigned char code num3[]={
/*-- 文字: 3 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00
};
char code num4[]={
/*-- 文字: 4 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00
};
unsigned char code num5[]={
/*-- 文字: 5 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00
};
unsigned char code num6[]={
/*-- 文字: 6 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00
};
unsigned char code num7[]={
/*-- 文字: 7 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00
};
unsigned char code num8[]={
/*-- 文字: 8 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00
};
unsigned char code num9[]={
/*-- 文字: 9 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00
};
unsigned char code empty[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
void SPI_init()
{
SPDAT = 0; //清空数据缓存
SPISS=1; /* enable master */ //片选信号 主机片选信号必须为高电平
SPCON |= 0x10; /* Master mode */
SPCON |= 0x01; /* Fclk Periph/64 */
SPCON &= ~0x08; /* CPOL=0; transmit mode example */
/*因为使用的12864是上升沿写入数据,所以注意CPOL 和CPHA的配置*/
SPCON &= ~0X04; /* CPHA=0; transmit mode example */
SPCON &=~0x20; /* Cleared to enable SS in both Master and Slave modes.*/
IEN1 |= 0x04; /* enable spi interrupt */
SPCON |= 0x40; /* run spi SPEN=1 */
EA=1; /* enable interrupts */
}
unsigned char SPIS_Transfer(unsigned char dat)
{
SPDAT = dat; //trigger SPI send
while (!(SPSTA&0X80)); //wait send complete
return SPDAT; //return received SPI data
}
/*****************************************************/
void Send_byte(unsigned char Byte)
{
SPIS_Transfer(Byte);
}
/***********写指令到LCD模块******************************************/
void Transfer_command(unsigned char send_cmd)
{
cs1=0;
rs=0;
Send_byte(send_cmd); // 发送起始信号 第1字节-格式:1111ABC
delay(5); // 延时是必须的
}
/*写数据到LCD模块*/
void Transfer_data(int send_data)
{
cs1=0;
rs=1;
Send_byte(send_data); // 发送起始信号 第1字节-格式:1111ABC
delay(5);
}
/*延时*/
void delay(unsigned int i)
{
unsigned int j,k;
for(j=0;j<i;j++)
for(k=0;k<110;k++);
}
/*LCD模块初始化*/
void initial_lcd()
{
cs1=0;
reset=0; /*低电平复位*/
delay(100);
reset=1; /*复位完毕*/
delay(20);
Transfer_command(0xe2); /*软复位*/
delay(5);
Transfer_command(0x2c); /*升压步聚1*/
delay(5);
Transfer_command(0x2e); /*升压步聚2*/
delay(5);
Transfer_command(0x2f); /*升压步聚3*/
delay(5);
Transfer_command(0x23); /*粗调对比度,可设置范围0x20~0x27*/
Transfer_command(0x81); /*微调对比度*/
Transfer_command(0x28); /*0x1a,微调对比度的值,可设置范围0x00~0x3f*/
Transfer_command(0xa2); /*1/9偏压比(bias)*/
Transfer_command(0xc8); /*行扫描顺序:从上到下*/
Transfer_command(0xa0); /*列扫描顺序:从左到右*/
Transfer_command(0x40); /*起始行:第一行开始*/
Transfer_command(0xaf); /*打开显示*/
clear_screen(); //clear all dots
cs1=1;
}
void lcd_address(unsigned char page,unsigned char column)
{
cs1=0;
column=column-1; //我们平常所说的第1列,在LCD驱动IC里是第0列。所以在这里减去1.
page=page-1;
Transfer_command(0xb0+page); //设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页,在LCD驱动IC里是第0页,所以在这里减去1*/
Transfer_command(((column>>4)&0x0f)+0x10); //设置列地址的高4位
Transfer_command(column&0x0f); //设置列地址的低4位
}
/*全屏清屏,实际上是向每个点送数据0*/
void clear_screen()
{
unsigned char i,j;
cs1=0;
for(i=0;i<9;i++)
{
lcd_address(1+i,1);
for(j=0;j<132;j++) //
{
Transfer_data(0x00);
}
}
cs1=1;
}
/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
void display_graphic_16x16(unsigned char page,unsigned char column,unsigned char *dp)
{
unsigned char i,j;
cs1=0;
for(j=0;j<2;j++)
{
lcd_address(page+j,column);
for (i=0;i<16;i++)
{
Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
dp++;
}
}
cs1=1;
}
/*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/
void display_graphic_8x16(unsigned char page,unsigned char column,unsigned char *dp)
{
unsigned char i,j;
cs1=0;
for(j=0;j<2;j++)
{
lcd_address(page+j,column);
for (i=0;i<8;i++)
{
Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
dp++;
}
}
cs1=1;
}
//分\秒闪烁,time表示分\秒的数据
void blink_graphic_8x16(unsigned char page,unsigned char column,unsigned char *dp)
{
unsigned char delay_counter; //延时计数器
while(Right==1) //我的主板的按键是接在某某I/O口与地之间
{
delay_counter=0; //延时计数器归零
display_graphic_8x16(page,column,empty); //显示首位空
while(Right==1&&delay_counter<5)
{
delay(100); //延时100 ms左右再去扫描键盘,如此反复多次
delay_counter++;
}
display_graphic_8x16(page,column,dp); //显示时间
delay_counter=0; //延时计数器归零
while(Right==1&&delay_counter<5)
{
delay(100); //延时100 ms左右再去扫描键盘,如此反复多次
delay_counter++;
}
delay_counter=0; //延时计数器归零
}
}
void keyscan()
{
if(Up == 0){
page--;
INT0=0;
if(page==255)page=7; // 定义为unsgined char 0 再减一等于255
}
/*
if(Down == 0){
page++;
T1 = 1;
if(page==7)page=0;
}
*/
if(Left == 0){
column--;
if(column==255)column=128; // // 定义为unsgined char 0 再减一等于255
}
if(Right == 0){
column++;
if(column==128)column=0;
}
}
void main(void)
{
LEDA=0;
SPI_init();
delay(5);
initial_lcd();
page = 3;
column= 0;
while(1)
{
// clear_screen(); //clear all dots
display_graphic_16x16(page,column,zhuang1); /*在第5页,第1列显示单个汉字"状"*/
display_graphic_16x16(page,(column+16),tai1); /*在第5页,第17列显示单个汉字"态"*/
display_graphic_8x16(page,(column+16*2),mao_hao); /*在第5页,第25列显示单个字符":"*/
display_graphic_16x16(page,(column+16*2+8),shi1); /*在第5页,第41列显示单个汉字"使"*/
display_graphic_16x16(page,(column+16*3+8),yong1); /*在第5页,第49列显示单个汉字"用"*/
display_graphic_8x16(page,(column+88),num0); /*在第5页,第89列显示单个数字"0"*/
display_graphic_8x16(page,(column+88+8*1),num0); /*在第5页,第97列显示单个数字"0"*/
display_graphic_8x16(page,(column+88+8*2),mao_hao); /*在第5页,第105列显示单个字符":"*/
display_graphic_8x16(page,(column+88+8*3),num0); /*在第5页,第113列显示单个数字"0"*/
display_graphic_8x16(page,(column+88+8*4),num0); /*在第5页,第121列显示单个数字"0"*/
blink_graphic_8x16(page,(column+88+8*4),num0); //光标闪烁
}
}
/**
* FUNCTION_PURPOSE:interrupt
* FUNCTIO N_INPUTS: void
* FUNCTION_OUTPUTS: transmit_complete is software transf
*/
void it_SPI(void) interrupt 9 /* interrupt address is 0x004B*/
{
SPCON |= 0x40; /* run spi SPEN=1 */
SPCON |= 0x10; /* Master mode */
switch( SPSTA ) /* read and clear spi status reGISTER*/
{
case 0x80:
//serial_data=SPDAT; /* read receive data */
//transmit_completed=1;/* set software flag */
break;
case 0x10:
/* put here for mode fault tasking */
break;
case 0x40:
/* put here for overrun tasking */
break;
}
}
确实能驱动12864了,但是程序里有
unsigned char SPIS_Transfer(unsigned char dat)
{
SPDAT = dat; //trigger SPI send
while (!(SPSTA&0X80)); //wait send complete
return SPDAT; //return received SPI data
}
这样的一段代码
但是这个 while (!(SPSTA&0X80)); 会导致传输变慢,
想在ISP中断里处理,怎么办呀
求大神帮助
|