数码之家

 找回密码
 立即注册
搜索
查看: 185|回复: 5

关于ST32平台本用于8080屏的相册程序适配SPI屏幕的问题

[复制链接]
发表于 2024-5-4 23:10:52 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 2361656471 于 2024-5-4 23:14 编辑

刚开始玩ST32,用的是某款32ZET6平台的开发板,配备的是8080TFT。开发板历程中有个电子相册,觉得挺有意思的。

因为最近学习嵌入式就是为了做个带屏幕小挂件能播放视频运行模拟器游戏啥的,所以对这个历程尤其的感兴趣。


这个电子相册的例程本来是用于8080接口的液晶屏的,利用了FATFS文件系统读取TF卡片的内容,然后利用些解码库解码后送给TFT液晶去显示。支持的格式还是挺多的,支持GIF、JPG、BMP。好像jpg的算法是最复杂的。由于单片机的内存实在是磕碜,解码分辨率高的图像的时候就直接打不开,解码jpg时有些图像颜色会不对,不过不管怎样我觉得直接用单片机进行解码已经是非常厉害了。



后来呢我在网上看到了迷你PMOLED彩色屏幕,觉得挺厉害,这种屏幕没有TFT所以要不停的在矩阵中扫描,频闪是非常明显的。到手以后用厂家提供的历程,用数组的方式显示了图片,就画质来说的确不是普通LCD能媲美的,颜色非常的通透,标准的RGB排列也比手机AMOLED的那种要好,可视角度也非常棒。

屏幕好是挺好,电子相册功能适配到这个OLED屏幕上就更好了。现在已经有了厂家提供的历程,我试着把厂家提供的历程中的LCD.c     LCD.h      LCD_INIT.c    LCD_INIT.h添加进去,编译就直接报错,而且keil5双击报错也不会跳转到相应位置,所以也不知道究竟是哪里错了。检查发现相册程序使用的是 systick.h,oled厂家的历程是delay.h,还有就是一个是sys.h一个是system.h,可是我把头文件改名,然后也添加了delay.h ,不过呢编译下来报错更多了。

开发板相册程序.JPG
oled屏幕厂家例程.JPG



下面我将开发板的适用于8080屏幕的工程文件和oled屏幕厂家历程的文件打了压缩包,希望哪位大神能有空帮忙分析下



工程.zip

6.14 MB, 下载次数: 4, 下载积分: 家元 -55

 楼主| 发表于 2024-5-4 23:16:58 | 显示全部楼层
相册程序主程序

  1. #include "system.h"
  2. #include "SysTick.h"
  3. #include "led.h"
  4. #include "usart.h"
  5. #include "tftlcd.h"
  6. #include "key.h"
  7. #include "malloc.h"
  8. #include "sd_sdio.h"
  9. #include "flash.h"
  10. #include "ff.h"
  11. #include "fatfs_app.h"
  12. #include "key.h"
  13. #include "font_show.h"
  14. #include "piclib.h"
  15. #include "string.h"               
  16. #include "math.h"


  17. int main()
  18. {
  19.         u8 i=0;               
  20.         u8 key;
  21.         u8 res;
  22.         DIR picdir;                         //图片目录
  23.         FILINFO *picfileinfo;//文件信息
  24.         u8 *pname;                        //带路径的文件名
  25.         u16 totpicnum;                 //图片文件总数
  26.         u16 curindex;                //图片当前索引
  27.         u8 pause=0;                        //暂停标记
  28.         u16 temp;
  29.         u32 *picoffsettbl;        //图片文件offset索引表
  30.        
  31.         SysTick_Init(72);
  32.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
  33.         LED_Init();
  34.         USART1_Init(115200);
  35.         TFTLCD_Init();                        //LCD初始化
  36.         KEY_Init();
  37.         EN25QXX_Init();                                         
  38.         my_mem_init(SRAMIN);                //初始化内部内存池
  39.        
  40.         FRONT_COLOR=RED;
  41.         while(SD_Init())//检测不到SD卡
  42.         {
  43.                 LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,16,"SD Card Error!");
  44.                 delay_ms(500);
  45.                 LED2=!LED2;
  46.         }
  47.        
  48.         FATFS_Init();                                //为fatfs相关变量申请内存                                 
  49.           f_mount(fs[0],"0:",1);                 //挂载SD卡
  50.         f_mount(fs[1],"1:",1);                 //挂载SPI FLASH
  51.        
  52.         while(font_init())                         //检查字库
  53.         {  
  54.                 LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,16,"Font Error!   ");
  55.                 delay_ms(500);
  56.         }
  57.         LCD_ShowFontString(10,10,tftlcd_data.width,tftlcd_data.height,"普中科技-PRECHIN",16,0);
  58.         LCD_ShowFontString(10,30,tftlcd_data.width,tftlcd_data.height,"www.prechin.net",16,0);
  59.         LCD_ShowFontString(10,50,tftlcd_data.width,tftlcd_data.height,"数码相框-图片显示",16,0);
  60.        
  61.         while(f_opendir(&picdir,"0:/PICTURE"))//打开图片文件夹
  62.         {            
  63.                 LCD_ShowFontString(10,70,tftlcd_data.width,tftlcd_data.height,"PICTURE文件夹错误!",16,0);
  64.                 delay_ms(200);
  65.                 LCD_Fill(10,70,tftlcd_data.width,86,WHITE);//清除显示
  66.                 delay_ms(200);
  67.         }  
  68.         totpicnum=fatfs_get_filetype_tnum("0:/PICTURE",TYPE_PICTURE); //得到总有效文件数
  69.           while(totpicnum==NULL)//图片文件为0               
  70.         {            
  71.                 LCD_ShowFontString(10,70,tftlcd_data.width,tftlcd_data.height,"没有图片文件!",16,0);
  72.                 delay_ms(200);
  73.                 LCD_Fill(10,70,tftlcd_data.width,86,WHITE);//清除显示
  74.                 delay_ms(200);               
  75.         }
  76.         picfileinfo=(FILINFO*)mymalloc(SRAMIN,sizeof(FILINFO));        //申请内存
  77.         pname=mymalloc(SRAMIN,_MAX_LFN*2+1);        //为带路径的文件名分配内存
  78.         picoffsettbl=mymalloc(SRAMIN,4*totpicnum);        //申请4*totpicnum个字节的内存,用于存放图片索引
  79.         while(!picfileinfo||!pname||!picoffsettbl)        //内存分配出错
  80.         {                   
  81.                 LCD_ShowFontString(10,70,tftlcd_data.width,tftlcd_data.height,"内存分配失败!",16,0);
  82.                 delay_ms(200);                                  
  83.                 LCD_Fill(10,70,tftlcd_data.width,86,WHITE);//清除显示
  84.                 delay_ms(200);                                  
  85.         }         
  86.         //记录索引
  87.     res=f_opendir(&picdir,"0:/PICTURE"); //打开目录
  88.         if(res==FR_OK)
  89.         {
  90.                 curindex=0;//当前索引为0
  91.                 while(1)//全部查询一遍
  92.                 {
  93.                         temp=picdir.dptr;                                                                //记录当前dptr偏移
  94.                 res=f_readdir(&picdir,picfileinfo);                       //读取目录下的一个文件
  95.                 if(res!=FR_OK||picfileinfo->fname[0]==0)break;        //错误了/到末尾了,退出                  
  96.                         res=f_typetell((u8*)picfileinfo->fname);       
  97.                         if((res&0XF0)==TYPE_PICTURE)//取高四位,看看是不是图片文件       
  98.                         {
  99.                                 picoffsettbl[curindex]=temp;//记录索引
  100.                                 curindex++;
  101.                         }            
  102.                 }
  103.         }   
  104.         LCD_ShowFontString(10,70,tftlcd_data.width,tftlcd_data.height,"开始显示...",16,0);
  105.         delay_ms(1500);
  106.         piclib_init();                                                                                //初始化画图                     
  107.         curindex=0;                                                                                        //从0开始显示
  108.            res=f_opendir(&picdir,(const TCHAR*)"0:/PICTURE");         //打开目录
  109.         while(res==FR_OK)//打开成功
  110.         {       
  111.                 dir_sdi(&picdir,picoffsettbl[curindex]);                        //改变当前目录索引          
  112.         res=f_readdir(&picdir,picfileinfo);                       //读取目录下的一个文件
  113.         if(res!=FR_OK||picfileinfo->fname[0]==0)break;        //错误了/到末尾了,退出
  114.                 strcpy((char*)pname,"0:/PICTURE/");                                //复制路径(目录)
  115.                 strcat((char*)pname,(const char*)picfileinfo->fname);//将文件名接在后面
  116.                 LCD_Clear(BLACK);
  117.                 picfile_display(pname,0,0,tftlcd_data.width,tftlcd_data.height,1);//显示图片   
  118.                 LCD_ShowFontString(2,2,tftlcd_data.width,16,pname,16,1);                                 //显示图片名字
  119.                 i=0;
  120.                 while(1)
  121.                 {
  122.                         key=KEY_Scan(0);                //扫描按键
  123.                         if(i>250)
  124.                                 key=1;                        //模拟一次按下K_DOWN   
  125.                         if(i%10==0)
  126.                                 LED1=!LED1;//D1闪烁,提示程序正在运行.
  127.                         if(key==KEY_UP_PRESS)                //上一张
  128.                         {
  129.                                 if(curindex)curindex--;
  130.                                 else curindex=totpicnum-1;
  131.                                 break;
  132.                         }
  133.                         else if(key==KEY1_PRESS)//下一张
  134.                         {
  135.                                 curindex++;                          
  136.                                 if(curindex>=totpicnum)curindex=0;//到末尾的时候,自动从头开始
  137.                                 break;
  138.                         }
  139.                         else if(key==KEY0_PRESS)
  140.                         {
  141.                                 pause=!pause;
  142.                                 LED1=!pause;         //暂停的时候LED1亮.  
  143.                         }
  144.                         if(pause==0)
  145.                                 i++;
  146.                         delay_ms(10);
  147.                 }                                            
  148.                 res=0;  
  149.         }                                                             
  150.         myfree(SRAMIN,picfileinfo);                        //释放内存                                                                       
  151.         myfree(SRAMIN,pname);                                //释放内存                            
  152.         myfree(SRAMIN,picoffsettbl);                        //释放内存
  153. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-5-4 23:20:35 | 显示全部楼层
相册程序的8080屏幕驱动代码部分

  1.         LCD_Display_Dir(TFTLCD_DIR);                //0:竖屏  1:横屏  默认竖屏
  2.         LCD_Clear(WHITE);
  3. }

  4. //清屏函数
  5. //color:要清屏的填充色
  6. void LCD_Clear(u16 color)
  7. {
  8.         uint16_t i, j ;

  9.         LCD_Set_Window(0, 0, tftlcd_data.width-1, tftlcd_data.height-1);         //作用区域
  10.           for(i=0; i<tftlcd_data.width; i++)
  11.         {
  12.                 for (j=0; j<tftlcd_data.height; j++)
  13.                 {
  14.                         LCD_WriteData_Color(color);
  15.                 }
  16.         }
  17. }


  18. //在指定区域内填充单个颜色
  19. //(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)   
  20. //color:要填充的颜色
  21. void LCD_Fill(u16 xState,u16 yState,u16 xEnd,u16 yEnd,u16 color)
  22. {         
  23.         uint16_t temp;

  24.     if((xState > xEnd) || (yState > yEnd))
  25.     {
  26.         return;
  27.     }   
  28.         LCD_Set_Window(xState, yState, xEnd, yEnd);
  29.     xState = xEnd - xState + 1;
  30.         yState = yEnd - yState + 1;

  31.         while(xState--)
  32.         {
  33.                  temp = yState;
  34.                 while (temp--)
  35.                  {                       
  36.                         LCD_WriteData_Color(color);       
  37.                 }
  38.         }       
  39. }

  40. //在指定区域内填充指定颜色块                         
  41. //(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)   
  42. //color:要填充的颜色
  43. void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)
  44. {  
  45.         u16 height,width;
  46.         u16 i,j;
  47.         width=ex-sx+1;                         //得到填充的宽度
  48.         height=ey-sy+1;                        //高度
  49.        
  50.         for(i=0;i<height;i++)
  51.         {
  52.                 for(j=0;j<width;j++)
  53.                 {
  54.                         LCD_Set_Window(sx+j, sy+i,ex, ey);
  55.                         LCD_WriteData_Color(color[i*width+j]);
  56.                 }
  57.         }                  
  58. }
  59. //画点
  60. //x,y:坐标
  61. //FRONT_COLOR:此点的颜色
  62. void LCD_DrawPoint(u16 x,u16 y)
  63. {
  64.         LCD_Set_Window(x, y, x, y);  //设置点的位置
  65.         LCD_WriteData_Color(FRONT_COLOR);       
  66. }

  67. //快速画点
  68. //x,y:坐标
  69. //color:颜色
  70. void LCD_DrawFRONT_COLOR(u16 x,u16 y,u16 color)
  71. {          
  72.         LCD_Set_Window(x, y, x, y);
  73.         LCD_WriteData_Color(color);       
  74. }

  75. //画线
  76. //x1,y1:起点坐标
  77. //x2,y2:终点坐标  
  78. void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
  79. {
  80.         u16 t;
  81.         int xerr=0,yerr=0,delta_x,delta_y,distance;
  82.         int incx,incy,uRow,uCol;
  83.         delta_x=x2-x1; //计算坐标增量
  84.         delta_y=y2-y1;
  85.         uRow=x1;
  86.         uCol=y1;
  87.         if(delta_x>0)incx=1; //设置单步方向
  88.         else if(delta_x==0)incx=0;//垂直线
  89.         else {incx=-1;delta_x=-delta_x;}
  90.         if(delta_y>0)incy=1;
  91.         else if(delta_y==0)incy=0;//水平线
  92.         else{incy=-1;delta_y=-delta_y;}
  93.         if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
  94.         else distance=delta_y;
  95.         for(t=0;t<=distance+1;t++ )//画线输出
  96.         {  
  97.                 LCD_DrawPoint(uRow,uCol);//画点
  98.                 xerr+=delta_x ;
  99.                 yerr+=delta_y ;
  100.                 if(xerr>distance)
  101.                 {
  102.                         xerr-=distance;
  103.                         uRow+=incx;
  104.                 }
  105.                 if(yerr>distance)
  106.                 {
  107.                         yerr-=distance;
  108.                         uCol+=incy;
  109.                 }
  110.         }  
  111. }

  112. void LCD_DrawLine_Color(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
  113. {
  114.         u16 t;
  115.         int xerr=0,yerr=0,delta_x,delta_y,distance;
  116.         int incx,incy,uRow,uCol;
  117.         delta_x=x2-x1; //计算坐标增量
  118.         delta_y=y2-y1;
  119.         uRow=x1;
  120.         uCol=y1;
  121.         if(delta_x>0)incx=1; //设置单步方向
  122.         else if(delta_x==0)incx=0;//垂直线
  123.         else {incx=-1;delta_x=-delta_x;}
  124.         if(delta_y>0)incy=1;
  125.         else if(delta_y==0)incy=0;//水平线
  126.         else{incy=-1;delta_y=-delta_y;}
  127.         if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
  128.         else distance=delta_y;
  129.         for(t=0;t<=distance+1;t++ )//画线输出
  130.         {  
  131.                 LCD_DrawFRONT_COLOR(uRow,uCol,color);//画点
  132.                 xerr+=delta_x ;
  133.                 yerr+=delta_y ;
  134.                 if(xerr>distance)
  135.                 {
  136.                         xerr-=distance;
  137.                         uRow+=incx;
  138.                 }
  139.                 if(yerr>distance)
  140.                 {
  141.                         yerr-=distance;
  142.                         uCol+=incy;
  143.                 }
  144.         }  
  145. }


  146. // 画一个十字的标记
  147. // x:标记的X坐标
  148. // y:标记的Y坐标
  149. // color:标记的颜色
  150. void LCD_DrowSign(uint16_t x, uint16_t y, uint16_t color)
  151. {
  152.     uint8_t i;

  153.     /* 画点 */
  154.     LCD_Set_Window(x-1, y-1, x+1, y+1);
  155.     for(i=0; i<9; i++)
  156.     {
  157.                 LCD_WriteData_Color(color);   
  158.     }

  159.     /* 画竖 */
  160.     LCD_Set_Window(x-4, y, x+4, y);
  161.     for(i=0; i<9; i++)
  162.     {
  163.                 LCD_WriteData_Color(color);
  164.     }

  165.     /* 画横 */
  166.     LCD_Set_Window(x, y-4, x, y+4);
  167.     for(i=0; i<9; i++)
  168.     {
  169.                 LCD_WriteData_Color(color);
  170.     }
  171. }

  172. //画矩形          
  173. //(x1,y1),(x2,y2):矩形的对角坐标
  174. void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2)
  175. {
  176.         LCD_DrawLine(x1,y1,x2,y1);
  177.         LCD_DrawLine(x1,y1,x1,y2);
  178.         LCD_DrawLine(x1,y2,x2,y2);
  179.         LCD_DrawLine(x2,y1,x2,y2);
  180. }
  181. //在指定位置画一个指定大小的圆
  182. //(x,y):中心点
  183. //r    :半径
  184. void LCD_Draw_Circle(u16 x0,u16 y0,u8 r)
  185. {
  186.         int a,b;
  187.         int di;
  188.         a=0;b=r;          
  189.         di=3-(r<<1);             //判断下个点位置的标志
  190.         while(a<=b)
  191.         {
  192.                 LCD_DrawPoint(x0+a,y0-b);             //5
  193.                 LCD_DrawPoint(x0+b,y0-a);             //0           
  194.                 LCD_DrawPoint(x0+b,y0+a);             //4               
  195.                 LCD_DrawPoint(x0+a,y0+b);             //6
  196.                 LCD_DrawPoint(x0-a,y0+b);             //1      
  197.                 LCD_DrawPoint(x0-b,y0+a);            
  198.                 LCD_DrawPoint(x0-a,y0-b);             //2            
  199.                   LCD_DrawPoint(x0-b,y0-a);             //7                     
  200.                 a++;
  201.                 //使用Bresenham算法画圆     
  202.                 if(di<0)di +=4*a+6;          
  203.                 else
  204.                 {
  205.                         di+=10+4*(a-b);   
  206.                         b--;
  207.                 }                                                     
  208.         }
  209. }



  210. //在指定位置显示一个字符
  211. //x,y:起始坐标
  212. //num:要显示的字符:" "--->"~"
  213. //size:字体大小 12/16/24
  214. //mode:叠加方式(1)还是非叠加方式(0)
  215. void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
  216. {                                                            
  217.     u8 temp,t1,t;
  218.         u16 y0=y;
  219.         u8 csize=(size/8+((size%8)?1:0))*(size/2);                //得到字体一个字符对应点阵集所占的字节数       
  220.         num=num-' ';//得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)
  221.         for(t=0;t<csize;t++)
  222.         {   
  223.                 if(size==12)temp=ascii_1206[num][t];                  //调用1206字体
  224.                 else if(size==16)temp=ascii_1608[num][t];        //调用1608字体
  225.                 else if(size==24)temp=ascii_2412[num][t];        //调用2412字体
  226.                 else return;                                                                //没有的字库
  227.                 for(t1=0;t1<8;t1++)
  228.                 {                            
  229.                         if(temp&0x80)LCD_DrawFRONT_COLOR(x,y,FRONT_COLOR);
  230.                         else if(mode==0)LCD_DrawFRONT_COLOR(x,y,BACK_COLOR);
  231.                         temp<<=1;
  232.                         y++;
  233.                         if(y>=tftlcd_data.height)return;                //超区域了
  234.                         if((y-y0)==size)
  235.                         {
  236.                                 y=y0;
  237.                                 x++;
  238.                                 if(x>=tftlcd_data.width)return;        //超区域了
  239.                                 break;
  240.                         }
  241.                 }           
  242.         }                                            
  243. }   
  244. //m^n函数
  245. //返回值:m^n次方.
  246. u32 LCD_Pow(u8 m,u8 n)
  247. {
  248.         u32 result=1;         
  249.         while(n--)result*=m;   
  250.         return result;
  251. }                         
  252. //显示数字,高位为0,则不显示
  253. //x,y :起点坐标         
  254. //len :数字的位数
  255. //size:字体大小
  256. //color:颜色
  257. //num:数值(0~4294967295);         
  258. void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)
  259. {                
  260.         u8 t,temp;
  261.         u8 enshow=0;                                                  
  262.         for(t=0;t<len;t++)
  263.         {
  264.                 temp=(num/LCD_Pow(10,len-t-1))%10;
  265.                 if(enshow==0&&t<(len-1))
  266.                 {
  267.                         if(temp==0)
  268.                         {
  269.                                 LCD_ShowChar(x+(size/2)*t,y,' ',size,0);
  270.                                 continue;
  271.                         }else enshow=1;
  272.                           
  273.                 }
  274.                  LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0);
  275.         }
  276. }

  277. //显示数字,高位为0,还是显示
  278. //x,y:起点坐标
  279. //num:数值(0~999999999);         
  280. //len:长度(即要显示的位数)
  281. //size:字体大小
  282. //mode:
  283. //[7]:0,不填充;1,填充0.
  284. //[6:1]:保留
  285. //[0]:0,非叠加显示;1,叠加显示.
  286. void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode)
  287. {  
  288.         u8 t,temp;
  289.         u8 enshow=0;                                                  
  290.         for(t=0;t<len;t++)
  291.         {
  292.                 temp=(num/LCD_Pow(10,len-t-1))%10;
  293.                 if(enshow==0&&t<(len-1))
  294.                 {
  295.                         if(temp==0)
  296.                         {
  297.                                 if(mode&0X80)LCD_ShowChar(x+(size/2)*t,y,'0',size,mode&0X01);  
  298.                                 else LCD_ShowChar(x+(size/2)*t,y,' ',size,mode&0X01);  
  299.                                 continue;
  300.                         }else enshow=1;
  301.                           
  302.                 }
  303.                  LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,mode&0X01);
  304.         }
  305. }
  306. //显示字符串
  307. //x,y:起点坐标
  308. //width,height:区域大小  
  309. //size:字体大小
  310. //*p:字符串起始地址                  
  311. void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p)
  312. {         
  313.         u8 x0=x;
  314.         width+=x;
  315.         height+=y;
  316.     while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
  317.     {      
  318.         if(x>=width){x=x0;y+=size;}
  319.         if(y>=height)break;//退出
  320.         LCD_ShowChar(x,y,*p,size,0);
  321.         x+=size/2;
  322.         p++;
  323.     }  
  324. }

  325. /****************************************************************************
  326. *函数名:LCD_ShowFontHZ
  327. *输  入:x:汉字显示的X坐标
  328. *      * y:汉字显示的Y坐标
  329. *      * cn:要显示的汉字
  330. *      * wordColor:文字的颜色
  331. *      * backColor:背景颜色
  332. *输  出:
  333. *功  能:写二号楷体汉字
  334. ****************************************************************************/
  335. #if 0
  336. void LCD_ShowFontHZ(u16 x, u16 y, u8 *cn)         
  337. {  
  338.         u8 i, j, wordNum;
  339.         u16 color;
  340.         while (*cn != '\0')
  341.         {
  342.                 LCD_Set_Window(x, y, x+31, y+28);
  343.                 for (wordNum=0; wordNum<20; wordNum++)
  344.                 {        //wordNum扫描字库的字数
  345.                         if ((CnChar32x29[wordNum].Index[0]==*cn)
  346.                              &&(CnChar32x29[wordNum].Index[1]==*(cn+1)))
  347.                         {
  348.                                 for(i=0; i<116; i++)
  349.                                 {        //MSK的位数
  350.                                         color=CnChar32x29[wordNum].Msk[i];
  351.                                         for(j=0;j<8;j++)
  352.                                         {
  353.                                                 if((color&0x80)==0x80)
  354.                                                 {
  355.                                                         LCD_WriteData_Color(FRONT_COLOR);                                                
  356.                                                 }                                                
  357.                                                 else
  358.                                                 {
  359.                                                         LCD_WriteData_Color(BACK_COLOR);
  360.                                                 }
  361.                                                 color<<=1;
  362.                                         }//for(j=0;j<8;j++)结束
  363.                                 }   
  364.                         }
  365.                 } //for (wordNum=0; wordNum<20; wordNum++)结束        
  366.                 cn += 2;
  367.                 x += 32;
  368.         }
  369. }
  370. #endif


  371. #if 1
  372. void LCD_ShowFontHZ(u16 x, u16 y, u8 *cn)
  373. {
  374.         u8 i, j, wordNum;
  375.         u16 color;
  376.         u16 x0=x;
  377.         u16 y0=y;
  378.         while (*cn != '\0')
  379.         {
  380.                 for (wordNum=0; wordNum<20; wordNum++)
  381.                 {        //wordNum扫描字库的字数
  382.                         if ((CnChar32x29[wordNum].Index[0]==*cn)
  383.                              &&(CnChar32x29[wordNum].Index[1]==*(cn+1)))
  384.                         {
  385.                                 for(i=0; i<116; i++)
  386.                                 {        //MSK的位数
  387.                                         color=CnChar32x29[wordNum].Msk[i];
  388.                                         for(j=0;j<8;j++)
  389.                                         {
  390.                                                 if((color&0x80)==0x80)
  391.                                                 {
  392.                                                         LCD_DrawFRONT_COLOR(x,y,FRONT_COLOR);
  393.                                                 }                                                
  394.                                                 else
  395.                                                 {
  396.                                                         LCD_DrawFRONT_COLOR(x,y,BACK_COLOR);
  397.                                                 }
  398.                                                 color<<=1;
  399.                                                 x++;
  400.                                                 if((x-x0)==32)
  401.                                                 {
  402.                                                         x=x0;
  403.                                                         y++;
  404.                                                         if((y-y0)==29)
  405.                                                         {
  406.                                                                 y=y0;
  407.                                                         }
  408.                                                 }
  409.                                         }//for(j=0;j<8;j++)结束
  410.                                 }       
  411.                         }
  412.                        
  413.                 } //for (wordNum=0; wordNum<20; wordNum++)结束        
  414.                 cn += 2;
  415.                 x += 32;
  416.                 x0=x;
  417.         }
  418. }       
  419. #endif

  420. void LCD_ShowPicture(u16 x, u16 y, u16 wide, u16 high,u8 *pic)
  421. {
  422.         u16 i,j;
  423.         u16 temp = 0;
  424.         long tmp=0,num=0;
  425.         LCD_Set_Window(x, y, x+wide-1, y+high-1);
  426.         num = wide * high*2 ;
  427.         //方法1:提高显示速度,太快可能导致图像显示不全
  428. //        do
  429. //        {  
  430. //                temp = pic[tmp + 1];
  431. //                temp = temp << 8;
  432. //                temp = temp | pic[tmp];
  433. //                LCD_WriteData_Color(temp);//逐点显示
  434. //                tmp += 2;
  435. //        }
  436. //        while(tmp < num);
  437.        
  438.         //方法2:可有效消除LCD显示速度过快导致显示不全问题
  439.         for(i=0;i<high;i++)
  440.         {
  441.                 for(j=0;j<wide;j++)
  442.                 {
  443.                         temp = pic[tmp + 1];
  444.                         temp = temp << 8;
  445.                         temp = temp | pic[tmp];
  446.                         LCD_DrawFRONT_COLOR(x+j,y+i,temp);
  447.                         tmp += 2;
  448.                 }
  449.         }       
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-5-4 23:21:46 | 显示全部楼层
需要适配的SPI屏幕的驱动代码
  1. #include "lcd.h"
  2. #include "lcd_init.h"
  3. #include "lcdfont.h"
  4. #include "delay.h"


  5. /******************************************************************************
  6.       函数说明:在指定区域填充颜色
  7.       入口数据:xsta,ysta   起始坐标
  8.                 xend,yend   终止坐标
  9.                                                                 color       要填充的颜色
  10.       返回值:  无
  11. ******************************************************************************/
  12. void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
  13. {         
  14.         u16 i,j;
  15.         LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
  16.         for(i=ysta;i<yend;i++)
  17.         {                                                                                                                           
  18.                 for(j=xsta;j<xend;j++)
  19.                 {
  20.                         LCD_WR_DATA(color);
  21.                 }
  22.         }                                                       
  23. }

  24. /******************************************************************************
  25.       函数说明:在指定位置画点
  26.       入口数据:x,y 画点坐标
  27.                 color 点的颜色
  28.       返回值:  无
  29. ******************************************************************************/
  30. void LCD_DrawPoint(u16 x,u16 y,u16 color)
  31. {
  32.         LCD_Address_Set(x,y,x,y);//设置光标位置
  33.         LCD_WR_DATA(color);
  34. }


  35. /******************************************************************************
  36.       函数说明:画线
  37.       入口数据:x1,y1   起始坐标
  38.                 x2,y2   终止坐标
  39.                 color   线的颜色
  40.       返回值:  无
  41. ******************************************************************************/
  42. void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
  43. {
  44.         u16 t;
  45.         int xerr=0,yerr=0,delta_x,delta_y,distance;
  46.         int incx,incy,uRow,uCol;
  47.         delta_x=x2-x1; //计算坐标增量
  48.         delta_y=y2-y1;
  49.         uRow=x1;//画线起点坐标
  50.         uCol=y1;
  51.         if(delta_x>0)incx=1; //设置单步方向
  52.         else if (delta_x==0)incx=0;//垂直线
  53.         else {incx=-1;delta_x=-delta_x;}
  54.         if(delta_y>0)incy=1;
  55.         else if (delta_y==0)incy=0;//水平线
  56.         else {incy=-1;delta_y=-delta_x;}
  57.         if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
  58.         else distance=delta_y;
  59.         for(t=0;t<distance+1;t++)
  60.         {
  61.                 LCD_DrawPoint(uRow,uCol,color);//画点
  62.                 xerr+=delta_x;
  63.                 yerr+=delta_y;
  64.                 if(xerr>distance)
  65.                 {
  66.                         xerr-=distance;
  67.                         uRow+=incx;
  68.                 }
  69.                 if(yerr>distance)
  70.                 {
  71.                         yerr-=distance;
  72.                         uCol+=incy;
  73.                 }
  74.         }
  75. }


  76. /******************************************************************************
  77.       函数说明:画矩形
  78.       入口数据:x1,y1   起始坐标
  79.                 x2,y2   终止坐标
  80.                 color   矩形的颜色
  81.       返回值:  无
  82. ******************************************************************************/
  83. void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
  84. {
  85.         LCD_DrawLine(x1,y1,x2,y1,color);
  86.         LCD_DrawLine(x1,y1,x1,y2,color);
  87.         LCD_DrawLine(x1,y2,x2,y2,color);
  88.         LCD_DrawLine(x2,y1,x2,y2,color);
  89. }


  90. /******************************************************************************
  91.       函数说明:画圆
  92.       入口数据:x0,y0   圆心坐标
  93.                 r       半径
  94.                 color   圆的颜色
  95.       返回值:  无
  96. ******************************************************************************/
  97. void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color)
  98. {
  99.         int a,b;
  100.         a=0;b=r;          
  101.         while(a<=b)
  102.         {
  103.                 LCD_DrawPoint(x0-b,y0-a,color);             //3           
  104.                 LCD_DrawPoint(x0+b,y0-a,color);             //0           
  105.                 LCD_DrawPoint(x0-a,y0+b,color);             //1               
  106.                 LCD_DrawPoint(x0-a,y0-b,color);             //2            
  107.                 LCD_DrawPoint(x0+b,y0+a,color);             //4               
  108.                 LCD_DrawPoint(x0+a,y0-b,color);             //5
  109.                 LCD_DrawPoint(x0+a,y0+b,color);             //6
  110.                 LCD_DrawPoint(x0-b,y0+a,color);             //7
  111.                 a++;
  112.                 if((a*a+b*b)>(r*r))//判断要画的点是否过远
  113.                 {
  114.                         b--;
  115.                 }
  116.         }
  117. }

  118. /******************************************************************************
  119.       函数说明:显示汉字串
  120.       入口数据:x,y显示坐标
  121.                 *s 要显示的汉字串
  122.                 fc 字的颜色
  123.                 bc 字的背景色
  124.                 sizey 字号 可选 16 24 32
  125.                 mode:  0非叠加模式  1叠加模式
  126.       返回值:  无
  127. ******************************************************************************/
  128. void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  129. {
  130.         while(*s!=0)
  131.         {
  132.                 if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
  133.                 else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
  134.                 else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
  135.                 else return;
  136.                 s+=2;
  137.                 x+=sizey;
  138.         }
  139. }

  140. /******************************************************************************
  141.       函数说明:显示单个16x16汉字
  142.       入口数据:x,y显示坐标
  143.                 *s 要显示的汉字
  144.                 fc 字的颜色
  145.                 bc 字的背景色
  146.                 sizey 字号
  147.                 mode:  0非叠加模式  1叠加模式
  148.       返回值:  无
  149. ******************************************************************************/
  150. void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  151. {
  152.         u8 i,j;
  153.         u16 k;
  154.         u16 HZnum;//汉字数目
  155.         u16 TypefaceNum;//一个字符所占字节大小
  156.         u16 x0=x;
  157.         TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
  158.                                   //也建议用户使用这样大小的字,否则显示容易出问题!
  159.         HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);        //统计汉字数目
  160.         for(k=0;k<HZnum;k++)
  161.         {
  162.                 if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1)))
  163.                 {        
  164.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  165.                         for(i=0;i<TypefaceNum;i++)
  166.                         {
  167.                                 for(j=0;j<8;j++)
  168.                                 {       
  169.                                         if(!mode)//非叠加方式
  170.                                         {
  171.                                                 if(tfont16[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
  172.                                                 else LCD_WR_DATA(bc);
  173.                                         }
  174.                                         else//叠加方式
  175.                                         {
  176.                                                 if(tfont16[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  177.                                                 x++;
  178.                                                 if((x-x0)==sizey)
  179.                                                 {
  180.                                                         x=x0;
  181.                                                         y++;
  182.                                                         break;
  183.                                                 }
  184.                                         }
  185.                                 }
  186.                         }
  187.                 }                                         
  188.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  189.         }
  190. }


  191. /******************************************************************************
  192.       函数说明:显示单个24x24汉字
  193.       入口数据:x,y显示坐标
  194.                 *s 要显示的汉字
  195.                 fc 字的颜色
  196.                 bc 字的背景色
  197.                 sizey 字号
  198.                 mode:  0非叠加模式  1叠加模式
  199.       返回值:  无
  200. ******************************************************************************/
  201. void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  202. {
  203.         u8 i,j;
  204.         u16 k;
  205.         u16 HZnum;//汉字数目
  206.         u16 TypefaceNum;//一个字符所占字节大小
  207.         u16 x0=x;
  208.         TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
  209.                                   //也建议用户使用这样大小的字,否则显示容易出问题!
  210.         HZnum=sizeof(tfont24)/sizeof(typFNT_GB24);        //统计汉字数目
  211.         for(k=0;k<HZnum;k++)
  212.         {
  213.                 if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1)))
  214.                 {        
  215.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  216.                         for(i=0;i<TypefaceNum;i++)
  217.                         {
  218.                                 for(j=0;j<8;j++)
  219.                                 {       
  220.                                         if(!mode)//非叠加方式
  221.                                         {
  222.                                                 if(tfont24[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
  223.                                                 else LCD_WR_DATA(bc);
  224.                                         }
  225.                                         else//叠加方式
  226.                                         {
  227.                                                 if(tfont24[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  228.                                                 x++;
  229.                                                 if((x-x0)==sizey)
  230.                                                 {
  231.                                                         x=x0;
  232.                                                         y++;
  233.                                                         break;
  234.                                                 }
  235.                                         }
  236.                                 }
  237.                         }
  238.                 }                                         
  239.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  240.         }
  241. }

  242. /******************************************************************************
  243.       函数说明:显示单个32x32汉字
  244.       入口数据:x,y显示坐标
  245.                 *s 要显示的汉字
  246.                 fc 字的颜色
  247.                 bc 字的背景色
  248.                 sizey 字号
  249.                 mode:  0非叠加模式  1叠加模式
  250.       返回值:  无
  251. ******************************************************************************/
  252. void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  253. {
  254.         u8 i,j;
  255.         u16 k;
  256.         u16 HZnum;//汉字数目
  257.         u16 TypefaceNum;//一个字符所占字节大小
  258.         u16 x0=x;
  259.         TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
  260.                                   //也建议用户使用这样大小的字,否则显示容易出问题!
  261.         HZnum=sizeof(tfont32)/sizeof(typFNT_GB32);        //统计汉字数目
  262.         for(k=0;k<HZnum;k++)
  263.         {
  264.                 if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1)))
  265.                 {        
  266.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  267.                         for(i=0;i<TypefaceNum;i++)
  268.                         {
  269.                                 for(j=0;j<8;j++)
  270.                                 {       
  271.                                         if(!mode)//非叠加方式
  272.                                         {
  273.                                                 if(tfont32[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
  274.                                                 else LCD_WR_DATA(bc);
  275.                                         }
  276.                                         else//叠加方式
  277.                                         {
  278.                                                 if(tfont32[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  279.                                                 x++;
  280.                                                 if((x-x0)==sizey)
  281.                                                 {
  282.                                                         x=x0;
  283.                                                         y++;
  284.                                                         break;
  285.                                                 }
  286.                                         }
  287.                                 }
  288.                         }
  289.                 }                                         
  290.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  291.         }
  292. }


  293. /******************************************************************************
  294.       函数说明:显示单个字符
  295.       入口数据:x,y显示坐标
  296.                 num 要显示的字符
  297.                 fc 字的颜色
  298.                 bc 字的背景色
  299.                 sizey 字号
  300.                 mode:  0非叠加模式  1叠加模式
  301.       返回值:  无
  302. ******************************************************************************/
  303. void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
  304. {
  305.         u8 temp,sizex,t;
  306.         u16 i,TypefaceNum;//一个字符所占字节大小
  307.         u16 x0=x;
  308.         sizex=sizey/2;
  309.         TypefaceNum=sizex/8*sizey;
  310.         num=num-' ';    //得到偏移后的值
  311.         LCD_Address_Set(x,y,x+sizex-1,y+sizey-1);  //设置光标位置
  312.         for(i=0;i<TypefaceNum;i++)
  313.         {
  314.                 if(sizey==16)temp=ascii_1608[num][i];                       //调用8x16字体
  315.                 else if(sizey==32)temp=ascii_3216[num][i];                 //调用16x32字体
  316.                 else return;
  317.                 for(t=0;t<8;t++)
  318.                 {
  319.                         if(!mode)//非叠加模式
  320.                         {
  321.                                 if(temp&(0x01<<t))LCD_WR_DATA(fc);
  322.                                 else LCD_WR_DATA(bc);
  323.                         }
  324.                         else//叠加模式
  325.                         {
  326.                                 if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
  327.                                 x++;
  328.                                 if((x-x0)==sizex)
  329.                                 {
  330.                                         x=x0;
  331.                                         y++;
  332.                                         break;
  333.                                 }
  334.                         }
  335.                 }
  336.         }                      
  337. }


  338. /******************************************************************************
  339.       函数说明:显示字符串
  340.       入口数据:x,y显示坐标
  341.                 *p 要显示的字符串
  342.                 fc 字的颜色
  343.                 bc 字的背景色
  344.                 sizey 字号
  345.                 mode:  0非叠加模式  1叠加模式
  346.       返回值:  无
  347. ******************************************************************************/
  348. void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
  349. {         
  350.         while(*p!='\0')
  351.         {      
  352.                 LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
  353.                 x+=sizey/2;
  354.                 p++;
  355.         }  
  356. }


  357. /******************************************************************************
  358.       函数说明:显示数字
  359.       入口数据:m底数,n指数
  360.       返回值:  无
  361. ******************************************************************************/
  362. u32 mypow(u8 m,u8 n)
  363. {
  364.         u32 result=1;         
  365.         while(n--)result*=m;
  366.         return result;
  367. }


  368. /******************************************************************************
  369.       函数说明:显示整数变量
  370.       入口数据:x,y显示坐标
  371.                 num 要显示整数变量
  372.                 len 要显示的位数
  373.                 fc 字的颜色
  374.                 bc 字的背景色
  375.                 sizey 字号
  376.       返回值:  无
  377. ******************************************************************************/
  378. void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey)
  379. {                
  380.         u8 t,temp;
  381.         u8 enshow=0;
  382.         u8 sizex=sizey/2;
  383.         for(t=0;t<len;t++)
  384.         {
  385.                 temp=(num/mypow(10,len-t-1))%10;
  386.                 if(enshow==0&&t<(len-1))
  387.                 {
  388.                         if(temp==0)
  389.                         {
  390.                                 LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);
  391.                                 continue;
  392.                         }else enshow=1;
  393.                           
  394.                 }
  395.                  LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
  396.         }
  397. }


  398. /******************************************************************************
  399.       函数说明:显示两位小数变量
  400.       入口数据:x,y显示坐标
  401.                 num 要显示小数变量
  402.                 len 要显示的位数
  403.                 fc 字的颜色
  404.                 bc 字的背景色
  405.                 sizey 字号
  406.       返回值:  无
  407. ******************************************************************************/
  408. void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey)
  409. {                
  410.         u8 t,temp,sizex;
  411.         u16 num1;
  412.         sizex=sizey/2;
  413.         num1=num*100;
  414.         for(t=0;t<len;t++)
  415.         {
  416.                 temp=(num1/mypow(10,len-t-1))%10;
  417.                 if(t==(len-2))
  418.                 {
  419.                         LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0);
  420.                         t++;
  421.                         len+=1;
  422.                 }
  423.                  LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
  424.         }
  425. }


  426. /******************************************************************************
  427.       函数说明:显示图片
  428.       入口数据:x,y起点坐标
  429.                 length 图片长度
  430.                 width  图片宽度
  431.                 pic[]  图片数组   
  432.       返回值:  无
  433. ******************************************************************************/
  434. void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
  435. {
  436.         u16 i,j,k=0;
  437.         LCD_Address_Set(x,y,x+length-1,y+width-1);
  438.         for(i=0;i<length;i++)
  439.         {
  440.                 for(j=0;j<width;j++)
  441.                 {
  442.                         LCD_WR_DATA8(pic[k*2]);
  443.                         LCD_WR_DATA8(pic[k*2+1]);
  444.                         k++;
  445.                 }
  446.         }                       
  447. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2024-5-5 10:40:09 | 显示全部楼层
本帖最后由 inthsunshine 于 2024-5-5 13:47 编辑

STM32H7系列带硬件jpg解码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-5-19 05:49 , Processed in 0.202801 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表