📄 lcd.c
字号:
/* LCD模块:16X2 */
/* 控制器:HD44780 */
/* 设计者:李晶皎 */
/* PTC0-RS,PTC1-R/W,PTC2-E*/
#include "gp32.h"
#define cli() _asm("cli\n") /*开中断*/
#define sei() _asm("sei\n") /*关中断*/
#define nop() _asm("nop\n") /*空操作*/
extern void KeyInit(void);
/*数据类型定义部分*/
typedef unsigned int Uint; /*无符号整型数据类型的定义*/
typedef unsigned char Uchar; /*无符号整型数据类型的定义*/
typedef struct bits {
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
} BITS;
typedef union bit_char {
unsigned char byte;
BITS b;
} BIT_CHAR;
#define BIT0 (unsigned char)0x01
#define BIT1 (unsigned char)0x02
#define BIT2 (unsigned char)0x04
#define BIT3 (unsigned char)0x08
#define BIT4 (unsigned char)0x10
#define BIT5 (unsigned char)0x20
#define BIT6 (unsigned char)0x40
#define BIT7 (unsigned char)0x80
#define BSET(x, y) ((x).b.b ## y = 1)
#define BCLR(x, y) ((x).b.b ## y = 0)
#define CLRBYTE(x) ((x).byte = 0)
@tiny volatile BIT_CHAR PTC @0x02; //重新定义PTC口,使其能进行位操作
const Uchar String[11]={0x57,0x45,0x4c,0x43,0x4f,0x4d,0x45,0x20,0x59,0x4f,0x55,};//WELCOME YOU
const Uchar YearMonthDay[24]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,//年 代码0
0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x00,//月 代码1
0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00,//日 代码2
};
const Uchar Table[11]={0x32,0x30,0x30,0x34,0x00, //2004年
0x30,0x38,0x01, //08月
0x30,0x31,0x02,}; //01日
const Uchar delay=80;//延时时间常数
/*延迟1 ms*/
static void Wait1ms(void) {
int cnt = 0;
while (cnt<delay) cnt++;
}
/*延迟n ms*/
void WaitNms(int n){
Uchar i;
for(i=1;i<=n;i++)
Wait1ms();
}
/*产生E信号的下降沿*/
void Toggle(void){
BSET(PTC,2); /* E=1 */
BCLR(PTC,2); /* E=0 */
}
/*读忙标志*/
void ReadBF(void){ //读取BF的值,判断控制器当前是否可以接收MCU发来的数据
Uchar temp;
DDRB=0x00;
while(1){
BCLR(PTC,0); //RS=0
BSET(PTC,1); //R/W=1
BSET(PTC,2); //E=1
temp=PTB;
BCLR(PTC,2); //E=0
if ((temp&0x80)==0x00) break;
}
}
/*写指令代码*/
void WRCommand(Uchar command){
ReadBF();
DDRB=0xff;
BCLR(PTC,1); //R/W=0
PTB=command;
Toggle();
}
/*写显示数据*/
void WRData(Uchar data){
ReadBF();
DDRB=0xff;
BSET(PTC,0); //RS=1
BCLR(PTC,1); //R/W=0
PTB=data;
Toggle();
}
/*读显示数据*/
Uchar RDData(void){
Uchar data;
ReadBF();
BSET(PTC,0); //RS=1
BSET(PTC,1); //R/W=1
BSET(PTC,2); //E=1
data=PTB;
BCLR(PTC,2); //E=0
}
/* 初始化HD44780 LCD*/
void Init_LCD(void)
{
PTB=0x30;
BCLR(PTC,0); //RS=0
BCLR(PTC,1); //R/W=0
Toggle();
WaitNms(5);
PTB=0x30;
BCLR(PTC,0); //RS=0
BCLR(PTC,1); //R/W=0
Toggle();
Wait1ms();
PTB=0x30;
BCLR(PTC,0); //RS=0
BCLR(PTC,1); //R/W=0
Toggle();
WaitNms(2);
WRCommand(0x38); //设置工作方式-8位总线 字符行数两行 5*7点阵
WRCommand(0x08); //设置显示状态-关显示
WRCommand(0x01); //清屏
WaitNms(20);
WRCommand(0x06); //设置输入方式-画面不动光标右移
WRCommand(0x0F); //设置显示状态-画面显示,光标、闪烁显示
}
/*写西文字符*/
void DisplayEChar(Uchar *str){
Uchar i;
WRCommand(0x82); //DDRAM地址0x0000
for(i=0;i<11;i++){ //"WELCOME YOU"
WRData(str[i]);
}
}
/*建立自定义字符的字模数组*/
void SetCGRAM(void){
Uchar i;
WRCommand(0x40); //设置CGRAM地址
for(i=0;i<24;i++){
WRData(YearMonthDay[i]);
}
}
/*显示自定义字符-在液晶屏的第二行显示"2003年7月1日"*/
void DisplayCChar(void){
Uchar i;
SetCGRAM();
WRCommand(0xC5); //设置DDRAM地址
for(i=0;i<11;i++){
WRData(Table[i]);}
}
/*光标移动*/
void CursorScroll(void){
Uchar i;
DisplayEChar(String);
WRCommand(0x8C);
for(i=0;i<10;i++){
WRCommand(0x10); //光标左移
WaitNms(200);
}
}
/*画面滚动*/
void ScreenScroll(void){
DisplayEChar(String);
DisplayCChar();
while(1){
WRCommand(0x18); //画面左滚
WaitNms(200);}
}
/*回归原始位置*/
void ReturnHome(void){
WRCommand(0x02);
}
//F1显示英文字符
void DisplayEnglish(void){
WRCommand(0x01); //清屏
DisplayEChar(String); //显示西文字符串
}
//F2显示汉字字符
void DisplayChinese(void){
WRCommand(0x01); //清屏
DisplayCChar(); //显示汉字
}
//F3光标滚动
void ComCurScroll(void){
WRCommand(0x01); //清屏
CursorScroll(); //光标滚动
}
//F4屏幕滚动
void ComScrScroll(void){
WRCommand(0x01); //清屏
ScreenScroll(); //屏幕滚动
}
//PLL初始化
void PLLInit(void){
PCTL=0; //关闭PLL,准备进行设置
PBWC=0x80; //自动带宽模式
PCTL=1; //R=1
PMSH=1;
PMSL=0x2c; //N=012c
PMRS=0x80; //L=80
PCTL=0x22; //E=2,PLLON=1,启动PLL
while(!(PBWC&0x40)); //等待稳定输出
PCTL|=0x10; //频率锁定,选PLL作为时钟源
}
/* 系统集成模块(SIM)初始化,禁止COP(看门狗)*/
void SIMInit(void) {
CONFIG2=0x01; /* 内部总线时钟用作SCI的时钟*/
CONFIG1=0x3d; /* 允许LVE复位信号,禁止LVI的电源,LVI工作在5V,*/
/* 经过32个CGMXCLK周期退出STOP模式,禁止COP模块 */
}
//主函数
void main(void)
{
sei(); //关中断
SIMInit(); //SIM初始化
PLLInit(); //PLL初始化
PTC.byte=0x00;
DDRC=0x0F; //PTC的高4位为输入,低4位输出
Init_LCD(); //LCD初始化
KeyInit(); //键盘中断初始化
cli(); //开中断
for(;;); //等待键盘中断,并进行处理
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -