- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * File Name : lcd.c
- * Description : Code for lcd application
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2023 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include <string.h>
- #include "lcd.h"
- #include "spi.h"
- #include "FONT.H"
- /* Private includes ----------------------------------------------------------*/
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- HAL_StatusTypeDef spi_status = HAL_OK;
- /* Private function prototypes -----------------------------------------------*/
- /* Private application code --------------------------------------------------*/
- /******************************************************************************
- 函数说明:LCD串行数据写入函数
- 入口数据:dat 要写入的串行数据
- 返回值: 无
- ******************************************************************************/
- void LCD_Writ_Bus(uint8_t data)
- {
- // uint8_t i;
- LCD_CS_L;
- spi_status = HAL_SPI_Transmit(&hspi2,&data,1,0xff);
- //spi_status = HAL_SPI_Transmit_DMA(&hspi1,&data,1);
- LCD_CS_H;
- }
- /******************************************************************************
- 函数说明:LCD写入数据
- 入口数据:dat 写入的数据
- 返回值: 无
- ******************************************************************************/
- void LCD_WR_DATA8(uint8_t dat)
- {
- LCD_Writ_Bus(dat);
- }
- /******************************************************************************
- 函数说明:LCD写入数据
- 入口数据:dat 写入的数据
- 返回值: 无
- ******************************************************************************/
- void LCD_WR_DATA16(uint16_t dat)
- {
- LCD_Writ_Bus(dat>>8);
- LCD_Writ_Bus(dat);
- }
- /******************************************************************************
- 函数说明:LCD写入命令
- 入口数据:dat 写入的命令
- 返回值: 无
- ******************************************************************************/
- void LCD_WR_CMD(uint8_t dat)
- {
- LCD_DC_L;//写命令
- LCD_Writ_Bus(dat);
- LCD_DC_H;//写数据
- }
- /******************************************************************************
- 函数说明:设置起始和结束地址
- 入口数据:x1,x2 设置列的起始和结束地址
- y1,y2 设置行的起始和结束地址
- 返回值: 无
- ******************************************************************************/
- void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
- {
- if(USE_HORIZONTAL==0)
- {
- LCD_WR_CMD(0x2a);//列地址设置
- LCD_WR_DATA16(x1);
- LCD_WR_DATA16(x2);
- LCD_WR_CMD(0x2b);//行地址设置
- LCD_WR_DATA16(y1);
- LCD_WR_DATA16(y2);
- LCD_WR_CMD(0x2c);//储存器写
- }
- else if(USE_HORIZONTAL==1)
- {
- LCD_WR_CMD(0x2a);//列地址设置
- LCD_WR_DATA16(x1);
- LCD_WR_DATA16(x2);
- LCD_WR_CMD(0x2b);//行地址设置
- LCD_WR_DATA16(y1+80);
- LCD_WR_DATA16(y2+80);
- LCD_WR_CMD(0x2c);//储存器写
- }
- else if(USE_HORIZONTAL==2)
- {
- LCD_WR_CMD(0x2a);//列地址设置
- LCD_WR_DATA16(x1);
- LCD_WR_DATA16(x2);
- LCD_WR_CMD(0x2b);//行地址设置
- LCD_WR_DATA16(y1);
- LCD_WR_DATA16(y2);
- LCD_WR_CMD(0x2c);//储存器写
- }
- else
- {
- LCD_WR_CMD(0x2a);//列地址设置
- LCD_WR_DATA16(x1+80);
- LCD_WR_DATA16(x2+80);
- LCD_WR_CMD(0x2b);//行地址设置
- LCD_WR_DATA16(y1);
- LCD_WR_DATA16(y2);
- LCD_WR_CMD(0x2c);//储存器写
- }
- }
- /******************************************************************************
- 函数说明:液晶初始化
- 入口数据:无
- 返回值: 无
- ******************************************************************************/
-
- void LCD_Init(void)
- {
- // LCD_GPIO_Init();//初始化GPIO
-
- LCD_RES_L;//复位
- osDelay(100);
- LCD_RES_H;
- osDelay(100);
-
- LCD_WR_CMD(0x11); //无此指令,不能正常初始化芯片,无显示
- osDelay(120);
- LCD_WR_CMD(0x36); //设置内存扫描方向,0X00正常扫描,从上往下,从左往右,RGB方式
- if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
- else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
- else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
- else LCD_WR_DATA8(0xA0);
- LCD_WR_CMD(0x3A); //数据格式,65K色,565
- LCD_WR_DATA8(0x05);
- LCD_WR_CMD(0xB2); //帧频设置
- LCD_WR_DATA8(0x0C);
- LCD_WR_DATA8(0x0C);
- LCD_WR_DATA8(0x00);
- LCD_WR_DATA8(0x33);
- LCD_WR_DATA8(0x33);
- LCD_WR_CMD(0xC6); //正常模式下的帧速率控制
- // LCD_WR_DATA8(0x01); //正常模式下:屏幕刷新率 111Hz
- LCD_WR_DATA8(0x1F); //正常模式下:屏幕刷新率 39Hz
-
- LCD_WR_CMD(0xB7); //GATE 设置
- LCD_WR_DATA8(0x35);
- LCD_WR_CMD(0xBB); //VCOM设置
- LCD_WR_DATA8(0x19);
- LCD_WR_CMD(0xC0); //LCM设置,默认0x2c
- LCD_WR_DATA8(0x2C);
- LCD_WR_CMD(0xC2); //VDV&VRH SET ,默认0x01
- LCD_WR_DATA8(0x01);
- LCD_WR_CMD(0xC3); //VRHS SET,默认0x0b
- LCD_WR_DATA8(0x12); //此处根据实际情况修正
- LCD_WR_CMD(0xC4); //VDV SET,默认0x20
- LCD_WR_DATA8(0x20);
- LCD_WR_CMD(0xC6); // FR SET, 默认0x0F
- LCD_WR_DATA8(0x0F);
- LCD_WR_CMD(0xD0); //电源控制1
- LCD_WR_DATA8(0xA4); //该参数不变
- LCD_WR_DATA8(0xA1); //此处根据实际情况修改
- LCD_WR_CMD(0xE0); //正极性GAMMA调整
- LCD_WR_DATA8(0xD0);
- LCD_WR_DATA8(0x04);
- LCD_WR_DATA8(0x0D);
- LCD_WR_DATA8(0x11);
- LCD_WR_DATA8(0x13);
- LCD_WR_DATA8(0x2B);
- LCD_WR_DATA8(0x3F);
- LCD_WR_DATA8(0x54);
- LCD_WR_DATA8(0x4C);
- LCD_WR_DATA8(0x18);
- LCD_WR_DATA8(0x0D);
- LCD_WR_DATA8(0x0B);
- LCD_WR_DATA8(0x1F);
- LCD_WR_DATA8(0x23);
- LCD_WR_CMD(0xE1); //负极性GAMMA调整
- LCD_WR_DATA8(0xD0);
- LCD_WR_DATA8(0x04);
- LCD_WR_DATA8(0x0C);
- LCD_WR_DATA8(0x11);
- LCD_WR_DATA8(0x13);
- LCD_WR_DATA8(0x2C);
- LCD_WR_DATA8(0x3F);
- LCD_WR_DATA8(0x44);
- LCD_WR_DATA8(0x51);
- LCD_WR_DATA8(0x2F);
- LCD_WR_DATA8(0x1F);
- LCD_WR_DATA8(0x1F);
- LCD_WR_DATA8(0x20);
- LCD_WR_DATA8(0x23);
- LCD_WR_CMD(0x21); //反显开,默认是0X20,正常模式
-
- LCD_WR_CMD(0x29); //显示开,等待MCU数传送
- }
- /******************************************************************************
- 函数说明:LCD清屏函数
- 入口数据:无
- 返回值: 无
- ******************************************************************************/
- void LCD_Clear(uint16_t Color)
- {
- uint16_t i,j;
- LCD_Address_Set(0,0,LCD_WIDTH-1,LCD_HEIGHT-1);
- for(i=0;i<LCD_WIDTH;i++)
- {
- for (j=0;j<LCD_HEIGHT;j++)
- {
- LCD_WR_DATA16(Color);
- }
- }
- }
- /******************************************************************************
- 函数说明:在指定区域填充颜色
- 入口数据:xsta,ysta 起始坐标
- xend,yend 终止坐标
- color 要填充的颜色
- 返回值: 无
- ******************************************************************************/
- void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color)
- {
- uint16_t i,j;
- LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
- for(i=ysta;i<yend;i++)
- {
- for(j=xsta;j<xend;j++)
- {
- LCD_WR_DATA16(color);
- }
- }
- }
- /******************************************************************************
- 函数说明:在指定位置画点
- 入口数据:x,y 画点坐标
- color 点的颜色
- 返回值: 无
- ******************************************************************************/
- void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color)
- {
- LCD_Address_Set(x,y,x,y);//设置光标位置
- LCD_WR_DATA16(color);
- }
- /******************************************************************************
- 函数说明:画线
- 入口数据:x1,y1 起始坐标
- x2,y2 终止坐标
- color 线的颜色
- 返回值: 无
- ******************************************************************************/
- void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
- {
- uint16_t t;
- int xerr=0,yerr=0,delta_x,delta_y,distance;
- int incx,incy,uRow,uCol;
- delta_x=x2-x1; //计算坐标增量
- delta_y=y2-y1;
- uRow=x1;//画线起点坐标
- uCol=y1;
- if(delta_x>0)incx=1; //设置单步方向
- else if (delta_x==0)incx=0;//垂直线
- else {incx=-1;delta_x=-delta_x;}
- if(delta_y>0)incy=1;
- else if (delta_y==0)incy=0;//水平线
- else {incy=-1;delta_y=-delta_y;}
- if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
- else distance=delta_y;
- for(t=0;t<distance+1;t++)
- {
- LCD_DrawPoint(uRow,uCol,color);//画点
- xerr+=delta_x;
- yerr+=delta_y;
- if(xerr>distance)
- {
- xerr-=distance;
- uRow+=incx;
- }
- if(yerr>distance)
- {
- yerr-=distance;
- uCol+=incy;
- }
- }
- }
- /******************************************************************************
- 函数说明:画矩形
- 入口数据:x1,y1 起始坐标
- x2,y2 终止坐标
- color 矩形的颜色
- 返回值: 无
- ******************************************************************************/
- void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color)
- {
- LCD_DrawLine(x1,y1,x2,y1,color);
- LCD_DrawLine(x1,y1,x1,y2,color);
- LCD_DrawLine(x1,y2,x2,y2,color);
- LCD_DrawLine(x2,y1,x2,y2,color);
- }
- /******************************************************************************
- 函数说明:画圆
- 入口数据:x0,y0 圆心坐标
- r 半径
- color 圆的颜色
- 返回值: 无
- ******************************************************************************/
- void Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t color)
- {
- int a,b;
- a=0;b=r;
- while(a<=b)
- {
- LCD_DrawPoint(x0-b,y0-a,color); //3
- LCD_DrawPoint(x0+b,y0-a,color); //0
- LCD_DrawPoint(x0-a,y0+b,color); //1
- LCD_DrawPoint(x0-a,y0-b,color); //2
- LCD_DrawPoint(x0+b,y0+a,color); //4
- LCD_DrawPoint(x0+a,y0-b,color); //5
- LCD_DrawPoint(x0+a,y0+b,color); //6
- LCD_DrawPoint(x0-b,y0+a,color); //7
- a++;
- if((a*a+b*b)>(r*r))//判断要画的点是否过远
- {
- b--;
- }
- }
- }
- /******************************************************************************
- 函数说明:显示单个字符
- 入口数据:x,y显示坐标
- num 要显示的字符
- fc 字的颜色
- bc 字的背景色
- sizey 字号
- mode: 0非叠加模式 1叠加模式
- 返回值: 无
- ******************************************************************************/
- void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
- {
- uint8_t temp,sizex,t,m=0;
- uint16_t i,TypefaceNum;//一个字符所占字节大小
- uint16_t x0=x;
- sizex=sizey/2;
- TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
- num=num-' '; //得到偏移后的值
- LCD_Address_Set(x,y,x+sizex-1,y+sizey-1); //设置光标位置
- for(i=0;i<TypefaceNum;i++)
- {
- if(sizey==12)temp=asc2_1206[num][i]; //调用6x12字体
- else if(sizey==16)temp=asc2_1608[num][i]; //调用8x16字体
- // else if(sizey==24)temp=asc2_2412[num][i]; //调用12x24字体
- // else if(sizey==32)temp=asc2_1206[num][i]; //调用16x32字体
- else return;
- for(t=0;t<8;t++)
- {
- if(!mode)//非叠加模式
- {
- if(temp&(0x01<<t))LCD_WR_DATA16(fc);
- else LCD_WR_DATA16(bc);
- m++;
- if(m%sizex==0)
- {
- m=0;
- break;
- }
- }
- else//叠加模式
- {
- if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
- x++;
- if((x-x0)==sizex)
- {
- x=x0;
- y++;
- break;
- }
- }
- }
- }
- }
- /******************************************************************************
- 函数说明:显示字符串
- 入口数据:x,y显示坐标
- *p 要显示的字符串
- fc 字的颜色
- bc 字的背景色
- sizey 字号
- mode: 0非叠加模式 1叠加模式
- 返回值: 无
- ******************************************************************************/
- void LCD_ShowString(uint16_t x,uint16_t y,const char *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
- {
- while(*p!='\0')
- {
- LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
- x+=sizey/2;
- p++;
- }
- }
然后在主函数中调用显示函数去更新屏幕显示:
- #include "lcd.h"
- #include "stts751.h"
- #include "lps22hh.h"
- #include "hts221.h"
- #include <stdio.h>
- #define DISPLAY_X_POS (0U)
- #define DISPLAY_Y_POS (80U)
- #define DISPLAY_X_STEP (0U)
- #define DISPLAY_Y_STEP (20U)
- #define DISPLAY_Y_BAIS (20U)
- void display_data( void )
- {
- uint8_t str_buffer[100];
- // 获取stts751的数据
- float temp = stts751_get_temperature();
- sprintf((char *)str_buffer, "STTS751 Temp:%3.2f C", temp);
- LCD_ShowString(DISPLAY_X_POS, DISPLAY_Y_POS, (char *)str_buffer, BLUE, YELLOW, 16, 0);
- // 获取lps22hh的数据
- temp = lps22hh_get_temperature();
- sprintf((char *)str_buffer, "LPS22HH Temp:%3.2f C", temp);
- LCD_ShowString(DISPLAY_X_POS + DISPLAY_X_STEP, DISPLAY_Y_POS + DISPLAY_Y_STEP + DISPLAY_Y_BAIS, (char *)str_buffer, BLUE, YELLOW, 16, 0);
- temp = lps22hh_get_pressure();
- sprintf((char *)str_buffer, "LPS22HH Press:%3.2f hPa", temp);
- LCD_ShowString(DISPLAY_X_POS + DISPLAY_X_STEP * 2 , DISPLAY_Y_POS + DISPLAY_Y_STEP * 2 + DISPLAY_Y_BAIS, (char *)str_buffer, BLUE, YELLOW, 16, 0);
- // 获取hts221的数据
- temp = hts221_get_humidity();
- sprintf((char *)str_buffer, "HTS221 Humi:%3.2f %%", temp);
- LCD_ShowString(DISPLAY_X_POS + DISPLAY_X_STEP *3 , DISPLAY_Y_POS + DISPLAY_Y_STEP * 3 + DISPLAY_Y_BAIS * 2, (char *)str_buffer, BLUE, YELLOW, 16, 0);
- temp = hts221_get_temperature();
- sprintf((char *)str_buffer, "HTS221 Temp:%3.2f C", temp);
- LCD_ShowString(DISPLAY_X_POS + DISPLAY_X_STEP * 4 , DISPLAY_Y_POS + DISPLAY_Y_STEP * 4 + DISPLAY_Y_BAIS * 2, (char *)str_buffer, BLUE, YELLOW, 16, 0);
- }
四、显示效果