我的5110画图库--Nokia 5110液晶屏实现画点、画线、画矩形、画圆和画图
好久没有写原创帖了,今天分享一个自己写的好东东。
最近花了好多时间终于完成了5110液晶屏的画图函数库,是在之前nios ii的工程基础之上做的,完善了画图的基本函数,有画点,画直线,画折线,画矩形,画圆和贴图的基本功能。函数库提供了使用缓冲区和不使用缓冲区的函数,可以根据需要灵活使用。单片机使用的是stm32,但是我的做了宏定义,非常容易移植到其他单片机上,具体情况在代码注释中应该介绍的蛮详细的(注释花了我不少时间整理哦)。
在画图的算法上,我画直线采用了Bresenham算法,画圆是用的中点画圆法,不过我稍微改了一些,没有使用浮点数,还有在一些乘法计算时采用移位代替,这两点都使画图速度大大加快了。
闲话少说,先上图吧!
再看看我的头文件都提供的哪些函数吧(个人觉得还是蛮多的):
LCD5110.h
#ifndef _LCD5110_H_#define _LCD5110_H_/*--------修改下面 <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 shorttypedef struct {u8 x;u8 y;}point;/*------5110屏幕尺寸和功能宏定义------*/#define DATA1//数据#define CMD 0//命令#define LCD_X84//液晶屏横坐标宽度#define LCD_ROW LCD_X//液晶屏列宽度#define LCD_Y48//液晶屏纵坐标高度#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_BITBIT6//SCE端口位#define LCD_REST_BIT BIT7//REST端口位/*------5110引脚动作宏定义-----------*/ #define LCD_SCLK_HLCD5110_PORT->BSRR = LCD_SCLK_BIT//SCLK置1#define LCD_SCLK_L LCD5110_PORT->BRR = LCD_SCLK_BIT//SCLK置0#define LCD_SDIN_HLCD5110_PORT->BSRR = LCD_SDIN_BIT#define LCD_SDIN_L LCD5110_PORT->BRR = LCD_SDIN_BIT#define LCD_DC_HLCD5110_PORT->BSRR = LCD_DC_BIT#define LCD_DC_L LCD5110_PORT->BRR = LCD_DC_BIT#define LCD_SCE_HLCD5110_PORT->BSRR = LCD_SCE_BIT#define LCD_SCE_L LCD5110_PORT->BRR = LCD_SCE_BIT#define LCD_REST_HLCD5110_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*/
下面是产生这四个图的主函数,看下很容易就知道函数的使用方法:
#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;}
至于源文件,因为有近千行,不可能都贴这,我就放在CSDN我的资源下了,是免积分下载的,整个工程都有,里面还有完整的6*8、8*16的ASCII字符库,大量的符号和图片库,链接是:http://download.csdn.net/detail/ming1006/4637936Nokia 5110液晶屏画点、画线、画矩形、画圆
- 1楼abclixu12339分钟前
- 很不错。