ATmage16 控制 1602LCD 液晶显示
#include
#define uchar unsigned char
#define uint unsigned int
#define sbi
//12864 汉字显示模块 与 MCU 连接
#define CTRPORT PORTA
#define CTRDDR DDRA
#define RS PA4// 1:输入数据 ;0:输入命令
#define set_rs() CTRPORT |= (1 << RS)
#define clr_rs() CTRPORT &= ~(1 << RS)
#define RW PA5//1:读数据 0:写数据
#define set_rw() CTRPORT |= (1 << RW)
#define clr_rw() CTRPORT &= ~(1 << RW)
#define E PA6
#define set_e() CTRPORT |= (1 << E)
#define clr_e() CTRPORT &= ~(1 << E)
#define PSB PA7
#define set_psb() CTRPORT |= (1 << PSB)
#define clr_psb() CTRPORT &= ~(1 << PSB)
//串并口选择 1:并口模式; 0:串口模式;
//#define RST = P2^6;
#define BUSY PB7
#define LcdData PORTB
#define LcdPin PINB
#define LcdDdr DDRB
void Lcd_WriteCmd1(unsigned char cmdcode);
//延时子程序
void delay(unsigned int t)
{ unsigned int i,j;
for(i=0;iset_rw();
asm("NOP"); asm("NOP");
LcdData |= (1 << BUSY);
set_e();
asm("NOP"); asm("NOP");
LcdDdr = 0;
asm("NOP"); asm("NOP");
b = LcdPin & (1 << BUSY);
LcdDdr = 0xff;
asm("NOP"); asm("NOP");
clr_e();
return b;
set_rs();
clr_e();
asm("NOP"); asm("NOP");
clr_rw();
asm("NOP"); asm("NOP");
set_e();
asm("NOP"); asm("NOP");
LcdData=dispdata;
asm("NOP"); asm("NOP");
clr_e();
asm("NOP"); asm("NOP");
set_rw();
}
//等待 LCD 到空闲
static void wait()
{
while(Check_Busy());
}
//写数据
static void Lcd_Writedata(unsigned char dispdata)
{ wait();
}
//写指令代码
static void Lcd_WriteCmd(unsigned char cmdcode)
{ wait();
clr_rs();
clr_e();
asm("NOP"); asm("NOP");
clr_rw();
asm("NOP"); asm("NOP");
set_e();
asm("NOP"); asm("NOP");
LcdData=cmdcode;
asm("NOP"); asm("NOP");
clr_e();
asm("NOP"); asm("NOP");
set_rw();
}
//初始化 LCD
void init_12864()
{
CTRDDR |= (1 << RS)|(1 << RW)|(1 << E)|(1 << PSB);
LcdDdr = 0xff;
/*RST=0;
delay(50);
RST=1;*/
set_psb();
Lcd_WriteCmd(0x30);
delay(50);
Lcd_WriteCmd(0x0c);
delay(50);
Lcd_WriteCmd(0x01);
delay(50);
Lcd_WriteCmd(0x06);
的移位
delay(50);
}
//复位
//选择并行方式
//选择基本指令集
//开显示(无游标、不反白)
//清除显示,并且设定地址指针为 00H
//指定在资料的读取及写入时,设定游标的移动方向及指定显示
void WriteStr(unsigned char *s)
{
while(*s>0)
{ Lcd_Writedata(*s);
delay(50);
s++;
}
}
void hzDisp()
{
Lcd_WriteCmd(0x80);
delay(5);
WriteStr("黄河远上白云间,");
Lcd_WriteCmd(0x90);
WriteStr("一片孤城万仞山。");
Lcd_WriteCmd(0x88);
WriteStr("羌笛何须怨杨柳?");
Lcd_WriteCmd(0x98);
WriteStr("春风不度玉门关。");
}
/*绘图显示的步骤
1 关闭绘图显示功能
2 先将垂直的坐标(Y)写入绘图 RAM 地址
3 再将水平的位元组坐标(X)写入绘图 RAM 地址
4 将 D15-D8 写入 RAM 中
5 将 D7-D0 写入到 RAM 中
6 打开绘图显示功能*/
//整屏显示竖条
//当 ii=0 时显示上面 128×32,当 ii=8 时显示下面 128×32
void LcdFill_Vertical()
{ unsigned char x,y,ii;
for(ii=0;ii<9;ii+=8)
for(y=0;y<0x20;y++)
for(x=0;x<8;x++)
{
Lcd_WriteCmd(0x36);//扩充指令 绘图显示
Lcd_WriteCmd(y+0x80);
Lcd_WriteCmd(x+0x80+ii);
//行地址
//列地址
Lcd_Writedata(0x55); //写数据 D15-D8
Lcd_Writedata(0x55); //写数据 D7-D0
Lcd_WriteCmd(0x30);
}
}
//当 ii=0 时显示上面 128×32,当 ii=8 时显示下面 128×32
//整屏显示横条线
void LcdFill_Level()
{ unsigned char x,y,ii;
unsigned char k;
for(ii=0;ii<9;ii+=8)
for(y=0;y<0x20;y++)
{
if((y%2)==1)
k=0xff;
else
k=0;
Lcd_WriteCmd(0x30);
}
}
}
void lcd12864_test(void)
{
init_12864();
for(x=0;x<8;x++)
{ Lcd_WriteCmd(0x36);
Lcd_WriteCmd(y+0x80);
Lcd_WriteCmd(x+0x80+ii);
Lcd_Writedata(k);
Lcd_Writedata(k);
//扩充指令 绘图显示
//行地址
//列地址
LcdFill_Vertical();//显示竖条
delay(60000);
init_12864();
LcdFill_Level();//显示横条
delay(60000);
init_12864();
hzDisp(); //显示汉字
delay(60000);
}