📄 lcd12864.c
字号:
/******************************************************************************
/* LCD12864驱动程序
/* 文 件 名:LCD12864
/* 创建时间:2004年12月24日
/* 创 建 人:胡勇刚
/* Email: hygbeyond@163.com
//******************************************************************************
/* 这是根据我以前所做的C51的程序移值的,这个驱动已经在mega16L上运行成功了
/* 这个驱动要注意的是:你用的mega系列的话,要注意和JTAG,ISP的冲突问题,如果
/* 用的是C口作为数据口的话,就一定要关闭JTAG,记住如果要用JTAG作为仿真用的话
/* 尽量的不要用这几个脚,否则就关闭JTAG(特别是作为I/O口)
/* 我就是因为这个问题浪费了不少时间,主要的现象是插上LCD就不工作,
/* 拔掉LCD就一切正常,好像应该是LCD触发了JTAG,从而使芯片进入仿真状态了
/* 还有一点就是时钟频率,如果时钟频率高的话,需要修改DELAY_COUNT值
/* 不然的话显示会有问题,这是因为12864本身的反应速度比较慢的原因
/* 我现在所用的是mege16L 频率: 3.6864M
/*
/* 各位大虾如果有比这个驱动更优化的程序,请给我一份,就用上面的邮箱.谢谢了
//*****************************************************************************/
/*2005-8-27 21:38 把以前的ICC下的LCD12864驱动重新写了一遍 又移植到GCC*/
#define __LCD_12864_H
#include "config.h"
/******************************************************************************/
#ifndef uchar
#define uchar unsigned char
#endif
//***************************************************************************/
/***************************************************************************
#ifndef LCD_DI
#define LCD_DI PB0
#define LCD_RW PB1
#define LCD_EN PB2
#define LCD_CS1 PB3
#define LCD_CS2 PB4
#define LCD_DATA_IN PINC
#define LCD_DATA_OUT PORTC
#define LCD_DATA_DDR DDRC
#define LCD_CODE_OUT PORTB
#define LCD_DI_H LCD_CODE_OUT |= BIT(LCD_DI)
#define LCD_DI_L LCD_CODE_OUT &= ~BIT(LCD_DI)
#define LCD_RW_H LCD_CODE_OUT |= BIT(LCD_RW)
#define LCD_RW_L LCD_CODE_OUT &= ~BIT(LCD_RW)
#define LCD_EN_H LCD_CODE_OUT |= BIT(LCD_EN)
#define LCD_EN_L LCD_CODE_OUT &= ~BIT(LCD_EN)
#define LCD_CS1_H LCD_CODE_OUT |= BIT(LCD_CS1)
#define LCD_CS1_L LCD_CODE_OUT &= ~BIT(LCD_CS1)
#define LCD_CS2_H LCD_CODE_OUT |= BIT(LCD_CS2)
#define LCD_CS2_L LCD_CODE_OUT &= ~BIT(LCD_CS2)
#endif
//****************************************************************************/
#define pre_page 0xb8
/*预设LCD页地址*/
#define pre_col 0x40
/*预设LCD列地址*/
#define DELAY_COUNT 25
/*LCD延迟时间数*/
#define LCD_NOP() lcd_delay()
/*LCD延迟*/
#define LCD_STAY
/*写入左屏的地址初始*/
#define addressL( page, col) wcodeL(pre_page+page);\
wcodeL(pre_col+col)
/*写入右屏的地址初始*/
#define addressR( page, col) wcodeR(pre_page+page);\
wcodeR(pre_col+col)
//*****************************************************************************
void lcd_delay(void); //延迟
void wcodeL(uchar left_code); //左屏写入命令
void wdataL(uchar left_data); //左屏写入数据
void wcodeR(uchar right_code); //右屏写入命令
void wdataR(uchar right_data); //右屏写入数据
void lcd_init(void); //LCD初始化
void lcd_clear_range(uchar range);
void lcd_clear_left(void);
void lcd_print(uchar x,uchar y,uchar lcd_char);
void lcd_print88(uchar x,uchar y,const prog_uchar *lcd_char); //输出8*8的字符
void lcd_print1616(uchar x,uchar y,const prog_uchar *lcd_char); //输出16*16的汉字
void lcd_print816(uchar x,uchar y,const prog_uchar *lcd_char); //输出8*16的字符
//***************************************************************************/
void wcodeL(uchar left_code)//左屏写指令
{
LCD_DATA_DDR=0X00;
while(1)
{
//如果液晶空闲开始写数据和命令
LCD_CODE_OUT |=((1<<LCD_EN) | (1<<LCD_RW) | (1<<LCD_CS2));
LCD_CODE_OUT &= ~((1<<LCD_DI) | (1<<LCD_CS1));
if(!(LCD_DATA_IN & 0x80))
{
break;
}
}
LCD_RW_L;
LCD_DATA_DDR = 0XFF;
LCD_DATA_OUT = left_code;
LCD_NOP();
LCD_EN_L;
}
/******************************************************************************/
void wdataL(uchar left_data)//左屏写数据
{
LCD_DATA_DDR=0X00;
while(1)
{
//如果液晶空闲开始写数据和命令
LCD_CODE_OUT |= ((1<<LCD_EN) | (1<<LCD_RW) | (1<<LCD_CS2));
LCD_CODE_OUT &= ~((1<<LCD_DI) | (1<<LCD_CS1));
if(!(LCD_DATA_IN & 0x80))
{
break;
}
}
LCD_RW_L;
LCD_DI_H;
LCD_DATA_DDR=0XFF;
LCD_DATA_OUT=left_data;
LCD_NOP();
LCD_EN_L;
}
/******************************************************************************/
void wcodeR(uchar right_code)//右屏写指令
{
LCD_DATA_DDR=0X00;
while(1)
{
//如果液晶空闲开始写数据和命令
LCD_CODE_OUT |= ((1<<LCD_EN) | (1<<LCD_RW) | (1<<LCD_CS1));
LCD_CODE_OUT &= ~((1<<LCD_DI) | (1<<LCD_CS2));
if(!(LCD_DATA_IN & 0x80))
{
break;
}
}
LCD_RW_L;
LCD_DATA_DDR=0XFF;
LCD_DATA_OUT=right_code;
LCD_NOP();
LCD_EN_L;
}
/******************************************************************************/
void wdataR(uchar right_data)//写右屏数据
{
LCD_DATA_DDR=0X00;
while(1)
{
//如果液晶空闲开始写数据和命令
LCD_CODE_OUT |= ((1<<LCD_EN) | (1<<LCD_RW) | (1<<LCD_CS1));
LCD_CODE_OUT &= ~((1<<LCD_DI) | (1<<LCD_CS2));
if(!(LCD_DATA_IN & 0x80))
{
break;
}
}
LCD_RW_L;
LCD_DI_H;
LCD_DATA_DDR=0XFF;
LCD_DATA_OUT=right_data;
LCD_NOP();
LCD_EN_L;
}
/******************************************************************************/
void lcd_init(void)
{
uchar x,y;
//设置显示起始行
wcodeL(0x0c0);
wcodeR(0x0c0);
//开显示
wcodeL(0x3f);
wcodeR(0x3f);
for(x=0;x<8;x++)
{
wcodeL(pre_page+x);
for(y=0;y<64;y++)
{
wcodeL(pre_col+y);
wdataL(0);
}
}
for(x=0;x<8;x++)
{
wcodeR(pre_page+x);
for(y=0;y<64;y++)
{
wcodeR(pre_col+y);
wdataR(0);
}
}
}
/******************************************************************************/
void lcd_clear_range(uchar range)
{
uchar x=0;
for(x=0;x<64;x++)
{
addressL(range,x);
wdataL(0);
}
}
/******************************************************************************/
void lcd_clear_left(void)
{
uchar x,y;
for(x=0;x<8;x++)
{
for(y=0;y<64;y++)
{
addressL(x,y);
wdataL(0);
}
}
}
/******************************************************************************/
void lcd_print(uchar x,uchar y,uchar lcd_char)
{
if(x > 7)
{
x -= 7;
}
if(y > 63)
{
y -= 63;
addressL(x,y);
wdataL(lcd_char);
}else
{
addressR(x,y);
wdataR(lcd_char);
}
}
/******************************************************************************/
void lcd_print88(uchar x,uchar y,const prog_uchar *lcd_char)//显示8*8字符
{
uchar i;
for(i=0;i<8;i++)
{
lcd_print(x,y+i,pgm_read_byte(lcd_char++));
}
}
/******************************************************************************/
void lcd_print1616(uchar x,uchar y,const prog_uchar *lcd_char)//显示16*16的汉字
{
uchar i,j;
for(i=0;i<2;i++)
{
for(j=0;j<16;j++)
{
lcd_print(x+i,y+j,pgm_read_byte(lcd_char++));
}
}
}
/******************************************************************************/
void lcd_print816(uchar x,uchar y,const prog_uchar *lcd_char)//显示8*16字符
{
uchar i,j;
for(i=0;i<2;i++)
{
for(j=0;j<8;j++)
{
lcd_print(x+i,y+j,pgm_read_byte(lcd_char++));
}
}
}
/******************************************************************************/
void lcd_delay(void)
{
uchar i = DELAY_COUNT;
while(i--)
{
NOP();
}
}
/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -