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

📄 lcd0724.c

📁 基于三星0724芯片的液晶驱动程序
💻 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 + -