lcd.c源码:

#define GPECON  (*((volatile unsigned long *)0x7F008080))

#define GPEDAT  (*((volatile unsigned long *)0x7F008084))

#define GPFCON  (*((volatile unsigned long *)0x7F0080A0))

#define GPFDAT  (*((volatile unsigned long *)0x7F0080A4))

#define GPICON  (*((volatile unsigned long *)0x7F008100))

#define GPJCON  (*((volatile unsigned long *)0x7F008120))

// display controller 

#define MIFPCON     (*((volatile unsigned long *)0x7410800C))

#define SPCON         (*((volatile unsigned long *)0x7F0081A0))

#define VIDCON0      (*((volatile unsigned long *)0x77100000))

#define VIDCON1      (*((volatile unsigned long *)0x77100004))

#define VIDTCON0     (*((volatile unsigned long *)0x77100010))

#define VIDTCON1     (*((volatile unsigned long *)0x77100014))

#define VIDTCON2     (*((volatile unsigned long *)0x77100018))

#define WINCON0      (*((volatile unsigned long *)0x77100020))

#define VIDOSD0A      (*((volatile unsigned long *)0x77100040))

#define VIDOSD0B      (*((volatile unsigned long *)0x77100044))

#define VIDOSD0C      (*((volatile unsigned long *)0x77100048))

#define VIDW00ADD0B0      (*((volatile unsigned long *)0x771000A0))

#define VIDW00ADD1B0      (*((volatile unsigned long *)0x771000D0))

#define VIDW00ADD2          (*((volatile unsigned long *)0x77100100))

#define WPALCON                (*((volatile unsigned long *)0x771001A0))

#define WIN0_PALENTRY0      0x77100400

#define  VSPW         9

#define  VBPD          1

#define  LINEVAL     271

#define  VFPD          1

#define  HSPW         40    

#define  HBPD          1

#define  HOZVAL      479

#define  HFPD          1

#define LeftTopX     0

#define LeftTopY     0

#define RightBotX   479

#define RightBotY   271

#define FRAME_BUFFER   0x54000000

unsigned int fb_base_addr;

unsigned int bpp;

unsigned int xsize;

unsigned int ysize;

void palette_init(void)

{

    int i;

    volatile unsigned long *p = (volatile unsigned long *)WIN0_PALENTRY0; //调色板地址

    

    WPALCON |= (1<<9);   // 允许CPU修改调色板 

    WPALCON &= ~(0x7);   

    WPALCON |= 1;            // 调色板的数据格式: 24-bit ( 8:8:8 ) 

    p[0] = 0x000000;          //只初始化了调色板的前五格的颜色值

    p[1] = 0x00ff00;

    p[2] = 0xff0000;

    p[3] = 0x0000ff;

    p[4] = 0xffffff;

    for (i = 0; i <256; i++)  //用调色板以后显存的bpp=8,8最大能表示256个地址,也就是调色板最大有256项

    {

        //p[i] = ;

    }

    

    WPALCON &= ~(1<<9);   // 禁止CPU访问调色板 

}

void clean_screem(void)

{

    int x;

    int y;

    int cnt = 0;

    

    volatile unsigned char *p = (volatile unsigned char *)fb_base_addr;

    for (x = 0; x <=HOZVAL; x++)

        for (y = 0; y <= LINEVAL; y++)

            p[cnt++] = 0;

}

void lcd_init(void)

{

    // 1. 设置相关GPIO引脚用于LCD 

    GPICON = 0xaaaaaaaa;    // gpi0~gpi15用作lcd_vd[0~15] 

    GPJCON = 0xaaaaaaa;     // gpj0~gpi11用作lcd 

    //GPFCON &= ~(0x3<<28);

    //GPFCON |=  (1<<28);    // GPF14用作背光使能信号 

    GPECON &= ~(0xf);

    GPECON |= (0x1);             // GPE0用作LCD的on/off信号 

    // 2. 初始化6410的display controller 

    // 2.1 hsync,vsync,vclk,vden的极性和时间参数

    // 2.2 行数、列数(分辨率),象素颜色的格式

    // 2.3 分配显存(frame buffer),写入display controller

    MIFPCON &= ~(1<<3);   // Normal mode 

    SPCON    &= ~(0x3);

    SPCON    |= 0x1;              // RGB I/F style 

#if 0

    VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6));     // RGB I/F, RGB Parallel format,  

    // vclk== 27MHz Ext Clock input / (CLKVAL+1) = 27/3 = 9MHz 

    VIDCON0 |= ((2<<6) | (1<<4) | (0x3<<2));      

#else

    VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6)  | (3<<2));     // RGB I/F, RGB Parallel format,  

    VIDCON0 |= ((14<<6) | (1<<4) );      // vclk== HCLK / (CLKVAL+1) = 133/15 = 9MHz 

#endif

    VIDCON1 &= ~(1<<7);               // 在vclk的下降沿获取数据 

    VIDCON1 |= ((1<<6) | (1<<5));  // HSYNC高电平有效, VSYNC高电平有效, 

    VIDTCON0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);

    VIDTCON1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);

    VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);

    WINCON0 &= ~(0xf << 2);

    WINCON0 |= (0x3<<2) | (1<<17);    // 8 BPP (palletized), byte swap 

    VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);

    VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);

    VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1) / 4;

    VIDW00ADD0B0 = FRAME_BUFFER;

    VIDW00ADD1B0 =  (((HOZVAL + 1)*1 + 0) * (LINEVAL + 1)) & (0xffffff);

    // VBASEL = VBASEU + (LINEWIDTH+OFFSIZE) x (LINEVAL+1) 

    //        = 0 + (480*1 + 0) * 272

    //        = 

    //VIDW00ADD2 =  HOZVAL + 1;

    

    // 设置调色板 

    palette_init();    

    pwm_set(2);

                                    

    fb_base_addr = FRAME_BUFFER;

    xsize = HOZVAL + 1;

    ysize = LINEVAL + 1;

    bpp   = 8;

    clean_screem();

}

void backlight_enable(void)

{

    //GPFDAT |= (1<<14);

}

void backlight_disable(void)

{

    //GPFDAT &= ~(1<<14);

}

void lcd_on(void)

{

    GPEDAT |= (1<<0);

    // 等待10 frame 

}

void lcd_off(void)

{

    GPEDAT &= ~(1<<0);

}

void displaycon_on(void)

{

    VIDCON0 |= 0x3;

    WINCON0 |= 1;   //6410的lcd控制器有多个窗口,这里只使能了一个窗口

}

void displaycon_off(void)

{

    VIDCON0 &= ~0x3;

    WINCON0 &= ~1;   //6410的lcd控制器有多个窗口,这里只使能了一个窗口

}

void lcd_enable(void)

{

    // 使能LCD本身 

    lcd_on();

    

    // 打开背光 

    //backlight_enable();

    pwm_start();

    

    // 使能display controller 

    displaycon_on();

}

void lcd_disable(void)

{

    // 关闭背光 

    // 关闭LCD本身 

    // 关闭display controller 

}

void draw_line(void)

{

    //不用调色板的时候画线传入的是24位颜色值,用调色板以后传入的是在调色板中的颜色索引值

    DrawLine(0,0, 0,271, 0);

    DrawLine(0,0, 479,0, 1);

    DrawLine(0,0, 479,271, 2);

    DrawLine(0,271, 479,0, 3);

    DrawLine(0,271, 479,271, 1);

    DrawLine(479,271, 479,0, 2);

    DrawLine(0,136, 479,136, 3);

    DrawLine(240,0, 240,271, 1);

}

void display_red(void)

{

    volatile unsigned char *p = (volatile unsigned char *)FRAME_BUFFER;

    int x, y;

    int cnt = 0;

    unsigned char colors[] = {0, 1, 2, 3};

    static int color_idx = 0;

    

    for (y = 0; y <= LINEVAL; y++)

    {

        for (x = 0; x <= HOZVAL; x++)

        {

            p[cnt++] =colors[color_idx] ;  // red 

        }

    }

    color_idx++;

    if (color_idx == 5)

        color_idx = 0;

}

void lcd_test(void)

{

    unsigned char c;

    static int lcdon = 0;

    static int blon = 0;

    static int dispon = 0;

    lcd_init();

    

    while (1)

    {

        printf("********LCD TEST MENU********\n\r");

        printf("[L] enable/disable LCD\n\r");

        printf("[B] enable/disable back light\n\r");

        printf("[C] enable/disable s3c6410 display controller\n\r");

        printf("[D] display color\n\r");

        printf("[I]  draw line\n\r");

        printf("[Q] quit\n\r");

        do {

            c = getc();

            if (c == '\n' || c == '\r')

            {

                printf("\n\r");

            }

            else

            {

                putc(c);

            }

        } while (c == '\n' || c == '\r');

        switch (c) {

            case 'l':

            case 'L':

            {

                if (lcdon)

                {

                    lcd_off();

                    printf("LCD off\n\r");

                }

                else

                {

                    lcd_on();

                    printf("LCD on\n\r");

                }

                lcdon = !lcdon;

                break;

            }

            case 'b':

            case 'B':

            {

                pwm_menu();

                break;

            }

            case 'c':

            case 'C':

            {

                if (dispon)

                {

                    displaycon_off();

                    printf("Display controller off\n\r");

                }

                else

                {

                    displaycon_on();

                    printf("Display controller on\n\r");

                }

                blon = !blon;

                break;

            }

            case 'd':

            case 'D':

            {

                display_red();

                break;

            }

            case 'i':

            case 'I':

            {

                draw_line();

                break;

            }

            case 'q':

            case 'Q':

            {

                return ;

                break;

            }

        }

    }

}

=====================================================================

framebuffer.c源码:

// FILE: framebuffer.c

// 实现在framebuffer上画点、画线、画同心圆、清屏的函数

#include "types.h"

#include "framebuffer.h"

extern unsigned int fb_base_addr;

extern unsigned int bpp;

extern unsigned int xsize;

extern unsigned int ysize;

//typedef UINT32 FB_24BPP[272][480];

// 画点

// 输入参数:

//     x、y : 象素坐标

//     color: 颜色值

//         对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),

//     需要转换为5:6:5格式

//         对于8BPP: color为调色板中的索引值,

//     其颜色取决于调色板中的数值

void PutPixel(UINT32 x, UINT32 y, UINT32 color)

{

    UINT8 red,green,blue;

    switch (bpp){

        case 24:

        {

            //bpp=24位,但是为了对齐会浪费一个字节,一共4字节32位

            UINT32 *addr = (UINT32 *)fb_base_addr + (y * xsize + x);

            *addr =  color;

            break;

        }

        case 16:

        {

            UINT16 *addr = (UINT16 *)fb_base_addr + (y * xsize + x);

            red   = (color >> 19) & 0x1f;

            green = (color >> 10) & 0x3f;

            blue  = (color >>  3) & 0x1f;

            color = (red << 11) | (green << 5) | blue; // 格式5:6:5

            *addr = (UINT16) color;

            break;

        }

        

        case 8:

        {

            UINT8 *addr = (UINT8 *)fb_base_addr + (y * xsize + x);

            *addr = (UINT8) color;  // 调色板的索引值 

            break;

        }

        default:

            break;

    }

}

// 画线

// 输入参数:

//     x1、y1 : 起点坐标

//     x2、y2 : 终点坐标

//     color  : 颜色值

//         对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),

//     需要转换为5:6:5格式

//         对于8BPP: color为调色板中的索引值,

//     其颜色取决于调色板中的数值

void DrawLine(int x1,int y1,int x2,int y2,int color)

{

    int dx,dy,e;

    dx=x2-x1; 

    dy=y2-y1;

    

    if(dx>=0)

    {

        if(dy >= 0) // dy>=0

        {

            if(dx>=dy) // 1/8 octant

            {

                e=dy-dx/2;

                while(x1<=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1+=1;e-=dx;}   

                    x1+=1;

                    e+=dy;

                }

            }

            else        // 2/8 octant

            {

                e=dx-dy/2;

                while(y1<=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1+=1;e-=dy;}   

                    y1+=1;

                    e+=dx;

                }

            }

        }

        else           // dy<0

        {

            dy=-dy;   // dy=abs(dy)

            if(dx>=dy) // 8/8 octant

            {

                e=dy-dx/2;

                while(x1<=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1-=1;e-=dx;}   

                    x1+=1;

                    e+=dy;

                }

            }

            else        // 7/8 octant

            {

                e=dx-dy/2;

                while(y1>=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1+=1;e-=dy;}   

                    y1-=1;

                    e+=dx;

                }

            }

        }   

    }

    else //dx<0

    {

        dx=-dx;     //dx=abs(dx)

        if(dy >= 0) // dy>=0

        {

            if(dx>=dy) // 4/8 octant

            {

                e=dy-dx/2;

                while(x1>=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1+=1;e-=dx;}   

                    x1-=1;

                    e+=dy;

                }

            }

            else        // 3/8 octant

            {

                e=dx-dy/2;

                while(y1<=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1-=1;e-=dy;}   

                    y1+=1;

                    e+=dx;

                }

            }

        }

        else           // dy<0

        {

            dy=-dy;   // dy=abs(dy)

            if(dx>=dy) // 5/8 octant

            {

                e=dy-dx/2;

                while(x1>=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1-=1;e-=dx;}   

                    x1-=1;

                    e+=dy;

                }

            }

            else        // 6/8 octant

            {

                e=dx-dy/2;

                while(y1>=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1-=1;e-=dy;}   

                    y1-=1;

                    e+=dx;

                }

            }

        }   

    }

}

// 绘制同心圆

void Mire(void)

{

    UINT32 x,y;

    UINT32 color;

    UINT8 red,green,blue,alpha;

    for (y = 0; y < ysize; y++)

        for (x = 0; x < xsize; x++){

            color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;

            red   = (color/8) % 256;

            green = (color/4) % 256;

            blue  = (color/2) % 256;

            alpha = (color*2) % 256;

            color |= ((UINT32)alpha << 24);

            color |= ((UINT32)red   << 16);

            color |= ((UINT32)green << 8 );

            color |= ((UINT32)blue       );

            PutPixel(x,y,color);

        }

}

 

// 将屏幕清成单色

// 输入参数:

//     color: 颜色值

//         对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),

//     需要转换为5:6:5格式

//         对于8BPP: color为调色板中的索引值,

//     其颜色取决于调色板中的数值

void ClearScr(UINT32 color)

{   

    UINT32 x,y;

    

    for (y = 0; y < ysize; y++)

        for (x = 0; x < xsize; x++)

            PutPixel(x, y, color);

}

#define FONTDATAMAX 2048

extern const unsigned char fontdata_8x8[FONTDATAMAX];

void lcd_putc(unsigned char c)

{

    static int x = 0;

    static int y = 0;

    int i,j;

    unsigned char line_dots;

    // 获得字模 

    unsigned char *char_dots = fontdata_8x8 + c * 8;    

    // 在framebuffer里描点 

    if (c == '\n')

    {

        //y = (y + 8) % 272;

        y += 8;

        if (y > 272)

            y = 0;

        return ;

    }

    else if (c == '\r')

    {

        x = 0;

        return;

    }

    for (i = 0; i < 8; i++)    

    {

        line_dots = char_dots[i];

        

        for (j = 0; j < 8; j++)

        {

            if (line_dots & (0x80 >> j))

            {

                PutPixel(x+j,  y+i, 1);  // 调色板里面第1个条目的颜色值 

            }

            else

            {

                PutPixel(x+j,  y+i, 0);  // 调色板里面第0个条目的颜色值 

            }

        }

    }

    //x = (x + 8) % 480;

    x += 8;

    if (x > 480)

        x = 0;

    

    if (x == 0)

    {

        //y = (y + 8) % 272;

        y += 8;

        if (y > 272)

            y = 0;

    }

}


关键字:OK6410  裸机  LCD调色板 引用地址:OK6410裸机之LCD调色板

上一篇:自己写bootloader之OK6410
下一篇:OK6410裸机之LCD显

推荐阅读

   10月9日,广东省电子信息行业协会联合广电运通、致链科技、中山大学等多个单位,发起成立了广东省电子信息行业协会区块链专业委员会,广州广电运通区块链科技有限公司总经理邹均当选该专委会主任。该专委会将致力于通过搭建统一平台,汇聚各方力量,联合开展区块链技术、标准和产业研究,共同探索区块链的新模式和新机制,推进技术、产业与应用研发...
40只实验鼠连续54周暴露在含尼古丁的电子烟烟雾中,结果有9只(22.5%)出现了肺癌。此外,有23只(57.5%)出现了膀胱增生,患癌风险增加。 上述是美国纽约大学医学院研究团队针对电子烟做的研究,残酷的实验结果撕下了电子烟“更健康”的伪装。毫无疑问,电子烟是非常有害的。 可能小白鼠实验不足以引人警醒。但残酷的现实是电子烟在烟民中的事故也开始雨...
据外媒报道,苹果计划在10月31日将iPhone 5C、MacBook 15英寸2014年款列入过时和停产产品清单(vintage and obsolete products)。  苹果的过时产品名单都是已上市5-7年的产品,更长时间的则转入停产名单。  在过去,成为过时产品,就意味着苹果不再提供任何维修服务,但是从2018年开始,苹果延长了特定过时产品的维修服务期限。  今...
消费市场的PC制造商面临零组件短缺,其影响可能将外溢到记忆体市场。美光(Micron)日前表示,这一季的记忆体营收很可能低于分析师的预期。 美光第三季受PC缺料影响,营收可能低于预期 美光生产用于资料储存的NAND记忆体晶片,以及广泛应用在资料中心、PC与其他装置的DRAM记忆体晶片,而今年第三季,两种晶片的销量都可能下滑。美光执行长Sanjay Mehrotra表...

史海拾趣

问答坊 | AI 解惑

送给学习VHDL的兄弟们

一本VHDL的书   感觉不错…

查看全部问答∨

模拟集成电路三本圣经(书及答案)

模拟三本经典著作及答案,另外附送拉扎维的射频微电子(中文版) 这么经典的东西不用详细介绍了吧 拉扎维的《Design of Analog CMOS Integrated Circuits》书及答案 Gray和Meyer等人的《Analysis and Design of analog IC》书及答案 P.E.Allen ...…

查看全部问答∨

LPC1114之SysTick计算

LPC1114的SysTick延时时间的计算方式如下图 我用这个延时做了一个LED闪烁的例子,现在共享给大家。下面是源代码,附件里有工程文件。 #include \"LPC11xx.h\"             & ...…

查看全部问答∨

c51的8253求助

我用51控制8253进行计数工作,片选接P24,A1A0通过373接P00P01,以下是我的总线方式 #define cnt0_8253 XBYTE[0xe0f0] #define cnt1_8253 XBYTE[0xe0f1] #define cnt2_8253 XBYTE[0xe0f2] #define ctrl_8253 XBYTE[0xe0f3] 我的计数器可以选到, ...…

查看全部问答∨

progisp V1.67安装不上??

我的电脑(台式)上装progisp167的USB驱动装不上,为什么? 我是从www.zhifengsoft.com上下载的,解压后不管是直接右击usbprog.inf安装还是插设备在向导里安装,都装不上。可是,同事的笔记本就能装! www.zhifengsoft.com的网站上也没有说怎么回 ...…

查看全部问答∨

串口at指令,读取到的数据包括写入的吗?

发送\"at\\r\\n\",读取的是\"at\\r\\n\\r\\nOK\\r\\n\",不仅是\"\\r\\nOK\\r\\n\",读取的包括写入的,at指令都是这个原理的吗?…

查看全部问答∨

有谁知道不带驱动的LED照明产品吗

有谁知道不带驱动的LED照明产品吗?谢谢!…

查看全部问答∨

EK_LM3S811开发套件应用(只谈应用)

以下为收集整理的LM3S811开发套件部分应用实例,希望对新手和闲置板子的人有所帮助,欢迎拍砖!!LM3S811 小组DIY:1、TI LM3S811 DIY之【步进电机驱动器】步进电机驱动器,以LM3S811为核心,掌握该片子的ADC,PWM,COMP等模块的使用 ...…

查看全部问答∨
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved