完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.代码
头文件 #ifndef __BSP_LCD_H #define __BSP_LCD_H #include "lcd_drv.h" /* RGB565: 高位至低位排列, RRRR RGGG GGGB BBBB */ #define RGB(R,G,B) (((R >> 3) << 11) | ((G >> 2) << 5) | (B >> 3)) //24位RGB转化为 16位RGB565格式 #define RGB565_R(x) ((x >> 8) & 0xF8) #define RGB565_G(x) ((x >> 3) & 0xFC) #define RGB565_B(x) ((x << 3) & 0xF8) enum { CL_WHITE = RGB(255, 255, 255), /* 白 */ CL_BLACK = RGB( 0, 0, 0), /* 黑 */ CL_RED = RGB(255, 0, 0), /* 红 */ CL_GREEN = RGB( 0, 255, 0), /* 绿 */ CL_BLUE = RGB( 0, 0, 255), /* 蓝 */ CL_YELLOW = RGB(255, 255, 0), /* 黄 */ CL_GREY = RGB( 98, 98, 98), /* 深灰 */ CL_BUTTON_GREY = RGB( 220, 220, 220), /* 按钮灰*/ }; /* 可供外部模块调用的函数 */ void LCD_Init(void); #define LCD_GetHeight() LCD_HEIGHT #define LCD_GetWidth() LCD_WIDTH //#define LCD_FillColorPre lcddrv_FillColorPre void LCD_PutPixel(uint16_t _usX, uint16_t _usY, uint16_t _usColor); void LCD_DrawHLine(uint16_t _usX , uint16_t _usY , uint16_t _uslen , uint16_t _usColor); void LCD_DrawHColorLine(uint16_t _usX , uint16_t _usY, uint16_t _uslen, const uint16_t *_pColor); void LCD_Fill_Rect(uint16_t _usX, uint16_t _usY, uint16_t _usWidth, uint16_t _usHeight, uint16_t _usColor); void LCD_Fill_ColorRect(uint16_t _usX, uint16_t _usY, uint16_t _usWidth, uint16_t _usHeight, const uint16_t *_pColor); #define LCD_ClrScr(_usColor) LCD_Fill_Rect(0,0,LCD_WIDTH,LCD_HEIGHT,_usColor); #define LCD_DrawVLine(_usX,_usY,len,_usColor) LCD_Fill_Rect(_usX,_usY,1,len,_usColor) void LCD_DrawLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usY2 , uint16_t _usColor); void LCD_DrawPolyline(uint16_t *x, uint16_t *y, uint16_t _usSize, uint16_t _usColor); void LCD_DrawRect(uint16_t _usX, uint16_t _usY, uint16_t _usWidth,uint16_t _usHeight, uint16_t _usColor); void LCD_DrawCircle(uint16_t _usX, uint16_t _usY, uint16_t _usRadius, uint16_t _usColor); void LCD_DrawBinBMP(uint16_t _usX, uint16_t _usY, const char * pPath); void LCD_DispOn(void); void LCD_DispOff(void); void LCD_SetBackLight(uint8_t _ucBright); uint8_t LCD_GetBackLight(void); #endif C文件 #include "bsp.h" #include "lcd_drv.h" #include "fonts.h" //#define LCD_GetWidth() LCD_WIDTH //#define LCD_GetHeight() LCD_HEIGHT static uint8_t s_ucBright; /* 背光亮度参数 */ /* ************************************************************************************************* * 函 数 名: LCD_DispOn * 功能说明: 打开显示 * 形 参: 无 * 返 回 值: 无 ************************************************************************************************* */ void LCD_DispOn(void) { lcddrv_DispOn(); } /* ************************************************************************************************ * 函 数 名: LCD_DispOff * 功能说明: 关闭显示 * 形 参: 无 * 返 回 值: 无 ************************************************************************************************ */ void LCD_DispOff(void) { lcddrv_DispOff(); } /* ************************************************************************************************* * 函 数 名: LCD_PutPixel * 功能说明: 打点函数 * 形 参: * _usX,_usY : 像素坐标 * _usColor :像素颜色 * 返 回 值: 无 ************************************************************************************************* */ void LCD_PutPixel(uint16_t _usX, uint16_t _usY, uint16_t _usColor) { lcddrv_FillColorPre(_usX, _usY,LCD_WIDTH,LCD_HEIGHT); /* 设置光标位置 */ /* Write 16-bit GRAM Reg */ LCDDRV_RAM = _usColor; } /* ************************************************************************************************* * 函 数 名: _DrawHLine * 功能说明: 绘制水平线 * 形 参: _usX ,_usY : 起始点坐标 * _usLen :长度 * _usColor : 颜色 * 返 回 值: 无 ************************************************************************************************* */ void LCD_DrawHLine(uint16_t _usX , uint16_t _usY , uint16_t _usLen , uint16_t _usColor) { uint16_t i; lcddrv_FillColorPre(_usX, _usY,LCD_WIDTH,LCD_HEIGHT); for (i = 0; i < _usLen; i++) { LCDDRV_RAM = _usColor; } } /* ************************************************************************************************* * 函 数 名: _DrawHColorLine * 功能说明: 绘制一条彩色水平线 * 形 参: _usX ,_usY :起始点坐标 * _usLen :直线的长度 * _pColor : 颜色缓冲区 * 返 回 值: 无 ************************************************************************************************* */ void LCD_DrawHColorLine(uint16_t _usX , uint16_t _usY, uint16_t _usLen, const uint16_t *_pColor) { uint16_t i; lcddrv_FillColorPre(_usX, _usY,LCD_WIDTH,LCD_HEIGHT); for (i = 0; i < _usLen; i++) { LCDDRV_RAM = *_pColor++; } } /* ************************************************************************************************* * 函 数 名: LCD_Fill_Rect * 功能说明: 绘制单色矩形区域 * 形 参: * _usX,_usY : 矩形左上角的坐标 * _usHeight : 矩形的高度 * _usWidth : 矩形的宽度 * _usColor : 颜色 * 返 回 值: 无 ************************************************************************************************* */ void LCD_Fill_Rect(uint16_t _usX, uint16_t _usY, uint16_t _usWidth, uint16_t _usHeight, uint16_t _usColor) { uint32_t i; uint32_t len = (uint32_t)_usWidth * _usHeight; lcddrv_FillColorPre(_usX, _usY, _usWidth, _usHeight); for (i = 0; i < len; i++) { LCDDRV_RAM = _usColor; } } /* ************************************************************************************************* * 函 数 名: LCD_Fill_ColorRect * 功能说明: 绘制矩形区域,颜色填充数据 * 形 参: * _usX,_usY : 矩形左上角的坐标 * _usHeight : 矩形的高度 * _usWidth : 矩形的宽度 * _pColor : 颜色缓冲区 * 返 回 值: 无 ************************************************************************************************* */ void LCD_Fill_ColorRect(uint16_t _usX, uint16_t _usY, uint16_t _usWidth, uint16_t _usHeight, const uint16_t *_pColor) { uint32_t i; uint32_t len = (uint32_t)_usWidth * _usHeight; lcddrv_FillColorPre(_usX, _usY, _usWidth, _usHeight); for (i = 0; i < len; i++) { ST7789_RAM = *_pColor++; } } /* ************************************************************************************************* * 函 数 名: LCD_DrawRect * 功能说明: 绘制矩形边。 * 形 参: * _usX,_usY: 矩形左上角的坐标 * _usWidth : 矩形的宽度 * _usHeight : 矩形的高度 * 返 回 值: 无 ************************************************************************************************* */ void LCD_DrawRect(uint16_t _usX, uint16_t _usY, uint16_t _usWidth, uint16_t _usHeight, uint16_t _usColor) { LCD_DrawHLine( _usX , _usY , _usWidth , _usColor); LCD_DrawHLine( _usX , _usY + _usHeight - 1 , _usWidth , _usColor); LCD_DrawVLine( _usX , _usY , _usHeight, _usColor); LCD_DrawVLine( _usX + _usWidth - 1 , _usY , _usHeight, _usColor); } /* ************************************************************************************************* * 函 数 名: LCD_DrawLine * 功能说明: Bresenham 算法绘制2点间的直线。 * 形 参: * _usX1, _usY1 : 起始点坐标 * _usX2, _usY2 : 终止点Y坐标 * _usColor : 颜色 * 返 回 值: 无 ************************************************************************************************* */ void LCD_DrawLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usY2 , uint16_t _usColor) { int32_t dx , dy ; int32_t tx , ty ; int32_t inc1 , inc2 ; int32_t d , iTag ; int32_t x , y ; LCD_PutPixel(_usX1 , _usY1 , _usColor); if ( _usX1 == _usX2 && _usY1 == _usY2 ) { LCD_PutPixel( _usX1, _usY2, _usColor); return; } iTag = 0 ; if (_usX2 >= _usX1) { dx = _usX2 - _usX1; } else { dx = _usX1 - _usX2; } if (_usY2 >= _usY1) { dy = _usY2 - _usY1; } else { dy = _usY1 - _usY2; } if ( dx < dy ) //如果dy为计长方向,则交换纵横坐标。 { uint16_t temp; iTag = 1 ; temp = _usX1; _usX1 = _usY1; _usY1 = temp; temp = _usX2; _usX2 = _usY2; _usY2 = temp; temp = dx; dx = dy; dy = temp; } tx = _usX2 > _usX1 ? 1 : -1 ; //确定是增1还是减1 ty = _usY2 > _usY1 ? 1 : -1 ; x = _usX1 ; y = _usY1 ; inc1 = 2 * dy ; inc2 = 2 * ( dy - dx ); d = inc1 - dx ; while ( x != _usX2 ) // 循环画点 { if ( d < 0 ) { d += inc1 ; } else { y += ty ; d += inc2 ; } if ( iTag ) { LCD_PutPixel ( y , x , _usColor) ; } else { LCD_PutPixel ( x , y , _usColor) ; } x += tx ; } } /* ************************************************************************************************* * 函 数 名: LCD_DrawCircle * 功能说明: 画空心圆 * 形 参: * _usX,_usY : 圆心坐标 * _usRadius : 半径 * _usColor : 颜色 * 返 回 值: 无 ************************************************************************************************* */ void LCD_DrawCircle(uint16_t _usX, uint16_t _usY, uint16_t _usRadius, uint16_t _usColor) { int32_t D; /* Decision Variable */ uint32_t CurX; /* 当前 X 值 */ uint32_t CurY; /* 当前 Y 值 */ D = 3 - (_usRadius << 1); CurX = 0; CurY = _usRadius; while (CurX <= CurY) { LCD_PutPixel(_usX + CurX, _usY + CurY, _usColor); LCD_PutPixel(_usX + CurX, _usY - CurY, _usColor); LCD_PutPixel(_usX - CurX, _usY + CurY, _usColor); LCD_PutPixel(_usX - CurX, _usY - CurY, _usColor); LCD_PutPixel(_usX + CurY, _usY + CurX, _usColor); LCD_PutPixel(_usX + CurY, _usY - CurX, _usColor); LCD_PutPixel(_usX - CurY, _usY + CurX, _usColor); LCD_PutPixel(_usX - CurY, _usY - CurX, _usColor); if (D < 0) { D += (CurX << 2) + 6; } else { D += ((CurX - CurY) << 2) + 10; CurY--; } CurX++; } } #define ONESIZE (2048) //从SD卡单次读取的数据大小 __inline static uint16_t turn332to565( uint16_t c) //RGB332转RGB565 { uint16_t r= (c&0x00E0)<<8; uint16_t g= (c&0x001C)<<6; uint16_t b= (c&0x0003)<<3; return r+g+b; } /* ************************************************************************************************* * 函 数 名: LCD_DrawBinBMP * 功能说明: 在LCD上显示一个SD卡的BMP-BIN格式位图,使用Img2Lcd将BMP转BIN;支持1BIT,8BIT,16BIT。 * 位图点阵扫描次序: 从左到右,从上到下.测试全幅图(16bit/RGB565),速度如下: * ONESIZE =512->180ms,1024->135ms,=2048->110ms,=4096->110ms * 形 参: * _usX, _usY : 图片的坐标 * path : 路径,比如"0:/bmp/001.bin" * _ptr : 图片点阵指针 * 返 回 值: 无 ************************************************************************************************* */ void LCD_DrawBinBMP(uint16_t _usX, uint16_t _usY, const char * path) { PICBIN_HEADCOLOR_T head; FRESULT fres; FIL xfile; u32 br=0,pos=0; u16 *const buf= mymalloc(SRAMCCM,ONESIZE); u8 *p; if(buf==NULL){ printf(" mymalloc err !rn");return;} fres=f_open(&xfile,path,FA_OPEN_EXISTING|FA_READ); if(fres == FR_OK) { f_lseek(&xfile,0); p=(u8*)buf; fres = f_read(&xfile,p,ONESIZE,&br); if( fres==FR_OK ) { memcpy(&head,p,sizeof(head)); lcddrv_FillColorPre( _usX,_usY,head.w,head.h); if(head.gray==1) //1bit图 { p+=6; u16 i=6; for(;i { u8 j=0; if( head.w%8 == 0 ) //宽度为8的倍数的情况 { for(;j<8;j++) { LCDDRV_RAM = ( (*p) & (0x80>>j) )?0:0xffff; } }else { //TODO. 处理多余的0 printf(" bit errrn"); } p++; } pos=ONESIZE; while(pos p=(u8*)buf; f_lseek(&xfile,pos); fres = f_read(&xfile,p,ONESIZE,&br); if( fres==FR_OK ) { u16 i=0; for(;i { u8 j=0; if( head.w%8 == 0 ) { for(;j<8;j++) { LCDDRV_RAM = ( (*p) & (0x80>>j) )?0:0xffff; } }else { //TODO. 处理多余的0 printf(" bit errrn"); } p++; } } pos+=ONESIZE; } } else if(head.gray==8) //8bit图 { p+=6; u16 i=6; for(;i { LCDDRV_RAM =turn332to565(*p)+4 +0x80+0x1000; p++; } pos=ONESIZE; while(pos p=(u8*)buf; f_lseek(&xfile,pos); fres = f_read(&xfile,p,ONESIZE,&br); if( fres==FR_OK ) { u16 i=0; for(;i { LCDDRV_RAM = turn332to565(*p)+4 +0x80+0x1000; p++; } } pos+=ONESIZE; } } else //16bit图 { p+=8; u16 i=8; for(;i { LCDDRV_RAM = *(u16*)p; p+=2; } pos=ONESIZE; while(pos p=(u8*)buf; f_lseek(&xfile,pos); fres = f_read(&xfile,p,ONESIZE,&br); if( fres==FR_OK ) { u16 i=0; for(;i { LCDDRV_RAM = *(u16*)p; p+=2; } } pos+=ONESIZE; } } } f_close(&xfile); }else printf(" no" %s" file!rn",path); myfree(SRAMCCM,buf); } /* ************************************************************************************************* * 函 数 名: LCD_SetBackLight * 功能说明: LCD背光控制 * 形 参: _ucBright 亮度,0灭 * 返 回 值: 无 ************************************************************************************************* */ void LCD_SetBackLight(uint8_t _ucBright) { s_ucBright = _ucBright; /* 保存背光值 */ lcddrv_SetBackLight(_ucBright); } /* ************************************************************************************************* * 函 数 名: LCD_GetBackLight * 功能说明: 获取背光亮度 * 形 参: 无 * 返 回 值: 背光亮度 ************************************************************************************************* */ uint8_t LCD_GetBackLight(void) { return s_ucBright; } /* ************************************************************************************************* * 函 数 名: LCD_Init * 功能说明: 初始化LCD * 形 参: 无 * 返 回 值: 无 ************************************************************************************************* */ void LCD_Init(void) { lcddrv_Init(); LCD_ClrScr(0xffff); LCD_SetBackLight(BRIGHT_DEFAULT); /* 打开背光,设置为缺省亮度 */ } 如果编译错误,试试勾选C99模式,因为我把一些变量放在语句后面定义了。 即使更换了其他驱动芯片的LCD,也只需要修改上篇文章的lcd_drv.c的底层驱动,和lcd_drv.h的LCD_RAM地址即可。本文件是中间层代码,隔离逻辑业务层与底层驱动层。 如果屏幕IC不使用FSMC驱动,则应该将画点函数,单色填充函数,颜色数据填充函数等几个基本画图函数放在底层lcd_drv.c文件实现。而为了追求速度,我设计了lcddrv_FillColorPre函数,导致不是很通用。 |
|
|
|
只有小组成员才能发言,加入小组>>
3311 浏览 9 评论
2994 浏览 16 评论
3493 浏览 1 评论
9058 浏览 16 评论
4087 浏览 18 评论
1178浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 23:41 , Processed in 1.234994 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号