/*****************************************************************
程序说明CA12864K(ST7920)内核的点阵型LCD12864子程序
日 期:2010-09-10
修改日期:
引脚图
|-----------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|GND VCC V0 RS(CS) R/W(SID) E(CLK) DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 PSB NC RESET VOUT BLA(5V) BLK(0V) |
|-----------------------------------------------------------------------------------------------------|
PSB H-并行,L-串行
注:(1)单片机:AT89S52 晶振Fosc:RC 8MHz
(2)环境:编译环境 AVR Studio 4.17/AVR GCC WINAVR2009
(3)显示芯片:CA12864K 控制器:ST7920
(4)LCM的接口方式:并行方式,PSB接高;
(5)液晶复位端 悬空 上电清屏时要延时
(6)每次清屏时要延时 否则会在第一位出现乱码
(7)每次读/写LCD操作之前,应首先检测忙标志BF,确认BF=0后,访问过程才能进行;
(8)绘图显示的步骤
1 关闭绘图显示功能
2 先将垂直的坐标(Y)写入绘图RAM地址
3 再将水平的位元组坐标(X)写入绘图RAM地址
4 将D15-D8写入RAM中
5 将D7-D0写入到RAM中
6 打开绘图显示功能
(9)对于屏幕上面任意一个点,如果我们想要点亮它,必须先读出此点的状态,然后再修改该点,最后送出去,即 读----修改----写
******************************************************************/
//-----------------------------------------------------------------
// 包含文件
//-----------------------------------------------------------------
#include <avr/io.h>
#include <avr/delay.h> //WINAVR所带的延时子程序头文件
#include "LCD12864.h"
//-----------------------------------------------------------------
// 数据类型宏定义
//-----------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
//-----------------------------------------------------------------
// 初始化程序区
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// void LCDIO_Init(void)
//-----------------------------------------------------------------
//
// 函数功能: LCDIO初始化
// 入口参数: 无
// 返回参数: 无
// 全局变量: 无
// 调用模块:
// 注意事项:
//-----------------------------------------------------------------
void LCDIO_Init(void)
{
LCDDDR_DOUT; //I/O口方向设置
LCDDAT_PORT = 0xff; //I/O口电平设置
LCDSIG_DDR; //SIG口方向设置
LCDSIG_PORT; //SIG口电平设置
}
//-----------------------------------------------------------------
// void LCD12864_Init(void)
//-----------------------------------------------------------------
//
// 函数功能: LCD12864初始化
// 入口参数: 无
// 返回参数: 无
// 全局变量: 无
// 调用模块: LCD12864_WriteCom(uchar cmd);Delay_us(uint);Delay_ms(uint);
// 注意事项: 在向液晶写完命令后,必须适当延时;
//-----------------------------------------------------------------
void LCD12864_Init(void)
{
LCDDDR_DOUT; //LCDIO设置输出
LCDSIG_DDR; //SIG口方向设置
Delay_ms(1);
LCD12864_WriteCom(FUN_MODE); //显示模式设置 选择基本指令集
Delay_ms(1); //延时10ms(7.5ms以上)
LCD12864_WriteCom(FUN_MODE); //选择8bit数据流
Delay_ms(1); //延时10ms(7.5ms以上)
LCD12864_WriteCom(CLEAR_SCREEN); //清屏指令:清屏且AC值为00H
Delay_ms(1); //延时10ms(7.5ms以上)
LCD12864_WriteCom(DISPLAY_ON); //显示开
Delay_ms(1); //延时2us
LCD12864_WriteCom(CURSE_ADD); //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)
Delay_ms(1); //延时2us
}
//-----------------------------------------------------------------
// 功能程序区
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// void LCD12864_Busy(void)
//-----------------------------------------------------------------
//
// 函数功能: LCD12864忙检测
// 入口参数: 无
// 返回参数: 无
// 全局变量: 无
// 调用模块: 无
// 注意事项:
//-----------------------------------------------------------------
void LCD12864_Busy(void)
{
LCDDDR_DIN; //LCDIO设置输入
LCDRS_CLR; //选中命令寄存器
LCDRW_SET; //E为H时,数据读到DB7-DB0(RW=H)
LCDEN_SET; //高电平使能
while((LCDDAT_PIN & 0x80) == 0x80);
LCDEN_CLR; //禁止
LCDDDR_DOUT; //LCDIO设置输出
}
//-----------------------------------------------------------------
// void LCD12864_WriteCom(uchar cmd)
//-----------------------------------------------------------------
//
// 函数功能: LCD12864写指令
// 入口参数: LCD12864指令
// 返回参数: 无
// 全局变量: 无
// 调用模块: LCD12864_Busy(void);Delay_us(uint x);
// 注意事项: 对lcd1286操作前要忙检测
// 在数据写入的时候加入适当的延时
//-----------------------------------------------------------------
void LCD12864_WriteCom(uchar cmd)
{
// LCD12864_Busy(); //忙检测
LCDRS_CLR; //选中命令寄存器
LCDRW_CLR; //写操作
LCDEN_SET; //使能
LCDDAT_PORT = cmd; //数据放到端口
Delay_ms(5); //延时
LCDEN_CLR; //禁止操作
}
//-----------------------------------------------------------------
// void LCD12864_WriteData(uchar dat)
//-----------------------------------------------------------------
//
// 函数功能: LCD12864写数据
// 入口参数: LCD12864数据
// 返回参数: 无
// 全局变量: 无
// 调用模块: LCD12864_Busy(void);Delay_us(uint x);
// 注意事项: 在数据写入的时候加入适当的延时
//-----------------------------------------------------------------
void LCD12864_WriteData(uchar dat)
{
// LCD12864_Busy(); //忙检测
LCDRS_SET; //选中数据寄存器
LCDRW_CLR; //写操作
LCDEN_SET; //使能
LCDDAT_PORT = dat; //数据放到端口
Delay_ms(5); //延时
LCDEN_CLR; //禁止操作
}
//-----------------------------------------------------------------
// uchar LCD12864_ReadData(void)
//-----------------------------------------------------------------
//
// 函数功能: LCD12864读数据
// 入口参数: 无
// 返回参数: LCD12864数据
// 全局变量: 无
// 调用模块: LCD12864_Busy(void);Delay_us(uint x);
// 注意事项: 在数据写入的时候加入适当的延时
//-----------------------------------------------------------------
uchar LCD12864_ReadData(void)
{
uchar read;
// LCD12864_Busy(); //忙检测
LCDDDR_DIN; //LCDIO设置输入
LCDRS_SET; //选中数据寄存器
LCDRW_SET; //读操作
LCDEN_CLR; //禁止操作
LCDEN_SET; //使能
Delay_us(1); //延时
read = LCDDAT_PIN; //从端口读数据
Delay_us(1); //延时
LCDEN_CLR; //禁止操作
LCDDDR_DOUT; //LCDIO设置输出
return (read); //返回读取值
}
//-----------------------------------------------------------------
// void LCD12864_DispString(uchar xpos,uchar ypos,uchar *s)
//-----------------------------------------------------------------
//
// 函数功能: lcd12864显示字符串
// 入口参数: 液晶横坐标 纵坐标 显示汉字指针
// 返回参数: 无
// 全局变量: 无
// 调用模块: void Goto_xy(xpos,ypos);void LCD12864_WriteData(uchar dat);
// void Delay_us(uchar x);
// 注意事项: xpos、ypos为汉字坐标;给数据首地址;最多写8*4个汉字
//-----------------------------------------------------------------
void LCD12864_DispString(uchar xpos,uchar ypos,uchar *s)
{
Goto_xy(xpos,ypos); //指定写到液晶的坐标
Delay_ms(5); //延时
while(*s != '\0')
{
LCD12864_WriteData(*s); //写数据
Delay_ms(5); //延时
s++;
}
}
//-----------------------------------------------------------------
// void Goto_xy(uchar xpos,uchar ypos)
//-----------------------------------------------------------------
//
// 函数功能: 设置显示位置
// 入口参数: 横坐标 纵坐标
// 返回参数: 无
// 全局变量: 无
// 调用模块: void LCD12864_WriteCom(uchar cmd);
// 注意事项: X坐标
// 第一行 80H 81H 82H 83H 84H 85H 86H 87H
// 第二行 90H 91H 92H 93H 94H 95H 96H 97H
// 第三行 88H 89H 8aH 8bH 8cH 8dH 8eH 8fH
// 第四行 98H 99H 9aH 9bH 9cH 9dH 9eH 9fH
//-----------------------------------------------------------------
void Goto_xy(uchar xpos,uchar ypos)
{
switch(ypos)
{
case 0:LCD12864_WriteCom(0x80|xpos);break;//第一行0,0~0,7
case 1:LCD12864_WriteCom(0x90|xpos);break;//第二行1,0~1,7
case 2:LCD12864_WriteCom(0x88|xpos);break;//第三行2,0~2,7
case 3:LCD12864_WriteCom(0x98|xpos);break;//第四行3,0~3,7
default:break;
}
}
//-----------------------------------------------------------------
// void LCD12864_CleGdram(void)
//-----------------------------------------------------------------
//
// 函数功能: 清空GDRAM
// 入口参数: 无
// 返回参数: 无
// 全局变量: 无
// 调用模块: LCD12864_WriteCom(uchar);LCD12864_WriteData(uchar);
// 注意事项:
//-----------------------------------------------------------------
void LCD12864_CleGdram(void)
{
uchar x,y,i;
for(i=0;i<2;i++)
{
for(y=0;y<32;y++)
{
for(x=0;x<8;x++)
{
LCD12864_WriteCom(0x36); //扩充指令 绘图显示
LCD12864_WriteCom(y+0x80); //行地址
LCD12864_WriteCom(x+0x80+i*8); //列地址
LCD12864_WriteData(0x00); //写数据 D15-D8
LCD12864_WriteData(0x00); //写数据 D7-D0
LCD12864_WriteCom(0x30);
}
}
}
}
//-----------------------------------------------------------------
// void LCD12864_Cle(void)
//-----------------------------------------------------------------
//
// 函数功能: 清空LCD12864
// 入口参数: 无
// 返回参数: 无
// 全局变量: 无
// 调用模块: void LCD12864_WriteCom(uchar);void LCD12864_CleGdram(void);
// void Delay_us(uint);
// 注意事项:
//-----------------------------------------------------------------
void LCD12864_Cle(void)
{
LCD12864_WriteCom(0x0c); //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)
Delay_us(100); //延时100us
LCD12864_WriteCom(0x01); //清屏指令:清屏且AC值为00H
Delay_ms(1); //延时1ms
LCD12864_CleGdram(); //清空GDRAM
}
//-----------------------------------------------------------------
// END of FILE
//-----------------------------------------------------------------
int main(void )
{
LCDIO_Init();
Delay_ms(100); //延时100ms
LCD12864_Init(); //LCD12864初始化
LCD12864_CleGdram(); //清空GDRAM
LCD12864_Cle(); //清空LCD12864
while(1)
{
Goto_xy(1,1); //设置显示位置
LCD12864_WriteData(0x31); //LCD12864写数据
}
}
/********************************************************
头文件名:lcd12864.h
编写时间:2010.04.20
完成时间:2010.04.20
修改日期:
作者:蔡亚辉
********************************************************/
#ifndef _LCD12864_H_
#define _LCD12864_H_
//-----------------------------------------------------------------
// 数据类型宏定义
//-----------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define F_CPU 8000000 // 单片机主频为7.3728MHz,
#define Delay_us(x) _delay_us(x) //AVR GCC延时函数 x(us)
#define Delay_ms(x) _delay_ms(x) //AVR GCC延时函数 x(ms)
#define BIT(x) (1<<(x))
//-----------------------------------------------------------------
// I/O口定义
//-----------------------------------------------------------------
#define LCDDDR_DIN DDRC = 0 //I/O口方向设置
#define LCDDDR_DOUT DDRC = 0xff
#define LCDDAT_DDR DDRC
#define LCDDAT_PORT PORTC
#define LCDDAT_PIN PINC
#define LCDSIG_DDR DDRA |= BIT(PA1)|BIT( PA2)|BIT(PA3) //SIG口方向设置
#define LCDSIG_PORT PORTA|= BIT(PA1)|BIT( PA2)|BIT(PA3) //SIG口电平设置
#define LCDRS_CLR PORTA &= ~BIT(PA3) //RS置低
#define LCDRS_SET PORTA |= BIT(PA1) //RS置高
#define LCDRW_CLR PORTA &= ~BIT(PA2) //RW置低
#define LCDRW_SET PORTA |= BIT(PA1) //RW置高
#define LCDEN_CLR PORTA &= ~BIT(PA1) //E置低
#define LCDEN_SET PORTA |= BIT(PA1) //E置高
//-----------------------------------------------------------------
// LCD12864功能初始化指令
//-----------------------------------------------------------------
#define CLEAR_SCREEN 0x01 //清屏指令:清屏且AC值为00H
#define AC_INIT 0x02 //将AC设置为00H。且游标移到原点位置
#define CURSE_ADD 0x06 //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)
#define FUN_MODE 0x30 //工作模式:8位基本指令集
#define FUN_SPREAD 0x34 //工作模式:扩展方式
#define DISPLAY_ON 0x0c //显示开
#define DISPLAY_OFF 0x08 //显示关
#define DISPLAYON 0x0f //显示开,显示游标,且游标位置反白
#define CURSE_DIR 0x14 //游标向右移动:AC=AC+1
#define SET_CG_AC 0x40 //设置AC,范围为:00H~3FH
#define GREW_ON 0x36 //绘图开
#define GREW_OFF 0x30 //绘图关
#define SET_DD_AC 0x80
//-----------------------------------------------------------------
// 外部函数声明
//-----------------------------------------------------------------
extern void LCD12864_Busy(void); //LCD12864忙检测
extern void LCD12864_WriteCom(uchar); //LCD12864写指令
extern void LCD12864_WriteData(uchar); //LCD12864写数据
extern uchar LCD12864_ReadData(void); //LCD12864读数据
extern void LCDIO_Init(void); //LCDIO初始化
extern void LCD12864_Init(void); //LCD12864初始化
extern void LCD12864_DispString(uchar xpos,uchar ypos,uchar *s);//lcd12864显示字符串
extern void Goto_xy(uchar xpos,uchar ypos); //设置显示位置
extern void LCD12864_CleGdram(void); //清空GDRAM
extern void LCD12864_Cle(void); //清空LCD12864
#endif
//-----------------------------------------------------------------
// END of FILE
//-----------------------------------------------------------------