📄 lcd0724.c
字号:
/*************************************************
* Lcd0724.c
* Lcd0724 module's operation
* By Liu Lixun
*************************************************/
#include "Lcd0724.h"
#include "91x_lib.h"
#define MAXY 127
#define MAXX 63
#define MAXP 7
#define LCD_DATA ((unsigned char *)(0x34000001))
#define LCD_CMD ((unsigned char *)(0x34000000))
typedef struct _DOT
{
ulong color;
ulong bgcolor;
uchar page;
uchar x;
uchar y;
uchar boffset; // offset of a byte in a page
uchar bmask; // mask of a byte if not snap to page
uchar mode; // 0 for direct write and 1 for xor write
}DOT;
static DOT curdot; // cursor dot
static unsigned char Contrast = 0x14;
//static void dummy1(void);
//static void dwr(unsigned char da);
#define dwr(da) *LCD_DATA = da
//static uchar drd(void);
#define drd() (*LCD_DATA)
//static void cwr(unsigned char command);
#define cwr(cmd) *LCD_CMD = cmd
//static uchar srd(void);
#define srd() (*LCD_CMD)
static bool busy(void);
static void setaddr(uchar page, uchar column);
static void sdelay(void);
// static void enterrmw(void);
#define enterrmw() cwr(0xE0)
// static void exitrmw(void);
#define exitrmw() cwr(0xEE)
#define dummy(); ;
uchar Lcd0724Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// Config GPIO0.3 as output, Alt output 1.
GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt1;
GPIO_Init(GPIO0, &GPIO_InitStructure);
GPIO_WriteBit(GPIO0, GPIO_Pin_3, Bit_RESET);
// reset lcd
cwr(0xE2);
// display off
busy();
cwr(0xAE);
// normal display A7 for invers //
busy();
cwr(0xA6);
// set com scan from COM[N-1] to COM[0]
busy();
cwr(0xC8); // c0 for 0 to N-1
// set LCD bias
busy();
cwr(0xA3);
// internal power supply
cwr(0x2C); // set VC
sdelay();
cwr(0x2E); // set VR
sdelay();
cwr(0x2F); // set VF
// regulator resister
cwr(0x24); //(1+Rb/Ra)=5.0;
sdelay();
// set multiplex ratio to 64
busy();
cwr(0xA8);
busy();
cwr(0x3F);
// set display offset to 0 //
busy();
cwr(0x10); // (0xD3)
busy();
cwr(0x00);
// set display start line to 0 //
busy();
cwr(0x60); // 40
// remap seg0 to column 0 //
busy();
cwr(0xA0);
// entire display off A5 for on //
busy();
// cwr(0xA5);
cwr(0xA4);
// set contrast control //
busy();
cwr(0x81);
busy();
cwr(0x12); // 0x3F max
Contrast = 0x12;
// display on
busy();
cwr(0xAF);
return 0;
}
void Lcd0724SetCursor(uint x, uint y)
{
curdot.x = x & 0x3f;
curdot.y = y & 0x7f;
curdot.page = curdot.x >> 3;
curdot.boffset = curdot.x & 0x07;
curdot.bmask = (1 << curdot.boffset) - 1;
}
uint Lcd0724GetX(void)
{
return curdot.x;
}
uint Lcd0724GetY(void)
{
return curdot.y;
}
void Lcd0724SetColor(ulong color)
{
curdot.color = color;
}
ulong Lcd0724GetColor(void)
{
return curdot.color;
}
void Lcd0724SetBackColor(ulong color)
{
curdot.bgcolor = color;
}
ulong Lcd0724GetBackColor(void)
{
return curdot.bgcolor;
}
void Lcd0724SetMode(uchar mode)
{
curdot.mode = mode;
}
uchar Lcd0724GetMode(void)
{
return curdot.mode;
}
void Lcd0724PutDotmap(DOTMAP *block)
{
uint i, j;
uchar page = curdot.page;
uchar od, nw;
// set addr to cursor
setaddr(curdot.page, curdot.y);
if(curdot.boffset == 0)
{
for(i=0; i<block->pages; i++)
{
for(j=0; (j<block->pagebytes) && (j<=MAXY); j++)
{
nw = block->dots[i][j];
if(!curdot.color)
nw ^= 0xff;
if(curdot.mode)
{
enterrmw();
od = drd(); // dummy read
od = drd();
exitrmw();
nw ^= od;
}
dwr(nw);
}
page += 1;
if(page > MAXP)
page = 0;
setaddr(page, curdot.y);
}
}
else
{
// 1st page
for(j=0; (j<block->pagebytes) && (j<=MAXY); j++)
{
enterrmw();
// insert a dummy read (SDS1305 require a dummy read
// operation at the begining of each continuous data
// read
od = drd();
// read the old data
od = drd();
exitrmw();
nw = block->dots[0][j];
//// check mode
if(!curdot.color)
nw ^= 0xff;
nw <<= curdot.boffset;
if(curdot.mode)
{
nw ^= od;
// nw &= ~curdot.bmask;
}
od = (od & curdot.bmask) | nw;
//// write
dwr(od);
}
// goto next page
page += 1;
if(page > MAXP)
page = 0;
setaddr(page, curdot.y);
// loop middle pages
for(i=1; i<block->pages; i++)
{
for(j=0; (j<block->pagebytes) && (j<=MAXY); j++)
{
nw = (block->dots[i-1][j] >> (8-curdot.boffset)) |
(block->dots[i][j] << curdot.boffset);
if(!curdot.color)
nw ^= 0xff;
if(curdot.mode)
{
enterrmw();
od = drd();
od = drd();
exitrmw();
nw ^= od;
}
dwr(nw);
}
page += 1;
if(page > MAXP)
page = 0;
setaddr(page, curdot.y);
}
// last pages
for(j=0; (j<block->pagebytes) && (j<=MAXY); j++)
{
enterrmw();
// insert a dummy read
od = drd();
// read the old data
od = drd();
exitrmw();
nw = block->dots[block->pages-1][j];
if(!curdot.color)
nw ^= 0xff;
nw >>= 8 - curdot.boffset;
if(curdot.mode)
{
nw ^= od;
}
od = (od & ~curdot.bmask) | nw;
dwr(od);
}
}
// set new cursor to the end of the block
curdot.y += block->pagebytes;
}
void Lcd0724PutBar(uint x1, uint y1, uint x2, uint y2)
{
uint i, j;
uchar page1, page2;
uchar mask1, mask2;
uchar boffset1, boffset2;
uchar bytes, pages;
uchar od, nw;
x1 &= 0x3f;
x2 &= 0x3f;
y1 &= 0x7f;
y2 &= 0x7f;
if(x1 > x2)
{
i = x1;
x1 = x2;
x2 = i;
}
if(y1 > y2)
{
i = y1;
y1 = y2;
y2 = i;
}
page1 = x1 >> 3;
boffset1 = x1 & 0x07;
mask1 = (1 << boffset1) - 1;
page2 = x2 >> 3;
boffset2 = x2 & 0x07;
mask2 = (0xff << (boffset2+1));
bytes = y2+1-y1;
pages = page2 - page1 + 1;
if(pages <= 1)
mask1 = mask1 | mask2;
setaddr(page1, y1);
// 1st page
for(j=0; j<bytes; j++)
{
enterrmw();
od = drd();
od = drd();
exitrmw();
// check mode
if(curdot.color)
nw = od | ~mask1;
else
nw = od & mask1;
if(curdot.mode)
nw ^= od & ~mask1;
//// write
dwr(nw);
}
// goto next page
page1 += 1;
if((page1 > page2) || (page1 > MAXP))
return;
setaddr(page1, y1);
// loop middle pages
for(i=1; i<pages-1; i++)
{
for(j=0; j<bytes; j++)
{
if(curdot.color)
nw = 0xff;
else
nw = 0;
if(curdot.mode)
{
enterrmw();
od = drd();
od = drd();
exitrmw();
nw ^= od;
}
dwr(nw);
}
page1 += 1;
if(page1 > MAXP)
return;
setaddr(page1, y1);
}
// last pages
for(j=0; j<bytes; j++)
{
enterrmw();
od = drd();
od = drd();
exitrmw();
if(curdot.color)
nw = od | ~mask2;
else
nw = od & mask2;
if(curdot.mode)
{
nw ^= od & ~mask2;
}
dwr(nw);
}
}
void Lcd0724PutPixel(uint x, uint y)
{
uchar c, n;
uchar page, mask;
if((x > MAXX) || (y > MAXY))
return;
page = (x & 0x3f) >> 3;
y &= 0x7f;
mask = 1 << (x & 0x07);
setaddr(page, y);
enterrmw();
// insert empty read for 1305
c = drd();
// read data
c = drd();
exitrmw();
if(curdot.color)
n = c | mask;
else
n = c & ~mask;
if(curdot.mode)
n ^= c & mask;
dwr(n);
}
void Lcd0724Clear(void)
{
uchar i, j, c;
if(curdot.bgcolor)
c = 0xff;
else
c = 0;
for(i=0; i<=MAXP; i++)
{
setaddr(i, 0);
for(j=0; j<=MAXY; j++)
{
dwr(c);
}
}
}
void Lcd0724Power(uchar mode)
{
switch(mode)
{
case 0: // off
cwr(0xAE);
break;
case 0xff: // on
cwr(0xAF);
break;
default: // dim on
cwr(0xAF);
}
}
void Lcd0724SetContrast(int value)
{
int i = Contrast;
i += value;
if(i < 0)
i = 0;
else if(i > 0x3E)
i = 0x3E;
Contrast = i;
cwr(0x81);
cwr(Contrast);
}
void Lcd0724SetBright(int value)
{
if(value >= 0)
GPIO_WriteBit(GPIO0, GPIO_Pin_3, Bit_RESET);
else
GPIO_WriteBit(GPIO0, GPIO_Pin_3, Bit_SET);
}
// ************************** internal static functions *********************************
void setaddr(uchar page, uchar column)
{
// set page address
cwr(0xB0 + (page & 0x07)); // cwr(0x22), cwr(curpage), cwr(MAXP);
column += 1;
if(column > MAXY)
column = 0;
// set column address
cwr(0x10 + (column >> 4)); // cwr(0x21), cwr(cury), cwr(MAXY);
cwr(0x00 + (column & 0x0f));
}
#if 0
void dummy1(void)
{
// just delay some time;
//uint i;
//for(i=0; i<100; i++);
}
#endif
bool busy(void)
{
if(srd() & 0x80)
return TRUE;
else
return FALSE;
}
void sdelay(void)
{
u16 i;
for(i=1; i; i++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -