📄 glcd.c
字号:
/*——————————————————————————————————————————————
〖文件〗glcd.c
〖说明〗
HD61202 LCD Driver For AvrGcc
这只是一个最基本的驱动。
我主要用它在开发是显示调试信息,所以很多功能尚未完成(如写汉字,画图标等)。
〖硬件〗
128*64点阵液晶,芯片为三星的KS0108+KS0107,兼任日立HD61202。
在SL-AVRS实验板上实验通过。
〖作者〗
张磊,2002/5/7 初始版本,在avrgcc-2001-11版本上编译通过。
〖修改〗
张磊,2002/7/2。 增加中文注释
张磊,2002/9/12。 增加一些新宏,这样就可以在avrgcc 2002-6-25及以上版本正确编译。
张磊,2006/7/19。 修改代码,使WinAVR-20050214及以上版本正确编译。
〖版本〗
V 1.03
〖版权〗
驱动可以无限制使用 。如果你愿意,请寄你的修改拷贝给我,谢谢!
张磊(zhanglei@zj165.net)保留其修改权利,并不对使用本驱动造成的损失负责。
修改自某高手的C51版本(可惜我找不到他的详细信息),在此向他致敬。
〖其它〗
1、由于字体为5*7(我为了节省Rom),所以反白显示有问题。你只要修改字体为8*8既可。
2、反白显示,更改字体只要简单修改glcd_putc()函数中,
glcd_wr_data(pgm_read_byte(&font5x7[((chr - 32) * 5) + a]));这一行既可。
——————————————————————————————————————————————*/
//#include "includes.h"
#include <avr/pgmspace.h>
#include "glcd.h"
#include "font.h"
unsigned char _xx = 0, _yy = 0;
/****************************************/
/* 打开背光 */
/****************************************/
void inline glcd_back_light_on(void)
{
//sbi(GLCD_CTRLPORT, GLCD_BLED);
}
/****************************************/
/* 关闭背光 */
/****************************************/
void inline glcd_back_light_off(void)
{
//cbi(GLCD_CTRLPORT, GLCD_BLED);
}
/****************************************/
/* 光标定位 */
/****************************************/
void inline glcd_gotoxy(unsigned char x, unsigned char y)
{
_xx = x;
_yy = y;
}
/****************************************/
/* 输出一个字符串 */
/****************************************/
void glcd_puts(unsigned char *data , unsigned char style)
{
while (*data)
{
glcd_putc(*data , style);
data++;
}
}
/****************************************/
/* 输出一个字符 */
/****************************************/
void glcd_putc(unsigned char chr , unsigned char style)
{
unsigned char a = 0, x;
if (_xx > 123)
{
_xx = 0;
_yy++;
if (_yy == 8) _yy = 0;
}
if (_xx < 64)
{
set_cs1();
x = _xx;
}
else
{
set_cs2();
x = _xx - 64;
}
glcd_set_x_addr(x);
glcd_set_y_addr(_yy);
do
{
glcd_wr_data(pgm_read_byte(&font5x7[((chr - 32) * 5) + a]));
a++;
_xx++;
if (_xx == 64)
{
clr_cs1();
set_cs2();
}
else if (_xx == 128)
{
clr_cs2();
set_cs1();
_xx = 0;
_yy++;
if (_yy == 8) _yy = 0;
}
if (_xx < 64) x = _xx;
else x = _xx - 64;
glcd_set_x_addr(x);
glcd_set_y_addr(_yy);
} while (a < 5);
_xx++;
if (_xx == 128)
_xx = 0;
else
glcd_wr_data(0x00);
clr_cs1();
clr_cs2();
glcd_start_line(0);
}
/****************************************/
/* 画点 */
/****************************************/
void glcd_set_dot(unsigned char x, unsigned char y)
{
unsigned char temp;
if (x < 64)
{
set_cs1();
glcd_set_x_addr(x);
glcd_set_y_addr(y / 8);
temp = glcd_rd_data(); /* 虚读 */
temp = glcd_rd_data();
glcd_set_x_addr(x);
glcd_wr_data(temp | (1 << (y % 8)));
clr_cs1();
}
else
{
set_cs2();
glcd_set_x_addr(x - 64);
glcd_set_y_addr(y / 8);
temp = glcd_rd_data(); /* 虚读 */
temp = glcd_rd_data();
glcd_set_x_addr(x - 64);
glcd_wr_data(temp | (1 << (y % 8)));
clr_cs2();
}
glcd_start_line(0);
}
/****************************************/
/* 消点 */
/****************************************/
void glcd_clr_dot(unsigned char x, unsigned char y)
{
unsigned char temp;
if (x < 64)
{
set_cs1();
glcd_set_x_addr(x);
glcd_set_y_addr(y / 8);
temp = glcd_rd_data(); /* 虚读 */
temp = glcd_rd_data();
glcd_set_x_addr(x);
glcd_wr_data(temp & (0xff - (1 << (y % 8))));
clr_cs1();
}
else
{
set_cs2();
glcd_set_x_addr(x - 64);
glcd_set_y_addr(y / 8);
temp = glcd_rd_data(); /* 虚读 */
temp = glcd_rd_data();
glcd_set_x_addr(x - 64);
glcd_wr_data(temp & (0xff - (1 << (y % 8))));
clr_cs2();
}
glcd_start_line(0);
}
/************************************************/
/*画线。任意方向的斜线,直线数学方程 aX+bY=1 */
/************************************************/
void glcd_line(unsigned char x1 , unsigned char y1 ,unsigned char x2 , unsigned char y2)
{
//
}
/****************************************/
/* 画圆 */
/****************************************/
void glcd_circle(unsigned char x_center, unsigned char y_center, unsigned char radius)
{
int tswitch, y, x = 0;
unsigned char d;
d = y_center - x_center;
y = radius;
tswitch = 3 - 2 * radius;
while (x <= y)
{
glcd_set_dot(x_center + x, y_center + y); glcd_set_dot(x_center + x, y_center - y);
glcd_set_dot(x_center - x, y_center + y); glcd_set_dot(x_center - x, y_center - y);
glcd_set_dot(y_center + y - d, y_center + x); glcd_set_dot(y_center + y - d, y_center - x);
glcd_set_dot(y_center - y - d, y_center + x); glcd_set_dot(y_center - y - d, y_center - x);
if (tswitch < 0)
tswitch += (4 * x + 6);
else
{
tswitch += (4 * (x - y) + 10);
y--;
}
x++;
}
}
/****************************************/
/* 画矩形 */
/****************************************/
void glcd_rect(unsigned char x, unsigned char y, unsigned char a, unsigned char b)
{
unsigned char j;
for (j = 0; j < a; j++)
{
glcd_set_dot(x, y + j);
glcd_set_dot(x + b - 1, y + j);
}
for (j = 0; j < b; j++)
{
glcd_set_dot(x + j, y);
glcd_set_dot(x + j, y + a - 1);
}
}
/****************************************/
/* 初始化 */
/****************************************/
void glcd_init(void)
{
GLCD_DATAPORT_DDR = 0x00 ;
glcd_back_light_off();
GLCD_CTRLPORT_DDR = ((1 << GLCD_RS) | (1 << GLCD_RW) | (1 << GLCD_EN) | (1 << GLCD_CS1) |
(1 << GLCD_CS2)| (1 << GLCD_RST)) ;
GLCD_CTRLPORT = ((0 << GLCD_RS) | (0 << GLCD_RW) | (0 << GLCD_EN) | (1 << GLCD_CS1) |
(0 << GLCD_CS2)| (0 << GLCD_RST) );
clr_rst();
glcd_delay(1);
set_rst();
set_cs1();
glcd_wait_for_reset();
glcd_wr_cmd(DISPLAY_ON);
clr_cs1();
set_cs2();
glcd_wait_for_reset();
glcd_wr_cmd(DISPLAY_ON);
clr_cs2();
glcd_clrscr();
}
/****************************************/
/* 小延时 */
/****************************************/
/*????
void glcd_delay(unsigned int p) // 1-8us ...2-13us ...5-31us
{ // 10-60us ...50-290us
unsigned int i; // 100-580us ...500-2,9ms
unsigned char j; // 1000-5,8ms ...5000-29ms
// 10000-56ms ...30000-170ms
// 50000-295ms...60000-345ms
for (i = 0; i < p; i++)
for (j = 0; j < 10; j++);
}????*/
/****************************************/
/* busy判断、等待 */
/****************************************/
/*?????
void glcd_wait_for_busy(void)
{
GLCD_DATAPORT_DDR = 0x00;
set_rw();
clr_rs();
do
{
glcd_delay(1);
set_en();
glcd_delay(1);
clr_en();
} while (bit_is_set(GLCD_DATAPORT_PIN, GLCD_STAT_BUSY));
}
????//*/
/****************************************/
/* 等待复位完成 */
/****************************************/
/*?????
void glcd_wait_for_reset(void)
{
GLCD_DATAPORT_DDR = 0x00;
set_rw();
clr_rs();
do
{
glcd_delay(1);
set_en();
glcd_delay(1);
clr_en();
} while (bit_is_set(GLCD_DATAPORT_PIN, GLCD_STAT_RESET));
}????*/
/****************************************/
/* 向液晶片寄存器中写命令 */
/****************************************/
void glcd_wr_cmd(unsigned char cmd)
{
glcd_wait_for_busy();
clr_rw();
clr_rs();
GLCD_DATAPORT_DDR = 0xFF;
GLCD_DATAPORT = cmd;
set_en();
glcd_delay(1);
clr_en();
}
/****************************************/
/* 向液晶片RAM中写数据 */
/****************************************/
void glcd_wr_data(unsigned char Data)
{
glcd_wait_for_busy();
clr_rw();
set_rs();
GLCD_DATAPORT_DDR = 0xFF;
GLCD_DATAPORT = Data;
set_en();
glcd_delay(1);
clr_en();
}
/****************************************/
/* 从液晶片RAM中读数据 */
/****************************************/
unsigned char glcd_rd_data(void)
{
glcd_wait_for_busy();
GLCD_DATAPORT_DDR = 0x00;
set_rw();
set_rs();
set_en();
glcd_delay(1);
clr_en();
//return inp(GLCD_DATAPORT_PIN);
return (GLCD_DATAPORT_PIN);
}
// from left to right ( 0 : 63 )
//inline:内联函数是代码被插入到调用者代码处的函数。如同 #define 宏
//内联函数通过避免被调用的开销来提高执行效率
void inline glcd_set_x_addr(unsigned char x_addr)
{
glcd_wr_cmd(DISPLAY_SET_Y | x_addr);
}
// from top to bottom ( 0 : 7 )
void inline glcd_set_y_addr(unsigned char y_addr)
{
glcd_wr_cmd(DISPLAY_SET_X | y_addr);
}
/****************************************/
/* 定义显示起始行为start */
/****************************************/
void glcd_start_line(unsigned char start)
{
set_cs1();
glcd_wr_cmd(DISPLAY_START_LINE | start);
clr_cs1();
set_cs2();
glcd_wr_cmd(DISPLAY_START_LINE | start);
clr_cs2();
}
/****************************************/
/* 清屏,全屏幕清零 */
/****************************************/
void glcd_clrscr(void)
{
unsigned char x, y;
set_cs1();
for (y = 0; y < 8; y++)
{
glcd_set_y_addr(y);
glcd_set_x_addr(0);
for (x = 0; x < 64; x++) glcd_wr_data(0);
}
clr_cs1();
set_cs2();
for (y = 0; y < 8; y++)
{
glcd_set_y_addr(y);
glcd_set_x_addr(0);
for (x = 0; x < 64; x++) glcd_wr_data(0);
}
clr_cs2();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -