📄 lcd.c
字号:
#include "44b0x.h"
#include "defs.h"
#include "avt.h"
/*
* COLOR MODE
*
* R G B
* 3 3 2
*/
// 液晶相关定义
#define LCD_XSIZE 680//横向
#define LCD_YSIZE 520//纵向
#define LCD_XSIZEp 640//不包含边界的屏幕大小
#define LCD_YSIZEp 480
#define HOZVAL (LCD_XSIZE-1)
#define LINEVAL (LCD_YSIZE-1)
#define MVAL_USED 0
#define CLKVAL_MONO 2
#define DISMOD_4BITS 0x1
#define DISMOD_8BITS 0x2
#define redcolor 0xe0 //红色常量
#define greecolor 0x1c //绿色常量
#define bluecolor 0x03 //蓝色常量
#define ncolor 0x20
#define SWAP(a, b) {a^=b; b^=a; a^=b;}
// VGA 显示
static UINT *DC = (UINT *)(VIDEORAM + LCD_XSIZE*35);//显存起始地址
static UCHAR attr;//前景色
static UCHAR bgcr;//背景色
struct tm theTime;//当前时间
// 颜色查找表
static const unsigned char clut[256] = {//clut离合器
0x00, 0x80, 0x10, 0x90, 0x02, 0x82, 0x12, 0xDB, 0xDB, 0xBB, 0x44, 0x64, 0x84, 0xA4, 0xC4, 0xE4,
0x08, 0x28, 0x48, 0x68, 0x88, 0xA8, 0xC8, 0xE8, 0x0C, 0x2C, 0x4C, 0x6C, 0x8C, 0xAC, 0xCC, 0xEC,
0x10, 0x30, 0x50, 0x70, 0x90, 0xB0, 0xD0, 0xF0, 0x14, 0x34, 0x54, 0x74, 0x94, 0xB4, 0xD4, 0xF4,
0x18, 0x38, 0x58, 0x78, 0x98, 0xB8, 0xD8, 0xF8, 0x1C, 0x3C, 0x5C, 0x7C, 0x9C, 0xBC, 0xDC, 0xFC,
0x01, 0x21, 0x41, 0x61, 0x81, 0xA1, 0xC1, 0xE1, 0x05, 0x25, 0x45, 0x65, 0x85, 0xA5, 0xC5, 0xE5,
0x09, 0x29, 0x49, 0x69, 0x89, 0xA9, 0xC9, 0xE9, 0x0D, 0x2D, 0x4D, 0x6D, 0x8D, 0xAD, 0xCD, 0xED,
0x11, 0x31, 0x51, 0x71, 0x91, 0xB1, 0xD1, 0xF1, 0x15, 0x35, 0x55, 0x75, 0x95, 0xB5, 0xD5, 0xF5,
0x19, 0x39, 0x59, 0x79, 0x99, 0xB9, 0xD9, 0xF9, 0x1D, 0x3D, 0x5D, 0x7D, 0x9D, 0xBD, 0xDD, 0xFD,
0x02, 0x22, 0x42, 0x62, 0x82, 0xA2, 0xC2, 0xE2, 0x06, 0x26, 0x46, 0x66, 0x86, 0xA6, 0xC6, 0xE6,
0x0A, 0x2A, 0x4A, 0x6A, 0x8A, 0xAA, 0xCA, 0xEA, 0x0E, 0x2E, 0x4E, 0x6E, 0x8E, 0xAE, 0xCE, 0xEE,
0x12, 0x32, 0x52, 0x72, 0x92, 0xB2, 0xD2, 0xF2, 0x16, 0x36, 0x56, 0x76, 0x96, 0xB6, 0xD6, 0xF6,
0x1A, 0x3A, 0x5A, 0x7A, 0x9A, 0xBA, 0xDA, 0xFA, 0x1E, 0x3E, 0x5E, 0x7E, 0x9E, 0xBE, 0xDE, 0xFE,
0x03, 0x23, 0x43, 0x63, 0x83, 0xA3, 0xC3, 0xE3, 0x07, 0x27, 0x47, 0x67, 0x87, 0xA7, 0xC7, 0xE7,
0x0B, 0x2B, 0x4B, 0x6B, 0x8B, 0xAB, 0xCB, 0xEB, 0x0F, 0x2F, 0x4F, 0x6F, 0x8F, 0xAF, 0xCF, 0xEF,
0x13, 0x33, 0x53, 0x73, 0x93, 0xB3, 0xD3, 0xF3, 0x17, 0x37, 0x57, 0x77, 0x97, 0xB7, 0xD7, 0xF7,
0x1B, 0x3B, 0x5B, 0x7B, 0x9B, 0xBB, 0xFF, 0xB6, 0x92, 0xE0, 0x1C, 0xFC, 0x03, 0xE3, 0x1F, 0xFF
};
// 徽标位图
static UCHAR logo[] = {
#include "bmp/menulogo.h"
};
static UCHAR exit[] = {
#include "bmp/exit.h"
};
static UCHAR save[] = {
#include "bmp/save.h"
};
static UCHAR set_ok[] = {
#include "bmp/set_ok.h"
};
// 获取前景色
int
GetTextColor(void) {
return attr;
}
// 设置前景色
int
SetTextColor(int c) {//256色
int old = attr;
attr = clut[c];
return old;
}
// 设置前景色(不使用clut颜色查找表)
int
SetTextColor2(int c) {
int old = attr;
attr = c;
return old;
}
// 设置背景色
int
SetBgColor(int c) {
int old = bgcr;
bgcr = c;
return old;
}
// 清屏
void
Lcd_Clr(void) {
UINT cc = bgcr | (bgcr << 8) | (bgcr << 16) | (bgcr << 24);
UINT i;
//cc=429496729;
for(i = 0; i < LCD_YSIZE*LCD_XSIZE/4; i++)//除4,每次4位,4位相同的值
DC[i] = cc;
}
// 填充屏幕区域
//
// X0: 区域左上角横坐标
// Y0: 区域左上角纵坐标
// w: 区域宽度
// h: 区域高度
// color: 填充色
//填充屏幕想要显示的颜色
void
Lcd_FillRect(UINT X0, UINT Y0,UINT w , UINT h, UCHAR color) {
UINT i;
UCHAR *Plcdbu = (UCHAR*)DC;//显存初始地址
ASSERT(X0 + w < LCD_XSIZEp);
ASSERT(Y0 + h < LCD_YSIZEp);
Plcdbu = Plcdbu + (X0 + (LCD_XSIZE * Y0));
for(i = 0; i < h; i++) {
Memset(Plcdbu, color, w);//分配空间
Plcdbu += LCD_XSIZE;//按行进行分配颜色
}
}
// 反白屏幕区域
//
// X0: 区域左上角横坐标
// Y0: 区域左上角纵坐标
// w: 区域宽度
// h: 区域高度
//在屏幕要求的区域反成对色
void
Lcd_NotRect(UINT X0, UINT Y0,UINT w , UINT h) {
UINT i, j;
UCHAR *Plcdbu = (UCHAR*)DC;
ASSERT(X0 + w < LCD_XSIZEp);
ASSERT(Y0 + h < LCD_YSIZEp);//断言
Plcdbu = Plcdbu + (X0 + (LCD_XSIZE * Y0));//
for(i = 0; i < h; i++) {
for(j = 0; j < w; j++)
Plcdbu[j] ^= 0xFF;
Plcdbu += LCD_XSIZE;
}
}
// 清除屏幕区域(使用clut颜色查找表)
//
// X0: 区域左上角横坐标
// Y0: 区域左上角纵坐标
// w: 区域宽度
// h: 区域高度
// color: 填充色
//对应 Lcd_FillRect 函数,调色板
void
Lcd_Clrxy(UINT X0, UINT Y0,UINT X , UINT Y,UCHAR color) {
UINT i;
UCHAR *Plcdbu = (UCHAR*)DC;
ASSERT(X0 + X < LCD_XSIZEp);
ASSERT(Y0 + Y < LCD_YSIZEp);
color = clut[color];
Plcdbu = Plcdbu + (X0 + (LCD_XSIZE * Y0));
for(i = 0; i < Y; i++) {
Memset(Plcdbu, color, X);
Plcdbu += LCD_XSIZE;
}
}
// 画点
//
// x: 点横坐标
// y: 点纵坐标
//cr: 点颜色
// 调色板
void
SetPixel(UINT x, UINT y, UCHAR cr) {
ASSERT(x < LCD_XSIZEp);
ASSERT(y < LCD_YSIZEp);
*((UCHAR*)DC + x + y * LCD_XSIZE) = clut[cr];
}
// 获取点颜色
//
// x: 点横坐标
// y: 点纵坐标
int
GetPixel(UINT x, UINT y) {
ASSERT(x < LCD_XSIZEp);
ASSERT(y < LCD_YSIZEp);
return *((UCHAR*)DC + x + y * LCD_XSIZE);
}
// 画横线
//
// x1: 起点横坐标
// x2: 终点横坐标
// y: 起点纵坐标
// c: 线颜色
// 调色板
void
DrawHorzLine(UINT x1, UINT x2, UINT y, UCHAR c) {
ASSERT(x2 < LCD_XSIZEp);
ASSERT(x1 < LCD_XSIZEp);
ASSERT(x1 <= x2);
ASSERT(y < LCD_YSIZEp);
if(x1 > x2)
SWAP(x1,x2);
Memset((UCHAR *)DC + x1 + y*LCD_XSIZE, clut[c], x2 - x1 + 1);
}
// 画竖线
//
// x: 起点横坐标
// y1: 起点纵坐标
// y2: 终点纵坐标
// c: 线颜色
// 调色板
/* Draw a vertical line from x,y1 to x,y2 including final point*/
void
DrawVertLine(UINT x, UINT y1, UINT y2, UCHAR c)
{
UCHAR * addr;
ASSERT(x < LCD_XSIZEp);
ASSERT(y1 < LCD_YSIZEp);
ASSERT(y2 < LCD_YSIZEp);
ASSERT(y1 <= y2);
c = clut[c];
if(y1 > y2)
SWAP(y1, y2);
addr = (UCHAR *)DC + x + y1*LCD_XSIZE;
while(y1++ <= y2) {
*addr = c;
addr += LCD_XSIZE;
}
}
// 画线
//
// x1: 起点横坐标
// y1: 终点纵坐标
// x2: 起点横坐标
// y2: 终点纵坐标
// c: 线颜色
// 调色板
void DrawLine(UINT x1, UINT y1, UINT x2, UINT y2, UCHAR color)
{
UINT rem, xdelta, ydelta;
UCHAR *pdc;
ASSERT(x1 < LCD_XSIZEp);
ASSERT(y1 < LCD_YSIZEp);
ASSERT(x2 < LCD_XSIZEp);
ASSERT(y2 < LCD_YSIZEp);
if(x1 == x2) {
DrawVertLine(x1,y1,y2,color);
return;
}
if(y1 == y2) {
DrawHorzLine(x1,x2,y1,color);
return;
}
//
// x1 < x2
// y1 < y2
//
if(x1 > x2)
SWAP(x1,x2);
if(y1 > y2)
SWAP(y1, y2);
pdc = (UCHAR*)DC + x1 + y1 * LCD_XSIZE;
color = clut[color];
xdelta = x2 - x1;
ydelta = y2 - y1; //注:没有算最左上角点
if (xdelta >= ydelta)
{
rem = xdelta >> 1;//即 rem=xdelta/2;
while (x1 != x2)
{
x1++;
pdc++;
rem += ydelta;
if (rem >= xdelta)
{
rem -= xdelta;
y1++;
pdc += LCD_XSIZE;
*pdc = color;
}//if
else
*pdc = color;
}//while
}//if
else
{
rem = ydelta >> 1;//即 rem=ydelta/2;
while (y1 != y2) {
y1++;
pdc += LCD_XSIZE;
rem += xdelta;
if (rem >= ydelta) {
rem -= ydelta;
x1--;
pdc++;
*pdc = color;
}
else
*pdc = color;
}
}//else
}
//
// 填充屏幕区域(使用clut颜色查找表)
//
// x1: 起点横坐标
// y1: 终点纵坐标
// x2: 起点横坐标
// y2: 终点纵坐标
// c: 方框颜色
// 调色板
void
FillRect(UINT x1, UINT y1, UINT x2, UINT y2, UCHAR c)
{
UCHAR *addr;
UINT x;
ASSERT(x1 < LCD_XSIZEp);
ASSERT(y1 < LCD_YSIZEp);
ASSERT(x2 < LCD_XSIZEp);
ASSERT(y2 < LCD_YSIZEp);
if(x1 > x2)
SWAP(x1, x2);
if(y1 > y2)
SWAP(y1, y2);
c = clut[c];
addr = (UCHAR *)DC + y1*LCD_XSIZE;
while(y1++ <= y2)
{
for(x = x1; x < x2; x++)//没有算x2所在列
addr[x] = c;
addr += LCD_XSIZE;
}
}
// 画矩形框
// x1: 起点横坐标
// y1: 终点纵坐标
// x2: 起点横坐标
// y2: 终点纵坐标
// c: 方框颜色
void
DrawRect(UINT x1, UINT y1, UINT x2, UINT y2, UCHAR c)
{
DrawVertLine(x1, y1, y2, c);
DrawVertLine(x2, y1, y2, c);
DrawHorzLine(x1, x2, y1, c);
DrawHorzLine(x1, x2, y2, c);
}
// 取整数字
// addr: 数据地址
static USHORT
readw(const void *addr) {
const UCHAR *bPtr = (UCHAR *)addr;
CHECK_PTR(addr);
return *bPtr + ((USHORT)bPtr[1]<<8);//bptr0,BPTR1高低8位
}
// 取整数双字
// addr: 数据地址
static UINT
readl(const void *addr) {
const UCHAR *bPtr = (UCHAR *)addr;
CHECK_PTR(addr);
return *bPtr + ((UINT)bPtr[1]<<8) + ((UINT)bPtr[2]<<16) + ((UINT)bPtr[3]<<24);
}
// 显示位图
// x: 横坐标
// y: 纵坐标
// bmp: 位图文件数据
//
void
DrawBitmap(UINT x, UINT y, UCHAR *bmp) {
UINT w, h;
int i, j;
UCHAR *bp, *dc;
ASSERT(x < LCD_XSIZEp);
ASSERT(y < LCD_YSIZEp);
// const UCHAR bmpp
CHECK_PTR(bmp);
// 'BM'
if(readw(bmp) != 0x4d42)
return;
// w: 位图宽度
w = readl(bmp + 0x12);
// h: 位图高度
h = readl(bmp + 0x16);
// bp: 指向位图数据
bp = bmp + readl(bmp + 10); // dwOffBits
for(i = h - 1; i >= 0; i--) {
dc = (UCHAR*)DC + x + (i + y) * LCD_XSIZE;//写入图象数据到显卡内存的初始地址
for(j = 0; j < w; j++)
*dc++ = clut[*bp++];//根据图象的信息来确定将显示的颜色
while(j % 4) {
j++;
bp++;
}
}
}
// 显示位图(位图数据经过压缩)
// x: 横坐标
// y: 纵坐标
// bmp: 位图文件数据(数据经过压缩)
// sz: 数据大小
//
void
drawbmp(UINT x, UINT y, UCHAR *bmp, UINT sz)
{
ASSERT(x < LCD_XSIZEp);
ASSERT(y < LCD_YSIZEp);
CHECK_PTR(bmp);
// 解压位图文件
bmp = gunzip(bmp, sz, 0);
if(!bmp)
return;
// 显示
DrawBitmap(x, y, bmp);
kfree(bmp);
}
/////////////////////////////////////////
/*
* 七段码数字转换表
*
* 5
* |------------|
* | |
* 6 | | 4
* | 7 |
* |------------|
* | |
* 0 | | 2
* | 1 | 3
* |------------| 。
*
*
* X 7 6 5 4 3 2 1 0 Hex
*---------------------------
* 0 0 1 1 1 0 1 1 1 77
* 1 0 0 0 1 0 1 0 0 14
* 2 1 0 1 1 0 0 1 1 b3
* 3 1 0 1 1 0 1 1 0 b6
* 4 1 1 0 1 0 1 0 0 d4
* 5 1 1 1 0 0 1 1 0 e6
* 6 1 1 1 0 0 1 1 1 e7
* 7 0 0 1 1 0 1 0 0 34
* 8 1 1 1 1 0 1 1 1 f7
* 9 1 1 1 1 0 1 1 0 f6
*/
/* 10个数字的转换表 */
#define D0 0x77
#define D1 0x14
#define D2 0xb3
#define D3 0xb6
#define D4 0xd4
#define D5 0xe6
#define D6 0xe7
#define D7 0x34
#define D8 0xf7
#define D9 0xf6
UCHAR LED_COLOR;
/* 10个数字的映射数组 */
static UCHAR DTbl[10] = {D0, D1, D2, D3, D4, D5, D6, D7, D8, D9};
// 显示一个七段码数
// x: 横坐标
// y: 纵坐标
// n: 待显示数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -