57、编写lcd画点、划线、画圆、点阵

1、framebuffer.c  实现画点的函数


#include "lcd.h"

/* 实现画点 */

/* 获得LCD参数 */
static unsigned int fb_base;
static int xres, yres, bpp;

void fb_get_lcd_params(void)
{
    get_lcd_params(&fb_base, &xres, &yres, &bpp);
}

/* rgb: 0x00RRGGBB */
unsigned short convert32bppto16bpp(unsigned int rgb)
{
    int r = (rgb >> 16)& 0xff;
    int g = (rgb >> 8) & 0xff;
    int b = rgb & 0xff;

    /* rgb565 */
    r = r >> 3;
    g = g >> 2;
    b = b >> 3;

    return ((r<<11) | (g<<5) | (b));
}


/* color : 32bit, 0x00RRGGBB
 *
 */
void fb_put_pixel(int x, int y, unsigned int color)
{
    unsigned char  *pc;  /* 8bpp */
    unsigned short *pw;  /* 16bpp */
    unsigned int   *pdw; /* 32bpp */

    unsigned int pixel_base = fb_base + (xres * bpp / 8) * y + x * bpp / 8;

    switch (bpp)
    {
        case 8:
            pc = (unsigned char *) pixel_base;
            *pc = color;
            break;
        case 16:
            pw = (unsigned short *) pixel_base;
            *pw = convert32bppto16bpp(color);
            break;
        case 32:
            pdw = (unsigned int *) pixel_base;
            *pdw = color;
            break;
    }
}

2、geometry.c   实现划线和画圆的函数


#include "framebuffer.h"

/*
 * http://blog.csdn.net/p1126500468/article/details/50428613
 */

 //-------------画圆函数。参数:圆心,半径,颜色----------    
 //        画1/8圆 然后其他7/8对称画  
 //          ---------------->X  
 //          |(0,0)   0  
 //          |       7     1    
 //          |      6       2  
 //          |       5     3    
 //       (Y)V          4  
 //  
 //      L = x^2 + y^2 - r^2  
 void draw_circle(int x, int y, int r, int color)  
 {    
     int a, b, num;  
     a = 0;  
     b = r;  
     while(22 * b * b >= r * r)          // 1/8圆即可  
     {    
         fb_put_pixel(x + a, y - b,color); // 0~1  
         fb_put_pixel(x - a, y - b,color); // 0~7  
         fb_put_pixel(x - a, y + b,color); // 4~5  
         fb_put_pixel(x + a, y + b,color); // 4~3  
   
         fb_put_pixel(x + b, y + a,color); // 2~3  
         fb_put_pixel(x + b, y - a,color); // 2~1  
         fb_put_pixel(x - b, y - a,color); // 6~7  
         fb_put_pixel(x - b, y + a,color); // 6~5  
           
         a++;  
         num = (a * a + b * b) - r*r;  
         if(num > 0)  
         {    
             b--;  
             a--;  
         }    
     }    
 }    
   
 //-----------画线。参数:起始坐标,终点坐标,颜色--------    
 void draw_line(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)    
                 {    
                     fb_put_pixel(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)    
                 {    
                     fb_put_pixel(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)    
                 {    
                     fb_put_pixel(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)    
                 {    
                     fb_put_pixel(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)    
                 {    
                     fb_put_pixel(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)    
                 {    
                     fb_put_pixel(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)    
                 {    
                     fb_put_pixel(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)    
                 {    
                     fb_put_pixel(x1,y1,color);  
                     if(e>0){x1-=1;e-=dy;}       
                     y1-=1;  
                     e+=dx;  
                 }    
             }    
         }       
     }    
 }    

3、font_8x16.c点阵

const unsigned char fontdata_8x16[FONTDATAMAX] = {

    /* 0 0x00 '^@' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */

    /* 1 0x01 '^A' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x7e, /* 01111110 */
    0x81, /* 10000001 */
    0xa5, /* 10100101 */
    0x81, /* 10000001 */
    0x81, /* 10000001 */
    0xbd, /* 10111101 */
    0x99, /* 10011001 */
    0x81, /* 10000001 */
    0x81, /* 10000001 */
    0x7e, /* 01111110 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */

     ...

    /* 255 0xff '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */

};

4、font.c 实现显示字符

extern const unsigned char fontdata_8x16[];
/* 获得LCD参数 */
static unsigned int fb_base;
static int xres, yres, bpp;

void font_init(void)
{
    get_lcd_params(&fb_base, &xres, &yres, &bpp);
}

/* 根据字母的点阵在LCD上描画文字 */

void fb_print_char(int x, int y, char c, unsigned int color)
{
    int i, j;
    
    /* 根据c的ascii码在fontdata_8x16中得到点阵数据 */
    unsigned char *dots = &fontdata_8x16[c * 16];

    unsigned char data;
    int bit;

    /* 根据点阵来设置对应象素的颜色 */
    for (j = y; j < y+16; j++)
    {
        data = *dots++;
        bit = 7;
        for (i = x; i < x+8; i++)
        {
            /* 根据点阵的某位决定是否描颜色 */
            if (data & (1<                 fb_put_pixel(i, j, color);
            bit--;
        }
    }
}


/* "abc\n\r123" */
void fb_print_string(int x, int y, char* str, unsigned int color)
{
    int i = 0, j;
    
    while (str[i])
    {
        if (str[i] == '\n')
            y = y+16;
        else if (str[i] == '\r')
            x = 0;

        else
        {
            fb_print_char(x, y, str[i], color);
            x = x+8;
            if (x >= xres) /* 换行 */
            {
                x = 0;
                y = y+16;
            }
        }
        i++;
    }
}


5、lcd_test.c 测试程序


#include "geometry.h"
#include "font.h"

void lcd_test(void)
{
    unsigned int fb_base;
    int xres, yres, bpp;
    int x, y;
    unsigned char *p0;
    unsigned short *p;
    unsigned int *p2;
        
    /* 初始化LCD */
    lcd_init();

    /* 使能LCD */
    lcd_enable();

    /* 获得LCD的参数: fb_base, xres, yres, bpp */
    get_lcd_params(&fb_base, &xres, &yres, &bpp);
    fb_get_lcd_params();
    font_init();
    
    /* 往framebuffer中写数据 */
    if (bpp == 8)
    {
        /* 让LCD输出整屏的红色 */

        /* bpp: palette[12] */

        p0 = (unsigned char *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p0++ = 12;

        /* palette[47] */
        p0 = (unsigned char *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p0++ = 47;

        /* palette[88] */
        p0 = (unsigned char *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p0++ = 88;

        /* palette[0] */
        p0 = (unsigned char *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p0++ = 0;
            
    }
    else if (bpp == 16)
    {
        /* 让LCD输出整屏的红色 */

        /* 565: 0xf800 */

        p = (unsigned short *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p++ = 0xf800;

        /* green */
        p = (unsigned short *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p++ = 0x7e0;

        /* blue */
        p = (unsigned short *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p++ = 0x1f;

        /* black */
        p = (unsigned short *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p++ = 0;
            
    }
    else if (bpp == 32)
    {
        /* 让LCD输出整屏的红色 */

        /* 0xRRGGBB */

        p2 = (unsigned int *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p2++ = 0xff0000;

        /* green */
        p2 = (unsigned int *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p2++ = 0x00ff00;

        /* blue */
        p2 = (unsigned int *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p2++ = 0x0000ff;

        /* black */
        p2 = (unsigned int *)fb_base;
        for (x = 0; x < xres; x++)
            for (y = 0; y < yres; y++)
                *p2++ = 0;

    }

    delay(1000000);
    
    /* 画线 */
    draw_line(0, 0, xres - 1, 0, 0x23ff77);
    draw_line(xres - 1, 0, xres - 1, yres - 1, 0xffff);
    draw_line(0, yres - 1, xres - 1, yres - 1, 0xff00aa);
    draw_line(0, 0, 0, yres - 1, 0xff00ef);
    draw_line(0, 0, xres - 1, yres - 1, 0xff45);
    draw_line(xres - 1, 0, 0, yres - 1, 0xff0780);

    delay(1000000);

    /* 画圆 */
    draw_circle(xres/2, yres/2, yres/4, 0xff);

    /* 输出文字 */
    fb_print_string(10, 10, "www.100ask.net\n\r100ask.taobao.com", 0xff);
}

 

你可能感兴趣的:(第2期ARM裸机加强版)