在NUCLEO_F413ZH实现RTC实时时钟的帖子中,介绍了一种以OLED屏来实现实时时钟的方法,本贴再介绍一种以串口TFT屏实现生肖图案的显示方法。
以前受程序存储空间的限制,在不加挂大容量存储器件的情况下要想显示一幅高质量的图片是件困难的事。对于NUCLEO_F413ZH来说这件事容易了许多,因为它的程序存储空间已达1.5M,显示的图片数据完全可以存到程序中,真有那种土豪有钱就任性的味道。
经实际测试,扣除显示程序所占用的空间,以F413的存储空间完全可以承担12幅图像数据的存储任务,其规格为200*200像素16位色彩的格式。至此用F413来进行12生肖的图像显示,可以说是绰绰有余了。图1为F413所显示的生肖图案效果。
图1 生肖图案显示效果
为便于生肖图案的显示,是将12个生肖图案的数据以头文件方式引入到程序中,相应的说明函数如下:
- // STM32413 + SPI_TFT +12*BMP(200*200*16) OK
- #include "main.h"
- #include "font.h" //显示字符的字模
- #include "sh.h"
- #include "yj.h"
- #include "xg.h"
- #include "hz.h"
- #include "zs.h"
- #include "cn.h"
- #include "yh.h"
- #include "mt.h"
- #include "cl.h"
- #include "ss.h"
- #include "wm.h"
- #include "wy.h"
复制代码2.2寸串口TFT屏与F413的连接关系如下:
CS --PB.4
SCK --PB.3
SDI --PB.5
DC --PB.1
REST --PB.0
对于的引脚输出高低电平的定义语句如下:
- #define LCD_CS_High() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);}
- #define LCD_CS_Low() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);}
- #define LCD_SCK_High() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);}
- #define LCD_SCK_Low() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);}
- #define LCD_SDI_High() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);}
- #define LCD_SDI_Low() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);}
- #define LCD_DC_High() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);}
- #define LCD_DC_Low() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);}
- #define LCD_REST_High() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);}
- #define LCD_REST_Low() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);}
复制代码为进行TFT屏显示,对GPIO的设置函数为:
- void GPIO_Configuration(void)
- {
- __HAL_RCC_GPIOB_CLK_ENABLE();
- GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_5|GPIO_PIN_1|GPIO_PIN_0;
- GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- }
复制代码串口TFT屏的初始化函数为:
- void Lcd_Init(void)
- {
- LCD_REST_Low();
- delay_ms(20);
- LCD_REST_High();
- delay_ms(20);
- LCD_CS_Low();
- LCD_WR_REG(0xCB);
- LCD_WR_DATA8(0x39);
- LCD_WR_DATA8(0x2C);
- LCD_WR_DATA8(0x00);
- LCD_WR_DATA8(0x34);
- LCD_WR_DATA8(0x02);
- LCD_WR_REG(0xCF);
- LCD_WR_DATA8(0x00);
- LCD_WR_DATA8(0XC1);
- LCD_WR_DATA8(0X30);
- LCD_WR_REG(0xE8);
- LCD_WR_DATA8(0x85);
- LCD_WR_DATA8(0x00);
- LCD_WR_DATA8(0x78);
- LCD_WR_REG(0xEA);
- LCD_WR_DATA8(0x00);
- LCD_WR_DATA8(0x00);
- LCD_WR_REG(0xED);
- LCD_WR_DATA8(0x64);
- LCD_WR_DATA8(0x03);
- LCD_WR_DATA8(0X12);
- LCD_WR_DATA8(0X81);
- LCD_WR_REG(0xF7);
- LCD_WR_DATA8(0x20);
- LCD_WR_REG(0xC0); //Power control
- LCD_WR_DATA8(0x23); //VRH[5:0]
- LCD_WR_REG(0xC1); //Power control
- LCD_WR_DATA8(0x10); //SAP[2:0];BT[3:0]
- LCD_WR_REG(0xC5); //VCM control
- LCD_WR_DATA8(0x3e); //?????
- LCD_WR_DATA8(0x28);
- LCD_WR_REG(0xC7); //VCM control2
- LCD_WR_DATA8(0x86); //--
- LCD_WR_REG(0x36); // Memory Access Control
- LCD_WR_DATA8(0x48); //C8 //48 68??//28 E8 ??
- LCD_WR_REG(0x3A);
- LCD_WR_DATA8(0x55);
- LCD_WR_REG(0xB1);
- LCD_WR_DATA8(0x00);
- LCD_WR_DATA8(0x18);
- LCD_WR_REG(0xB6); // Display Function Control
- LCD_WR_DATA8(0x08);
- LCD_WR_DATA8(0x82);
- LCD_WR_DATA8(0x27);
- LCD_WR_REG(0xF2); // 3Gamma Function Disable
- LCD_WR_DATA8(0x00);
- LCD_WR_REG(0x26); //Gamma curve selected
- LCD_WR_DATA8(0x01);
- LCD_WR_REG(0xE0); //Set Gamma
- LCD_WR_DATA8(0x0F);
- LCD_WR_DATA8(0x31);
- LCD_WR_DATA8(0x2B);
- LCD_WR_DATA8(0x0C);
- LCD_WR_DATA8(0x0E);
- LCD_WR_DATA8(0x08);
- LCD_WR_DATA8(0x4E);
- LCD_WR_DATA8(0xF1);
- LCD_WR_DATA8(0x37);
- LCD_WR_DATA8(0x07);
- LCD_WR_DATA8(0x10);
- LCD_WR_DATA8(0x03);
- LCD_WR_DATA8(0x0E);
- LCD_WR_DATA8(0x09);
- LCD_WR_DATA8(0x00);
- LCD_WR_REG(0XE1); //Set Gamma
- LCD_WR_DATA8(0x00);
- LCD_WR_DATA8(0x0E);
- LCD_WR_DATA8(0x14);
- LCD_WR_DATA8(0x03);
- LCD_WR_DATA8(0x11);
- LCD_WR_DATA8(0x07);
- LCD_WR_DATA8(0x31);
- LCD_WR_DATA8(0xC1);
- LCD_WR_DATA8(0x48);
- LCD_WR_DATA8(0x08);
- LCD_WR_DATA8(0x0F);
- LCD_WR_DATA8(0x0C);
- LCD_WR_DATA8(0x31);
- LCD_WR_DATA8(0x36);
- LCD_WR_DATA8(0x0F);
- LCD_WR_REG(0x11); //Exit Sleep
- delay_ms(120);
- LCD_WR_REG(0x29); //Display on
- LCD_WR_REG(0x2c);
- }
复制代码12生肖的显示函数为:
- void show_image(unsigned int x,unsigned int y,unsigned int n)
- { //200*200*16 bit BMP
- unsigned int i,j,k;
- unsigned int da;
- k=0;
- for(i=0;i<200;i++)
- {
- LCD_SetCursor(x,y+i);
- LCD_WriteRAM_Prepare();
- for(j=0;j<200;j++)
- {
- if(n==0) da=gImage_sh[k*2];
- if(n==1) da=gImage_yj[k*2];
- if(n==2) da=gImage_xg[k*2];
- if(n==3) da=gImage_hz[k*2];
- if(n==4) da=gImage_zs[k*2];
- if(n==5) da=gImage_cn[k*2];
- if(n==6) da=gImage_yh[k*2];
- if(n==7) da=gImage_mt[k*2];
- if(n==8) da=gImage_cl[k*2];
- if(n==9) da=gImage_ss[k*2];
- if(n==10) da=gImage_wm[k*2];
- if(n==11) da=gImage_wy[k*2];
- da<<=8;
- if(n==0) da|=gImage_sh[k*2+1];
- if(n==1) da|=gImage_yj[k*2+1];
- if(n==2) da|=gImage_xg[k*2+1];
- if(n==3) da|=gImage_hz[k*2+1];
- if(n==4) da|=gImage_zs[k*2+1];
- if(n==5) da|=gImage_cn[k*2+1];
- if(n==6) da|=gImage_yh[k*2+1];
- if(n==7) da|=gImage_mt[k*2+1];
- if(n==8) da|=gImage_cl[k*2+1];
- if(n==9) da|=gImage_ss[k*2+1];
- if(n==10) da|=gImage_wm[k*2+1];
- if(n==11) da|=gImage_wy[k*2+1];
- LCD_WR_DATA(da);
- k++;
- }
- }
- }
复制代码在主函数main()中,为显示酉鸡年图案的语句为:
LCD_Clear(WHITE); //清屏
show_image(20,10,1);//显示酉鸡图案
// LCD_ShowString(80,220,200,16,16,"2017-1-6");
// LCD_ShowString(80,260,200,16,16," 8:30:00");
显示的原始图案如图2所示。
图2 酉鸡年图案