📄 lcd.c
字号:
/*--------------------------------------------
主题:S3C44B0-LCM-NT7534显示程序
编写人:龙寿华
程序功能:用ARM点亮此13264点阵的黑白液晶屏
;连线图:
;*LCM------MCU* *LCM-------MCU*
;*DB0~7---VD0~7/PD0~PD3-PC7~PC4* *A0----VFRAME/PD7*
;*WR-------VCLK/PD4* *CS1----EL_ON/PC9*
;*RD------VLINE/PD5* *RESET-----NRESET*
-------------------------------------------------*/
#include "..\inc\uTypes.h"
#include "..\inc\44b0x.h"
#include "..\inc\console.h"
#include "..\inc\sysUtils.h"
#include <stdarg.h>
//#define LCM_DELAY 1 //事实证明根本不需要延时,LCM完全能反应过来
/***********LCM常用操作命令和参数定义***************/
#define DISPON 0xAf /*显示on */
#define DISPOFF 0xAe /*显示off */
#define DISPFIRST 0x40 /*显示起始行定义 */
#define SETX1 0x00 /*X定位低4位设定指令(列) */
#define SETX2 0x10 /*X定位高4位设定指令(列) */
#define SETY 0xb0 /*Y定位设定指令(页) */
#define Lcdbusy 0x80 /*LCM忙判断位,当读出数据的最高位为1时,表示正忙。 */
#define DISCURRENT 0x81 /*进入到电流量设定 */
/*初始化LCD时用到的指令和参数定义*/
#define DISADC 0xA0 /*LCM显示ADC设定,顺方向 */
#define DISVOL 0xA2 /*LCM显示偏压设定(取中间值) */
#define DISCOM 0xCF /*LCM公共输出模式选择,逆方向 */
#define DISNORMAL 0xA6 /*一般显示指令 */
#define DISREVERSE 0xA7 /*反显指令 */
#define DISVR 0x24 /*调整V0电阻比率,这里折中*/
#define DISCURVUL 0x5D /*设定电流量值,这里折中 */
#define DISfrequency 0xE4 /*设定LCM工作频率,这里是最大值 */
#define DISPOWER 0x2F /*LCM电源控制项设定,这里全开 */
#define LCMLIMIT 132 /*本程序驱动13264LCM,所以这里为132.*/
/*******************************************************/
const unsigned char Ezk[]; //ASCII字库8列*16行
#define SET_LCM_A0() \
rPDATD |= MASK_BIT(7)
#define CLR_LCM_A0() \
rPDATD &= ~MASK_BIT(7)
#define SET_LCM_WR() \
rPDATD |= MASK_BIT(4)
#define CLR_LCM_WR() \
rPDATD &= ~MASK_BIT(4)
#define SET_LCM_RD() \
rPDATD |= MASK_BIT(5)
#define CLR_LCM_RD() \
rPDATD &= ~MASK_BIT(5)
#define SET_LCM_CS1() \
rPDATC &= ~MASK_BIT(9) //LCM的CS1是经过一个反向器与ARM连接,所以要反向
#define CLR_LCM_CS1() \
rPDATC |= MASK_BIT(9)
unsigned char col,row; //col即LCM的行地址,row即LCM的列地址
/****************************************/
/* 向LCM数据口输出数据函数 */
/****************************************/
void LCM_WRITE(unsigned char data)
{
unsigned char count;
unsigned char baker;
rPDATD = (rPDATD&0xf0)|(data&0x0f);
baker=data>>4;
data=baker&0x01;
for(count=1;count<4;count++){ //高四位高低位交换
data=(data<<1)|((baker>>count)&0x01);
}
rPDATC = (rPDATC&0xff0f)|(data<<4);
}
/****************************************/
/* 读出LCM数据口数据函数 */
/****************************************/
unsigned char LCM_READ(void)
{
unsigned char count;
unsigned char baker,data1,data2;
data1 = (rPDATD&0x0f);
data2 = (rPDATC&0xf0);
baker=data2>>4;
data2=baker&0x01;
for(count=1;count<4;count++){ //高四位高低位交换
data2=(data2<<1)|((baker>>count)&0x01);
}
return((data2<<4)|data1);
}
/****************************************/
/* LCM专用延时函数 */
/****************************************/
void lcmDelay (unsigned int nDelay)
{
int i;
for (i = 0; i < nDelay; ++ i);
}
/****************************************/
/* 对LCM写入命令 */
/****************************************/
void lcmWriteCmd (U8 byCmd)
{
CLR_LCM_A0();
CLR_LCM_CS1();
SET_LCM_RD();
// lcmDelay (LCM_DELAY);
CLR_LCM_WR();
LCM_WRITE (byCmd);
SET_LCM_CS1();
SET_LCM_WR ();
SET_LCM_A0();
// lcmDelay (LCM_DELAY);
}
/****************************************/
/* 对LCM写入数据 */
/****************************************/
void lcmWriteData (U8 byData)
{
SET_LCM_A0 ();
CLR_LCM_CS1();
SET_LCM_RD();
// lcmDelay (LCM_DELAY);
CLR_LCM_WR();
LCM_WRITE (byData);
SET_LCM_CS1();
SET_LCM_WR ();
SET_LCM_A0();
// lcmDelay (LCM_DELAY);
}
/****************************************/
/* LCM写入地址函数 */
/****************************************/
void LcmLoadxy ()
{
lcmWriteCmd(row | SETY); /* 写入页地址 */
lcmWriteCmd((col>>4) | SETX2); /*写入列地址的高4位*/
lcmWriteCmd((col & 0x0F) | SETX1); /* 写入列地址的低4位 */
}
/****************************************/
/* 清屏,全屏幕清零,不清屏ICON图标 */
/****************************************/
void Lcmcls( void )
{
row=0,col=0;
for(row=0;row<8;row++) /*这里不清功能指示行*/
{
col=0; /*回归到初始值0*/
LcmLoadxy(); /* 写入页首地址 */
for(;col<LCMLIMIT;col++)lcmWriteData(0); /* 写入数据0 */
}
row=0,col=0; /* 地址归位 */
}
/****************************************/
/*LCM显示功能点函数*/
/*入口数i是指定要显示的点的列数,j为1时表示点亮该点,为0时消隐*/
/****************************************/
void Lcm_dot (unsigned char i,unsigned char j)
{
unsigned char bakerx,bakery; //定义两个变量,用于存放col及row的初值
bakerx=col;bakery=row; //备份地址
col=i; /*写入标志的列地址*/
row=8; /*功能点都在第8页,即第65行*/
LcmLoadxy(); /* 写入地址 */
if (j)
{lcmWriteData(0xFF);} /*j=1,则点亮此点*/
else
{lcmWriteData(0);} /*j=0,关掉此点*/
col=bakerx;row=bakery; //还原地址
}
/****************************************/
/* 判断当前行及列是否足够显示函数 */
/* 入口数i是要输出的图形总列数,r是图形的总页数 */
/****************************************/
void Alldot(unsigned char i,unsigned char r)
{
if((LCMLIMIT-col)<i) /*判断当页所剩的列数是否小于i*/
{
col=0; /*如果所剩列数不够显示,则换行*/
row=(2+row);
}
if((8-row)<r) /*判断所剩的页数是否小于r*/
{
Lcmcls(); /*清屏处理*/
LcmLoadxy(); /*输入当前字符首地址*/
}
}
/****************************************************************************/
// 显示图片函数
/* 入口数*photo为图片首指针,x为图片的列数,y为图片的页数(最多8页)*/
/****************************************************************************/
void show_photo(const unsigned char*photo,unsigned char x,unsigned char y)
{
unsigned char bakerx,bakery,a,j;
bakerx = col; /*暂存x,y坐标,备下半个字符使用 */
bakery = row;
LcmLoadxy(); /*输入当前字符的首地址*/
for(a=0;a<y;a++)
{
for(j=0;j<x;j++)
{
lcmWriteData(*photo); /*取点阵码,并写输出一字节 */
photo++;
}
col = bakerx; /*列对齐 */
row++; /*指向下一行 */
LcmLoadxy(); /*输入下一行的首地址*/
}
/*整个图形输出结束 */
col = bakerx; /*恢复原来的col值*/
row = bakery; /*恢复原来的row值*/
}
/****************************************/
/* 半角字符点阵码数据输出 */
/* 入口数Order是指要输出的半角字序号,比如输出"空格",那么Order=0 */
/****************************************/
void Putedot(unsigned char Order)
{
Alldot(8,2); /* 调用列、行判断函数 */
show_photo(&Ezk[Order * 0x10],8,2);
/*整个字符输出结束 */
col = (col+8); /*列增加8,便于输入下个字符,row值不变*/
}
/****************************************/
/* 字符串显示输出 */
/* 本函数是可变函数,入口数为要显示的字符串 */
/****************************************/
void myprintf(const char *format,...)
{
va_list ap;//说明变量ap
unsigned char c;
c=*format; //取第一个值。
va_start(ap,format);//ap被初始化为指向format第一个参数
while(c!='%')
{ // 利用指针取数。
Alldot(8,2);
Putedot(c-0x20); /*ascii码表从0x20开始*/
++format;
c=*format;
}
va_end(ap);//清除变量x
}
/********************************/
/*液晶屏初始化函数 */
/********************************/
void lcmInit ()
{
//先初始化端口
//PORT C GROUP
//BUSWIDTH=16 */
/* PC15 14 13 12 11 10 9 8 */
/* o o RXD1 TXD1 o o o o */
/* NC NC Uart1 Uart1 NC NC CS1 NC */
/* 01 01 11 11 01 01 01 01 */
/* PC7 6 5 4 3 2 1 0 */
/* o o o o o o o o */
/* VD4 VD5 VD6 VD7 LED LED LED LED */
/* 01 01 01 01 01 01 01 01 */
rPDATC = 0x0000; //All IO is low
rPCONC = 0x5f555555;
rPUPC = 0x3000; //PULL UP RESISTOR should be enabled to I/O
//PORT D GROUP
/* PORT D GROUP(I/O OR LCD) */
/* BIT7 6 5 4 3 2 1 0 */
/* A0 VM RD ER VD3 VD2 VD1 VD0 */
/* 01 01 01 01 01 01 01 01 */
rPDATD= 0x00;
rPCOND= 0x5555;
rPUPD = 0x00;
lcmDelay (100);
lcmWriteCmd(DISVOL); /*LCD偏压设定 */
lcmWriteCmd(DISADC); /*ADC选择(顺方向) */
lcmWriteCmd(DISCOM); /*公共输出模式选择(逆方向) */
lcmWriteCmd(DISVR); /*调整V0电压电阻比率(折中) */
lcmWriteCmd(DISCURRENT); /*进入电流量设定*/
lcmWriteCmd(DISCURVUL); /*设定电流量*/
lcmWriteCmd(DISfrequency); /*设定晶振振荡频率*/
lcmWriteCmd(DISPOWER); /*电源控制设定(全开)*/
lcmWriteCmd(DISNORMAL); /*正显*/
Lcmcls(); /*清屏 */
col=0; /*回归到初始值0*/
row=8; /*清第8页,即第65行的功能点显示控制页*/
LcmLoadxy(); /* 写入页首地址 */
for(;col<LCMLIMIT;col++)lcmWriteData(0); /* 写入数据0 */
lcmWriteCmd(DISPFIRST); /*设定显示起始行*/
lcmWriteCmd(DISPON);/*开显示*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -