注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
ming1006的个人空间 https://home.eeworld.com.cn/space-uid-388236.html [收藏] [复制] [分享] [RSS]
日志

我的5110画图库--Nokia 5110液晶屏实现画点、画线、画矩形、画圆和画图

已有 1929 次阅读2012-10-12 22:24

  最近花了好多时间终于完成了5110液晶屏的画图函数库,完善了画图的基本函数,有画点,画直线,画折线,画矩形,画圆和贴图的基本功能。函数库提供了使用缓冲区和不使用缓冲区的函数,可以根据需要灵活使用。单片机使用的是stm32,但是我的做了宏定义,非常容易移植到其他单片机上,具体情况在代码注释中应该介绍的蛮详细的(注释花了我不少时间整理哦)。   在画图的算法上,我画直线采用了Bresenham算法,画圆是用的中点画圆法,不过我稍微改了一些,没有使用浮点数,还有在一些乘法计算时采用移位代替,这两点都使画图速度大大加快了。
  闲话少说,先上图吧!


再看看我的头文件都提供的哪些函数吧(个人觉得还是蛮多的):
  LCD5110.h[code]#ifndef _LCD5110_H_
#define _LCD5110_H_

/*--------修改本文件 <5110端口和引脚宏定义> 可以改变单片机引脚连线-------------*/
/*----------如果要移植到其他单片机上只需再修改本文件的<5110引脚动-------------*/
/*------------作宏定义>和LCD5110.c文件中LcdPortInit函数对单片机--------------*/
/*--------------引脚的初始化,5110的VCC为3V时或显示不清时可以---------------*/
/*-------------------修改LCD5110.c中LcdInit函数的配置----------------------*/

#include \"stm32f0xx.h\"
#include \"stm32f0xx_gpio.h\"
#include \"Delay.h\"
#include \"Font6_8.h\"
#include \"Icon10_8.h\"
#include \"Font8_16.h\"
#include \"Font16_16.h\"
#include \"Bitmap.h\"


/*------保留下面这句表示使用buf,注释掉表示不使用buf-----*/
#define USE_BUF
/*------保留上面这句表示使用buf,注释掉表示不使用buf-----*/

#define u8                 unsigned char
#define u16         unsigned short

typedef struct
{
        u8 x;
        u8 y;
}point;

/*------5110屏幕尺寸和功能宏定义------*/
#define DATA        1                                                                                                                                //数据
#define CMD 0                                                                                                                                        //命令
#define LCD_X        84                                                                                                                        //液晶屏横坐标宽度
#define LCD_ROW LCD_X                                                                                                        //液晶屏列宽度
#define LCD_Y        48                                                                                                                        //液晶屏纵坐标高度
#define LCD_COLUMN LCD_Y / 8                                                                        //液晶屏行高度
#define LCD_AREA LCD_X * LCD_Y                                                                //液晶屏面积
#define LCD_AREA_BYTE LCD_COLUMN * LCD_ROW                //液晶屏字节容量

/*------位宏定义--------*/
#define BIT0         0x00000001
#define BIT1         0x00000002
#define BIT2         0x00000004
#define BIT3         0x00000008
#define BIT4         0x00000010
#define BIT5         0x00000020
#define BIT6         0x00000040
#define BIT7         0x00000080
#define BIT8         0x00000100
#define BIT9         0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000

/*------5110端口和引脚宏定义--------*/

#define LCD5110_PORT         GPIOB                                        //5110所在端口
#define LCD_SCLK_BIT         BIT3                                        //SCLK端口位
#define LCD_SDIN_BIT         BIT4                                        //SDIN端口位
#define LCD_DC_BIT                  BIT5                                        //DC端口位
#define LCD_SCE_BIT                BIT6                                        //SCE端口位
#define LCD_REST_BIT         BIT7                                        //REST端口位


/*------5110引脚动作宏定义-----------*/
#define LCD_SCLK_H        LCD5110_PORT->BSRR = LCD_SCLK_BIT                //SCLK置1       
#define LCD_SCLK_L  LCD5110_PORT->BRR  = LCD_SCLK_BIT                //SCLK置0

#define LCD_SDIN_H        LCD5110_PORT->BSRR = LCD_SDIN_BIT
#define LCD_SDIN_L  LCD5110_PORT->BRR  = LCD_SDIN_BIT

#define LCD_DC_H                LCD5110_PORT->BSRR = LCD_DC_BIT
#define LCD_DC_L          LCD5110_PORT->BRR  = LCD_DC_BIT

#define LCD_SCE_H                LCD5110_PORT->BSRR = LCD_SCE_BIT
#define LCD_SCE_L          LCD5110_PORT->BRR  = LCD_SCE_BIT

#define LCD_REST_H        LCD5110_PORT->BSRR = LCD_REST_BIT
#define LCD_REST_L  LCD5110_PORT->BRR  = LCD_REST_BIT

#define RCC_LCD5110_PORT         RCC_AHBENR_GPIOAEN << (((uint32_t)LCD5110_PORT-(uint32_t)GPIOA) >> 10)                        //5110 RCC使能

/*--------------------------------------------------------------------------------------------------------------*/
/*-------函数分不使用buf和使用buf,不使用buf最快,但是行不是任意坐标,是在5110本身的行的基础上定义的;----------*/
/*-------画的图案的高度必须是8的倍数,而且图案不能相或来进行叠加。使用buf的话不论是写字还是画图都没有-----------*/
/*-------坐标限制,图案宽度和高度也没有限制,而且可以进行图案和字符的叠加。使用buf的函数分两类,一类------------*/
/*-------是只对buf操作,大部分以tobuf,ofbuf,buf结尾比如PutChartoBuf、PutCircletoBuf、ClearBuf,这一类-----------*/
/*-------函数操作完后需要调用Refresh、RefreshAll这两个函数将buf的变化刷新到5110上,较灵活,可以通过减-----------*/
/*-------少刷新次数来加快画图速度。另一种是对buf操作后自动将结果刷新到5110上,大部分以buf开头,如BufPutChar-----*/
/*-------、BufPutHanzi等,还有画点画线画圆函数PutLine、PutRect等。----------------------------------------------*/

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////*                                以下为不使用缓冲区写字画图的相关函数                                *//////
//*--------------------------------------------------------*//
/////////////////////////////////////////////////////////////////////////////////////////////////////


//*******                                以下是基本操作和初始化函数                                *****//

/*----------初始化5110-----------*/
void InitLcd(void);
/*-------清空整个5110屏幕--------*/
void LcdClearAll(void);
/*---设置5110行和列坐标----*/
void SetXY(u8 row,u8 column);

//******                                以下是高度为8的各种操作函数                                *******//
//**                        包括6*8字符和字符串,6*8符号,10*8图标                          **//
//--every row contains 14 characters,there are 6 rows (font = 6 * 8)--//
                //-----------------           row                  ---------------------//
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                column = 0
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                column = 1
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                column = 2
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                column = 3
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                column = 4
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                column = 5
//-------------------------------------------------------//

/*---直接写一个ASCII字符(6*8)到5110(不需要坐标,紧跟上个字符或图标)---*/
void WriteChar(u8 value);
/*---直接写一个ASCII字符(6*8)到5110---*/
void PutChar(u8 value,u8 column,u8 row);
/*---直接写一个字符串(6*8)到5110(不需要坐标,紧跟上个字符或图标)---*/
void WriteStr(char * str);
/*--直接写一个字符串(6*8)到5110--*/
void PutStr(char * str,u8 column,u8 row);
/*---画sign(6*8)(不需要坐标,紧跟上个字符或图标)---*/
void WriteSign(char * sign);
/*----画sign(6*8)----*/
void PutSign(char * sign,u8 column,u8 row);
/*---画Icon(10*8)(不需要坐标,紧跟上个字符或图标)---*/
void WriteIcon(char * icon);
/*--画Icon(10*8),row(0~74)--*/
void PutIcon(char * icon,u8 column,u8 row);

//********                                以下是高度为16的各种操作函数                                *******//
//**                                包括8*16字符和字符串,16*16汉字                           **//
//--every row contains 10 characters,there are 3 rows (font = 8 * 16)--//
//-----------       row       ------------//
                //0 1 2 3 ... 81 82 83//        column = 0
                //0 1 2 3 ... 81 82 83//
                //0 1 2 3 ... 81 82 83//        column = 1
                //0 1 2 3 ... 81 82 83//
                //0 1 2 3 ... 81 82 83//        column = 2
                //0 1 2 3 ... 81 82 83//
//-----------------------------------------//

/*-----直接写一个ASCII字符(8*16)到5110------*/
void PutWideChar(u8 value,u8 column,u8 row);
/*--直接写一个字符串(6*8)到5110,自动换行,row(0~76)--*/
void PutWideStr(char * str,u8 column,u8 row);

//--every row contains 5 characters,there are 3 rows (font = 16 * 16)--//
//----------      row       --------------//
                //0 1 2 3 ... 81 82 83//        column = 0
                //0 1 2 3 ... 81 82 83//
                //0 1 2 3 ... 81 82 83//        column = 1
                //0 1 2 3 ... 81 82 83//
                //0 1 2 3 ... 81 82 83//        column = 2
                //0 1 2 3 ... 81 82 83//
//----------------------------------------//

/*-----直接写一个汉字(16*16)到5110------*/
void PutHanzi(char Hanzi[],u8 column,u8 row);
/*--写一串汉字(16*16),自动换行,row(0~58)--*/
void PutHanziStr(char Hanzi[],u8 column,u8 row,u8 num);

//********                                以下是画图的各种操作函数                                *********//
//**                                  包括84*48,高度为8的倍数的图片                       **//
//---------------           x                  ----------------------//
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                y = 0
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                y = 1
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                y = 2
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                y = 3
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                y = 4
                //0 1 2 3 4 5 6 7 8 9 10 11 12 13//                y = 5
//-----------------------------------------------//

/*---画picture(84*48),全屏---*/
void DrawPicture(char bitmap[]);
/*---画picture(高度必须是8的倍数)---*/
void DrawBmp(char bitmap[],u8 x,u8 y,u8 width,u8 height);

#ifdef USE_BUF        /*USE_BUF*/

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////*                                以下为使用缓冲区写字画图的相关函数                                *//////
//*-------------以下坐标统一为两种----------------*//
/////////////////////////////////////////////////////////////////////////////////////////////////////
//----------------------           x                  ------------------------//
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                y = 0
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                y = 1
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                y = 2
                //                                                        .
                //                                                        .
                //                                                        .
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                y = 45
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                y = 46
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                y = 47
//--------------------------------------------------------//
//-------------------          row                  ------------------------//
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                column = 0
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                column = 1
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                column = 2
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                column = 3
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                column = 4
                //0 1 2 3 4 5 ...78 79 80 81 82 83//                column = 5
//------------------------------------------------------//

///////*------------------------------------------*////////
//*********                                以下为刷新,清除等基本操作函数                        *********//
///////*------------------------------------------*////////

/*-----设置缓冲区指针坐标-------*/
void SetBufPtr(u8 x,u8 y);
/*----将整个缓冲区刷新到5110上-----*/
void RefreshAll(void);
/*-------将缓冲区指定区域刷新到5110对应区域-------*/
void Refresh(u8 x,u8 y,u8 width,u8 height);
/*------清空整个缓冲区-------*/
void ClearAllBuf(void);
/*------清空整个缓冲区并刷新5110------*/
void BufClearAll(void);
/*-------清空缓冲区指定区域-------*/
void ClearBuf(u8 x,u8 y,u8 width,u8 height);
/*-------清空缓冲区指定区域并刷新------*/
void BufClear(u8 x,u8 y,u8 width,u8 height);

///////*------------------------------------------*////////
//*********                                以下为写字符,汉字函数                                *********//
///////*------------------------------------------*////////


//******        以下字符高度均为8              ******//

/*-------写一个ASCII字符(6*8)到缓冲区(不需要坐标,紧跟上个字符)--------*/
void WriteChartoBuf(u8 value);
/*--------通过缓冲区写一个ASCII字符(6*8)到5110(不需要坐标,紧跟上个字符)--------*/
void BufWriteChar(u8 value);
/*----写一个ASCII字符(6*8)到缓冲区-----*/
void PutChartoBuf(u8 value,u8 x,u8 y);
/*----通过缓冲区写一个ASCII字符(6*8)到5110-----*/
void BufPutChar(u8 value,u8 x,u8 y);
/*------写一个字符串(高度8)到缓冲区(不需要坐标,紧跟上个字符)-----*/
u8 WriteStrtoBuf(char * str);
/*----通过缓冲区写一个字符串(高度8)到5110(不需要坐标,紧跟上个字符)----*/
u8 BufWriteStr(char * str);
/*-----写一个字符串(高度8)到缓冲区------*/
u8 PutStrtoBuf(char * str,u8 x,u8 y);
/*------通过缓冲区写一个字符串(高度8)到5110------*/
u8 BufPutStr(char * str,u8 x,u8 y);

//*******        以下字符汉字高度均为16          ********//

/*------写一个ASCII字符(8*16)到缓冲区------*/
void PutWideChartoBuf(u8 value,u8 x,u8 y);
/*----通过缓冲区写一个ASCII字符(8*16)到5110------*/
void BufPutWideChar(u8 value,u8 x,u8 y);
/*-----写一个字符串(高度16)到缓冲区------*/
u8 PutWideStrtoBuf(char * str,u8 x,u8 y);
/*------通过缓冲区写字符串(高度16)到5110------*/
u8 BufPutWideStr(char *str,u8 x,u8 y);
/*-----写一个汉字(16*16)到缓冲区------*/
void PutHanzitoBuf(char Hanzi[],u8 x,u8 y);
/*-----通过缓冲区写一个汉字(16*16)到5110-------*/
void BufPutHanzi(char Hanzi[],u8 x,u8 y);
/*-------写一串汉字(高度16)到缓冲区(num为汉字个数)-------*/
u8 PutHanziStrtoBuf(char Hanzi[],u8 x,u8 y,u8 num);
/*-----通过缓冲区写一串汉字(高度16)到5110(num为汉字个数)------*/
u8 BufPutHanziStr(char Hanzi[],u8 x,u8 y,u8 num);

//*********    以下为画点,线,折线,矩形,圆,bmp图片函数      *********//

/*------画一个点到缓冲区-------*/
void PutPointtoBuf(u8 x,u8 y);
/*------通过缓冲区画一个点到5110------*/
void PutPoint(u8 x,u8 y);
/*------画一条线到缓冲区--------*/               
void PutLinetoBuf(u8 x1,u8 y1,u8 x2,u8 y2);
/*-----通过缓冲区画一条线到5110-------*/       
void PutLine(u8 x1,u8 y1,u8 x2,u8 y2);
/*--画折线到缓冲区(p为折线各个节点,line_num为折线的线段数目)--*/
void PutPolylinetoBuf(point *p,u8 line_num);
/*--通过缓冲区画折线到5110(p为折线各个节点,line_num为折线的线段数目)--*/
void PutPolyline(point *p,u8 line_num);
/*---------画矩形到缓冲区--------*/
void PutRecttoBuf(u8 x,u8 y,u8 width,u8 height);
/*--------通过缓冲区画矩形到5110--------*/
void PutRect(u8 x,u8 y,u8 width,u8 height);
/*--------画圆到缓冲区--------*/
void PutCircletoBuf(u8 center_x,u8 center_y,u8 r);
/*--------通过缓冲区画圆到5110--------*/
void PutCircle(u8 center_x,u8 center_y,u8 r);
/*----画一个图片到缓冲区-----*/
void DrawBmptoBuf(char bitmap[],u8 x,u8 y,u8 width,u8 height);
/*-----通过缓冲区画一个图片到5110------*/
void BufDrawBmp(char bitmap[],u8 x,u8 y,u8 width,u8 height);

#endif /*USE_BUF*/

#endif /*LCD5110_H*/
[/code]下面是产生这四个图的主函数,看下很容易就知道函数的使用方法:[code]#include \"stm32f0xx.h\"
#include \"LCD5110.h\"

extern u8 lcd_buf[LCD_X][LCD_Y];

int main(void)
{
        u16 i;
        point p[4];       
       
        p[0].x = 41;
        p[0].y = 1;
        p[1].x = 80;
        p[1].y = 30;
        p[2].x = 49;
        p[2].y = 40;
        p[3].x = 41;
        p[3].y = 1;
       
        InitLcd();

lab:
       
/*-------不使用buf画图和写字,速度最快,省内存----------------*/
        for(i = 0;i < 6;i++)
                PutIcon((char*)(icon + i),i,0);
        SetXY(13,0);
        for(i = 0;i < 7;i++)
                WriteIcon((char*)(icon + 15 + i));
        PutHanziStr((char*)Hanzi,2,15,4);
        PutStr(\"oh my god\",2,3);
       
        Delayms(2000);
        BufClearAll();

/*--------使用buf画图和写字(每一次操作自动刷新,速度最慢)----------*/
        BufDrawBmp((char *)girl,0,0,45,48);
        BufPutStr(\"hello\",47,5);
        BufPutStr(\"ming\",49,15);
        PutRect(42,3,40,22);
        BufPutHanzi((char *)(Hanzi+4*32),44,30);
        BufPutHanzi((char *)(Hanzi+4*32),60,30);
        BufPutWideChar(\'!\',76,30);
               
        Delayms(2000);
        BufClearAll();
       
/*--------使用buf画图和写字(全部画完后一次性手动刷新,速度较快)----------*/
        DrawBmptoBuf((char *)(icon+16),62,37,10,8);
        DrawBmptoBuf((char *)(icon+16),22,25,10,8);
        DrawBmptoBuf((char *)(icon+17),55,18,10,8);
        DrawBmptoBuf((char *)(icon+17),12,36,10,8);
        PutCircletoBuf(3,20,1);
        PutCircletoBuf(8,20,2);
        PutCircletoBuf(30,20,18);
        PutLinetoBuf(4,2,44,43);
        PutLinetoBuf(68,16,50,38);
        PutPolylinetoBuf(p,3);
        PutRecttoBuf(0,33,28,12);
        PutStrtoBuf(\"ming\",0,8);
        RefreshAll();
               
        Delayms(2000);
        BufClearAll();
       
/*---------混合使用buf函数和不用buf函数----------------*/
        BufDrawBmp((char*)SFEFlameBubble,0,0,84,48);
        PutStr(\"ming\",2,1);
        BufClear(30,8,5,3);
       
        Delayms(2000);
        BufClearAll();
       
        goto lab;
}
[/code]  最后是整个工程,里面还有完整的6*8、8*16的ASCII字符库,大量的符号和图片库。

stm32 Nokia 5110液晶屏画点、画线、画矩形、画圆.zip

本文含有来自论坛的附件或图片点击查看原帖附件。

发表评论 评论 (1 个评论)
回复 cxzs1234 2013-6-28 09:51
支持一下

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章