⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glcd.c

📁 AVRMEG32编写的一个项目代码,里面包含一般应用的模块.
💻 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 + -