📄 240128.h
字号:
/* ----------------------------------------------------------
* 基于T6963C芯片的240x128点阵液晶屏驱动程序
*
* 程序编写 John P. Beale May 3-4, 1997 beale@best.com
* 程序改写 Nico Sachs Feb. 2006 for AVR-GCC
* 程序改写 bg4uvr 2007年5月22日 for WINAVR 20070122
* 同时将注释全部改为GB2312,方便中文用户
* bg4uvr@gmail.com
*
* 基本信息来源:
* 1、Steve Lawther 的著作
* 《Writing Software for T6963C based Graphic LCDs》, 1997年发布于
* http://ourworld.compuserve.com/homepages/steve_lawther/t6963c.pdf
* 2、东芝公司 T6963C 的数据手册
* 3、其他信息:
* http://www.citilink.com/~jsampson/lcdindex.htm
* http://www.cs.colostate.edu/~hirsch/LCD.html
* http://www.hantronix.com/
* ----------------------------------------------------------
*/
#ifndef __io_h__
#include <avr/io.h>
#endif
#ifndef __delay_h__
#include <util/delay.h>
#endif
#ifndef __stdio_h__
#include <stdio.h>
#endif
#ifndef __ina90_h__
#include <compat/ina90.h> //定义_NOP(),_CLI(),_SEI()
#endif
//以下头文件只在高级绘图函数中使用
/*
#ifndef __stdlib_h__
#include <stdlib.h> // rand()
#endif
#ifndef __string_h__
#include <string.h> // strlen()
#endif
#ifndef __math_h__
#include <math.h> // cos(),sin()
#endif
*/
//引脚定义
#define glcd_fs_PIN 0
#define glcd_wr_PIN 1
#define glcd_rd_PIN 6
#define glcd_ce_PIN 3
#define glcd_cd_PIN 4
#define glcd_rst_PIN 5
#define ctl_ddr DDRC
#define ctl_port PORTC
#define glcd_DATA_PORT PORTE
#define glcd_DATA_PIN PINE
#define glcd_DATADIR DDRE
/* ----- 定义液晶屏内部RAM ------ */
#define glcd_T_BASE 0x00 // 文本区内存首地址
#define glcd_G_BASE 0x200 // 图形区内存首地址
#define glcd_BYTES_PER_ROW 30 // 定义屏幕文本宽度为40字节
//定义宏
#define glcd_fs_high() ctl_port |= _BV(glcd_fs_PIN)
#define glcd_fs_low() ctl_port &= ~_BV(glcd_fs_PIN)
#define glcd_wr_high() ctl_port |= _BV(glcd_wr_PIN)
#define glcd_wr_low() ctl_port &= ~_BV(glcd_wr_PIN)
#define glcd_rd_high() ctl_port |= _BV(glcd_rd_PIN)
#define glcd_rd_low() ctl_port &= ~_BV(glcd_rd_PIN)
#define glcd_ce_high() ctl_port |= _BV(glcd_ce_PIN)
#define glcd_ce_low() ctl_port &= ~_BV(glcd_ce_PIN)
#define glcd_cd_high() ctl_port |= _BV(glcd_cd_PIN)
#define glcd_cd_low() ctl_port &= ~_BV(glcd_cd_PIN)
#define glcd_rst_high() ctl_port |= _BV(glcd_rst_PIN)
#define glcd_rst_low() ctl_port &= ~_BV(glcd_rst_PIN)
#define glcd_SET_DATADIR_OUT() (glcd_DATADIR = 0xff)
#define glcd_SET_DATADIR_IN() (glcd_DATADIR = 0x00)
//声明函数
void glcd_dput(unsigned char byte); // 写数据
//unsigned char glcd_dget(void); // 读数据
unsigned char glcd_sget(void); // 读状态
void glcd_cput(unsigned char byte); // 写命令
void glcd_setup(void); // 初始化控制线的电位
void glcd_init(void); // 初始化显存和显示方式
void glcd_xy(unsigned char x, unsigned char y); // 设置显示坐标(文本模式)
void glcd_clear_text(void); // 文本清屏
//void glcd_print(unsigned char x,unsigned char y,const char *string); // 显示字符串ROM
void glcd_print_ram(unsigned char x,unsigned char y,char *string); // 显示字符串RAM
void glcd_set_address(unsigned int addr); //设置地址
void glcd_clear_graph(void); // 图形清屏
void glcd_pixel(unsigned char column, unsigned char row, char show); //画、清点
void glcd_show(prog_char * s,int start_line,int how_many_line); //指定数据组图
void glcd_line(int x1, int y1, int x2, int y2, unsigned char show); //画直线
void glcd_circle(int x, int y, int radius, unsigned char show); //画圆
void glcd_circle_half(int x, int y, int radius, unsigned char show);//画半圆
void glcd_box(int x1, int y1, int x2, int y2, unsigned char show); //画矩形
//画线段
void glcd_degree_line(int x, int y, int degree, int inner_radius, int outer_radius, unsigned char show);
//画线段包围线
void glcd_degree_line_bold(int x, int y, int degree, int inner_radius, int outer_radius, unsigned char show);
void glcd_fill(int x1, int y1, int x2, int y2, unsigned char persent,char first); //画进度条
// 绘图坐标限制
#define glcd_XMAX 240
#define glcd_XMIN 0
#define glcd_YMAX 128
#define glcd_YMIN 0
//读取状态字节
unsigned char glcd_sget(void)
{
unsigned char glcd_status;
glcd_SET_DATADIR_IN();
glcd_cd_high(); // C/D高,读状态字节
glcd_ce_low(); // CE低,开片选信号
glcd_rd_low(); // RD低,打开读信号
_NOP();
_NOP();
glcd_status = glcd_DATA_PIN; // 读取状态字节
glcd_rd_high(); // 关闭读信号
glcd_ce_high(); // CE高,关闭片选
return(glcd_status);
}
// 写数据
void glcd_dput(unsigned char byte)
{
do {} while ((0x03 & glcd_sget()) != 0x03); // 等待屏幕可用
glcd_SET_DATADIR_OUT(); // 数据口转换为输出口
glcd_DATA_PORT = byte; // 写数据到数据口
glcd_cd_low();
glcd_ce_low(); // 低电平脉冲大于80ns
glcd_wr_low(); // 打开写数据方式
_NOP();
_NOP();
glcd_wr_high(); // WR拉高
glcd_ce_high(); // CE拉高
}
// 写命令
void glcd_cput(unsigned char byte)
{
do {} while ((0x03 & glcd_sget()) != 0x03); // 等待屏幕可用
glcd_SET_DATADIR_OUT(); // 数据口转换为输出口
glcd_DATA_PORT = byte; // 送数据到数据口
glcd_cd_high(); // C/D置高
glcd_ce_low(); // CE置低,要求大于 80ns
glcd_wr_low(); // WR置低
_NOP();
_NOP();
glcd_wr_high(); // WR轩高
glcd_ce_high(); // CE置高
}
// 读数据
/*
unsigned char glcd_dget(void)
{
unsigned char glcd_byte;
do {} while ((0x03 & glcd_sget()) != 0x03); // 等待屏幕可用
glcd_SET_DATADIR_IN(); // 设置数据口为输入口
glcd_cd_low(); // C/D置低
glcd_rd_low(); // 读置低
glcd_ce_low(); // CE置低
_NOP();
_NOP();
glcd_byte = glcd_DATA_PIN; // 读取数据
glcd_rd_high(); // RD置高
glcd_ce_high(); // CE置高
return(glcd_byte);
}
*/
//清全部32KB内存
void glcd_clear_ram(void)
{
int i;
glcd_set_address(0x0000);
for (i=0;i<0x8000;i++)
{
glcd_dput(0); // 写入数据0x00
glcd_cput(0xc0); // 0xc0为数据写入、增加指针 命令
}
}
//文本清屏
void glcd_clear_text(void)
{
int i;
glcd_set_address(glcd_T_BASE); // 设置地址为文本区基地址
for (i=0;i<480;i++)
{
glcd_dput(0); //写入数据
glcd_cput(0xc0); //0xc0为写入数据,增加指针命令
}
}
// 图形清屏
void glcd_clear_graph(void)
{
int i;
glcd_set_address(glcd_G_BASE); // 设置地址为图形区基地址
for (i=0;i<3840;i++) // 必须为3840
{
glcd_dput(0); // 写入数据0x00
glcd_cput(0xc0); // 0xc0为数据写入、增加指针 命令
}
}
// 文本方式设置显示坐标
void glcd_xy(unsigned char x, unsigned char y)
{
int addr;
addr = glcd_T_BASE + (y * glcd_BYTES_PER_ROW) + x;
glcd_set_address(addr); // 设置显示地址
}
//设置地址
void glcd_set_address(unsigned int addr){
glcd_dput((unsigned char)(addr));
glcd_dput(addr>>8);
glcd_cput(0x24); //0x24为设定地址命令
}
// 显示字符串RAM
void glcd_print_ram(unsigned char x,unsigned char y, char *string)
{
unsigned char i,c;
glcd_xy(x,y);
for (i=0;string[i]!=0;i++) {
c = string[i] - 0x20; // 转换ASCII码为屏幕内码
glcd_dput(c);
glcd_cput(0xc0); // 写字符,增加内部RAM指针
}
}
// 显示字符串ROM
void glcd_print(unsigned char x,unsigned char y, prog_char *string)
{
unsigned char i,c;
glcd_xy(x,y);
for (i=0;(pgm_read_byte(&string[i]))!=0;i++) {
c = pgm_read_byte(&string[i]) - 0x20; // 转换ASCII码为屏幕内码
glcd_dput(c);
glcd_cput(0xc0); // 写字符,增加内部RAM指针
}
}
//画、清点函数
//column为水平点数,row为垂直点数
//show=1画点,show=0清点
void glcd_pixel(unsigned char column, unsigned char row, char show)
{
int addr; // memory address of byte containing pixel to write
if( (column>=glcd_XMAX) || (row>=glcd_YMAX) )return;
addr = glcd_G_BASE + (row*glcd_BYTES_PER_ROW) + (column/8);
glcd_set_address(addr); // set LCD addr. pointer
if(show)
glcd_cput(0xf8 | (7-column%8)); // 0xf8为画点命令
else
glcd_cput(0xf0 | (7-column%8)); // 0xf0为清点命令
}
//以指定的数据进行画点
void glcd_show(prog_char * s,int start_line,int how_many_line){
int addr,i;
addr = glcd_G_BASE +start_line*30;
glcd_set_address(addr);
glcd_cput(0xB0); //自动写模式
for(i=0;i<how_many_line*30;i++){
glcd_dput(pgm_read_byte(&s[i]));
}
glcd_cput(0xB2);
}
/***********************************************************************
画一条x1,y1到x2,y2的直线
(show=1画点,show=0清点)
***********************************************************************/
void glcd_line(int x1, int y1, int x2, int y2, unsigned char show)
{
int dy ;
int dx ;
int stepx, stepy, fraction;
dy = y2 - y1;
dx = x2 - x1;
if (dy < 0)
{
dy = -dy;
stepy = -1;
}
else
{
stepy = 1;
}
if (dx < 0)
{
dx = -dx;
stepx = -1;
}
else
{
stepx = 1;
}
dy <<= 1;
dx <<= 1;
glcd_pixel(x1,y1,show);
if (dx > dy)
{
fraction = dy - (dx >> 1);
while (x1 != x2)
{
if (fraction >= 0)
{
y1 += stepy;
fraction -= dx;
}
x1 += stepx;
fraction += dy;
glcd_pixel(x1,y1,show);
}
}
else
{
fraction = dx - (dy >> 1);
while (y1 != y2)
{
if (fraction >= 0)
{
x1 += stepx;
fraction -= dy;
}
y1 += stepy;
fraction += dx;
glcd_pixel(x1,y1,show);
}
}
}
/***********************************************************************
以x,y为圆心,以radius为半径画贺
(show=1画点,show=0清点)
***********************************************************************/
void glcd_circle(int x, int y, int radius, unsigned char show)
{
int xc = 0;
int yc ;
int p ;
yc=radius;
p = 3 - (radius<<1);
while (xc <= yc)
{
glcd_pixel(x + xc, y + yc, show);
glcd_pixel(x + xc, y - yc, show);
glcd_pixel(x - xc, y + yc, show);
glcd_pixel(x - xc, y - yc, show);
glcd_pixel(x + yc, y + xc, show);
glcd_pixel(x + yc, y - xc, show);
glcd_pixel(x - yc, y + xc, show);
glcd_pixel(x - yc, y - xc, show);
if (p < 0)
p += (xc++ << 2) + 6;
else
p += ((xc++ - yc--)<<2) + 10;
}
}
//画半圆
void glcd_circle_half(int x, int y, int radius, unsigned char show)
{
int xc = 0;
int yc ;
int p ;
yc=radius;
p = 3 - (radius<<1);
while (xc <= yc)
{
// glcd_pixel(x + xc, y + yc, show);
glcd_pixel(x + xc, y - yc, show);
// glcd_pixel(x - xc, y + yc, show);
glcd_pixel(x - xc, y - yc, show);
// glcd_pixel(x + yc, y + xc, show);
glcd_pixel(x + yc, y - xc, show);
// glcd_pixel(x - yc, y + xc, show);
glcd_pixel(x - yc, y - xc, show);
if (p < 0)
p += (xc++ << 2) + 6;
else
p += ((xc++ - yc--)<<2) + 10;
}
}
//画矩形
void glcd_box(int x1, int y1, int x2, int y2, unsigned char show)
{
glcd_line(x1,y1,x2,y1,show); // up
glcd_line(x1,y2,x2,y2,show); // down
glcd_line(x2,y1,x2,y2,show); // right
glcd_line(x1,y1,x1,y2,show); // left
}
//***********************************************************************
//以x,y点为原点,以degree为角度,画一条从内径到外径之间的线段
//(show=1画点,show=0清点)
//***********************************************************************
/*
void glcd_degree_line(int x, int y, int degree, int inner_radius, int outer_radius, unsigned char show)
{
int fx,fy,tx,ty;
fx = x + (inner_radius * sin(degree * 3.14 / 180)); // ???????????????
fy = y - (inner_radius * cos(degree * 3.14 / 180));
tx = x + (outer_radius * sin(degree * 3.14 / 180));
ty = y - (outer_radius * cos(degree * 3.14 / 180));
glcd_line(fx,fy,tx,ty,show);
}
//画上函数线段的包括线
void glcd_degree_line_bold(int x, int y, int degree, int inner_radius, int outer_radius, unsigned char show)
{
int fx,fy,tx,ty;
fx = x + (inner_radius * sin(degree * 3.14 / 180)); // ???????????????
fy = y - (inner_radius * cos(degree * 3.14 / 180));
tx = x + (outer_radius * sin(degree * 3.14 / 180));
ty = y - (outer_radius * cos(degree * 3.14 / 180));
glcd_line(fx,fy,tx,ty,show);
glcd_line(fx+1,fy+1,tx+1,ty+1,show);
glcd_line(fx-1,fy-1,tx-1,ty-1,show);
}
*/
//画进度条函数
void glcd_fill(int x1, int y1, int x2, int y2, unsigned char persent,char first)
{
char M,horizon_line,horizon_line2,i,str1[10];
if(persent>100)return;
if(!first){
glcd_line(x1,y2,x2,y2,1); // down
glcd_line(x2,y1,x2,y2,1); // right
glcd_line(x1,y1,x1,y2,1); // left
first=1;
}
M=100/abs(y2-y1);
horizon_line=persent/M;
for(i=0;i<horizon_line;i++)
glcd_line(x1+2,y2-2-i,x2-2,y2-2-i,1);
horizon_line2=100/M;
for(i=horizon_line;i<horizon_line2;i++)
glcd_line(x1+2,y2-2-i,x2-2,y2-2-i,0);
sprintf(str1,"%02d%% ",persent);
glcd_print_ram( (x2+x1)/16-1 , (y2+y1)/16,str1);
}
// 初始化端口
void glcd_setup()
{
ctl_ddr=_BV(glcd_wr_PIN)|_BV(glcd_rd_PIN)|_BV(glcd_cd_PIN)|_BV(glcd_rst_PIN)|_BV(glcd_fs_PIN)|_BV(glcd_ce_PIN);
ctl_port=_BV(glcd_wr_PIN)|_BV(glcd_rd_PIN)|_BV(glcd_cd_PIN)|_BV(glcd_ce_PIN);//|_BV(glcd_fs_PIN);
_delay_ms(5);
glcd_rst_high();
}
// 初始化显存和显示模式
void glcd_init()
{
glcd_dput((unsigned char)(glcd_T_BASE));
glcd_dput(glcd_T_BASE>>8);
glcd_cput(0x40); // 0x40为设置文本存储区的基地址命令
glcd_dput(glcd_BYTES_PER_ROW);
glcd_dput(0);
glcd_cput(0x41); // 0x41为设置文本模式每行多少个字符数命令
glcd_dput((unsigned char)(glcd_G_BASE));
glcd_dput(glcd_G_BASE>>8);
glcd_cput(0x42); // 0x42为设置图形存储区基地址命令
glcd_dput(glcd_BYTES_PER_ROW);
glcd_dput(0);
glcd_cput(0x43); // 0x43为设置图形模式每行有多少个像素 命令
glcd_cput(0x81); // 模式设置: 异或 使用内部西文字库
glcd_cput(0xa7); // 光标高8线
glcd_dput(0x00);
glcd_dput(0x00);
glcd_cput(0x21); // 设置光标坐标
glcd_cput(0x9c); // 显示设置为:图形开、文本开
// 注意:如果设置显示光标,需要设定光标的位置
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -