/*************************************************************************
12864液晶串行显示测试程序
LCD型号:FYD12864-0402C
P2.4模拟SID(接第5脚),P2.5模拟SCLK(接第6脚)
4脚(CS信号)接高电平选通,15脚(PSB信号)接地选择串行方式->和GND焊盘相接
17脚(RST信号)根据注释提示悬空
*************************************************************************/
#include
#define uchar unsigned char
#define uint unsigned int
void int_port(void) //管脚初始化
{
P2SEL&=~BIT4; //P1.4模拟SID,设置为i/o口输出方向
P2DIR|=BIT4;
P2OUT&=~BIT4;
P2SEL&=~BIT5; //P1.5模拟SCLK,设置为i/o口输出方向
P2DIR|=BIT5;
P2OUT&=~BIT5;
}
/********************************************************************
* 名称 : delay()
*
* 输入 : t
* 输出 : 无
***********************************************************************/
void delay(uint t) //延时函数
{ //粗略延时,满足时序要求
uint i,j;
for(i=0; i
for(j=0; j<10; j++);
}
/********************************************************************
* 名称 : sendbyte()
* 功能 : 按照液晶的串口通信协议,发送数据
* 输入 : zdata
* 输出 : 无
***********************************************************************/
void sendbyte(uchar zdata) //数据传送函数
{
uchar code_seg7;
uchar serial_clk;
uchar serial_shift;
code_seg7=zdata;
serial_shift=0x80;
for(serial_clk=0; serial_clk<8; serial_clk++)
{
if(code_seg7&serial_shift)
{
P2OUT|=BIT4; //SID为1
}
else
{
P2OUT&=~BIT4; //SID为0
}
P2OUT&=~BIT5; //产生时钟信号下沿
P2OUT|=BIT5; //产生时钟信号上沿
serial_shift=serial_shift>>1; //准备发送下一位数据
}
}
/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode) //写命令函数
{
//串口控制格式(11111AB0)
//A数据方向控制,A=H时读,A=L时写
//B数据类型选择,B=H时为显示数据,B=L时为命令
sendbyte(0xf8); //MCU向LCD发命令
sendbyte(cmdcode & 0xf0); //发高四位数据(数据格式D7D6D5D4_0000)
sendbyte((cmdcode << 4) & 0xf0);//发低四位数据(数据格式D3D2D1D0_0000)
delay(2); //延时等待
}
/********************************************************************
* 名称 : write_data()
* 功能 : 写串口数据
* 输入 : Dispdata
* 输出 : 无
***********************************************************************/
void write_data(uchar Dispdata)//写数据函数
{
sendbyte(0xfa); //MCU向LCD发数据
sendbyte(Dispdata & 0xf0); //发高四位数据
sendbyte((Dispdata << 4) & 0xf0);//发低四位数据
delay(2);
}
/********************************************************************
* 名称 : lcdinit()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcdinit() //LCD初始化
{
delay(20000); //复位等待(内部自带上电复位电路),时间较长
write_com(0x30); //功能设定:基本指令集操作
delay(50); //延时等待
write_com(0x0c); //整体显示,关游标
delay(50);
write_com(0x01); //清屏
delay(50);
write_com(0x06); //入口设置
delay(50);
}
/********************************************************************
* 名称 : print_string()
* 功能 : 显示字符串
* 输入 : *s
* 输出 : 无
***********************************************************************/
void print_string(uchar *s) //发送字符串
{
while(*s > 0) //C语言里字符串末尾自动加“\\0”(ASCII码值为0)
{
write_data(*s); //发送字符对应的ASCII码,12864指针可设置自动指向下一个显示地址
s++;
delay(50);
}
}
/********************************************************************
* 函数名称 : LCD_12864_address_set( uchar x, y )
* 函数功能 : 12864地址坐标设置
* 函数参数 : X坐标,Y坐标
* 函数返回值: 无
*********************************************************************/
void LCD_12864_address_set( uchar x,uchar y )
{
uchar Address ;
switch( y )
{
case 1 : Address = 0x80 + (x - 1); break;
case 2 : Address = 0x90 + (x - 1); break;
case 3 : Address = 0x88 + (x - 1); break;
case 4 : Address = 0x98 + (x - 1); break;
default : break;
}
write_com(Address);
}
/**********************************************************************
* 函数名称 : LCD_12864_String( uchar y, uchar x, uchar *pData )
* 函数功能 : 12864显示字符串
* 函数参数 : 行,列,需要显示的字符串或汉字
* 函数返回值 : 无
***********************************************************************/
void LCD_12864_string( uchar y, uchar x, uchar *pData )
{
LCD_12864_address_set( x, y );
while( *pData != \'\\0\' )
{
write_data(*pData++);
}
}
/********************************************************************
* 函数名称 : LCD_12864_num(uchar y,uchar x,uchar num)
* 函数功能 : 12864以十进制格式显示一个两位数字
* 函数参数 : 行,列,需要输入需要显示的两位数字
* 函数返回值: 无
**********************************************************************/
void LCD_12864_2num(uchar y,uchar x,uchar num)
{
uchar num_1, num_2;
LCD_12864_address_set(x, y);
num_2 = (num/10) + 0x30;
num_1 = (num%10) + 0x30;
write_data(num_2);
write_data(num_1);
}
/********************************************************************
* 函数名称 : LCD_12864_num(uchar y,uchar x,uint num)
* 函数功能 : 12864以十进制格式显示一个四位数字
* 函数参数 : 行,列,需要输入需要显示的四位数字
* 函数返回值: 无
**********************************************************************/
void LCD_12864_4num(uchar y,uchar x,uint num)
{
uchar num_1, num_2, num_3, num_4 ;
LCD_12864_address_set(x, y);
num_4 = (num/1000) + 0x30;
num_3 = ((num%1000)/100) + 0x30;
num_2 = (((num%1000)%100)/10) + 0x30;
num_1 = (((num%1000)%100)%10) + 0x30;
write_data(num_4);
write_data(num_3);
write_data(num_2);
write_data(num_1);
}
/********************************************************************
* 函数名称 : LCD_12864_numx(uchar y,uchar x,char numx)
* 函数功能 : 12864以十六进制格式显示一个数字
* 函数参数 : 行,列,需要输入需要显示的数字(最高255 ==> 0xFF)
* 函数返回值: 无
**********************************************************************/
void LCD_12864_numx(uchar y,uchar x,uchar numx)
{
uchar num_l, num_h;
LCD_12864_address_set(x, y);
num_l = numx & 0x0F; //取键码的低四位
num_h = numx >> 4; //右移4次,高四位变为低四位
if(num_l > 9) num_l = num_l + 0x37;
else num_l = num_l + 0x30;
if(num_h > 9) num_h = num_h + 0x37;
else num_h = num_h + 0x30;
write_data(num_h);
write_data(num_l);
}
/********************************************************************
* 函数名称 : LCD_12864_draw_clear(void)
* 函数功能 : 12864绘图清屏
* 函数参数 : 无
* 函数返回值: 无
**********************************************************************/
void LCD_12864_draw_clear(void)
{
uchar i, j, k;
write_com(0x34); //扩展指令
for(i=0;i<2;i++)
{
for(j=0;j<32;j++)
{
write_com(0x80+j); //垂直地址+1
if(i==0)
{
write_com(0x80);//复位上半屏水平地址
}
else
{
write_com(0x88);//复位下半屏水平地址
}
write_com(0x36); //打开绘图
for(k=0;k<16;k++) //写两个字节数据水平地址加一,写完一行水平地址加到0x87
{
write_data(0x00);
}
}
}
write_com(0x30); //关闭扩展指令
}
/********************************************************************
* 函数名称 : LCD_12864_draw(*p)
* 函数功能 : 12864绘图
* 函数参数 : 图片数据数组首地址 (数组名)
* 函数返回值: 无
**********************************************************************/
void LCD_12864_draw(uchar *p)
{
uchar i, j, k;
LCD_12864_draw_clear(); //绘图清屏
write_com(0x34); //打开扩展指令
for(i=0; i<2; i++)
{
for(j=0; j<32; j++)
{
write_com(0x80+j); //垂直地址+1
if(i==0)
{
write_com(0x80); //复位上半屏水平地址
}
else
{
write_com(0x88); //复位下半屏水平地址
}
write_com(0x36); //打开绘图
for(k=0; k<16; k++) //写两个字节数据水平地址加一,写完一行水平地址加到0x87
{
write_data(*p++);
}
}
}
write_com(0x30); //关闭扩展指令
}
/********************************************************************
* 名称 : Test()
* 功能 : 显示子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Test()
{ uchar dat1,dat2,dat3,dat4;
dat1=6;dat2=8;dat3=8;dat4=8;
write_com(0x03); //发指令,地址归位
delay(50); //延时
write_com(0x80); //第一行首地址0x80
print_string(\"2012年电子竞赛 \"); //第一行显示(必须加一个空格否则不能下载)
write_com(0x94); //第二行首地址0x90,从第四个开始显示
write_data(dat1+0x30); //发送dat1的ASCII码,显示dat1的值
write_data(dat2+0x30); //发送dat1的ASCII码,显示dat2的值
write_data(dat3+0x30); //发送dat1的ASCII码,显示dat3的值
write_data(dat4+0x30); //发送dat1的ASCII码,显示dat4的值
write_data(\'H\'); //发送H的ASCII码,显示H
write_data(\'z\'); //发送z的ASCII码,显示z
write_com(0x90);
print_string(\"频率: \");
delay(500); //较长时间延时,保证下次操作前LCD完成上述功能处于非忙状态
}
void main()
{
WDTCTL=WDTPW+WDTHOLD; //关闭看门狗
int_port(); //端口初始化
lcdinit(); //LCD初始化
//Test(); //测试
LCD_12864_string(1,1,\"2012年TI杯\");
LCD_12864_string(2,1,\"倒计时:\");
LCD_12864_4num(3,1,0004);
LCD_12864_string(4,1,\"天 \");
while(1); //CPU空转
}