该款触摸屏幕显示芯片为:ST7789。触摸芯片为:CST816
一、所需文件
源文件来自于炸鸡派下的BSP下的TOUCH、LCD、IIC文件夹下的所有文件和SYS下的所有文件:
各个修改后的源文件为:
1.显示部分:
得手动配置硬件spi
lcdinit.h
#ifndef __LCD_INIT_H
#define __LCD_INIT_H#include "sys.h"#define USE_HORIZONTAL 0 //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏#if USE_HORIZONTAL==0||USE_HORIZONTAL==1
#define LCD_W 240
#define LCD_H 280#else
#define LCD_W 280
#define LCD_H 240
#endif//-----------------LCD端口定义----------------
#define RES_PORT GPIOA
#define RES_PIN GPIO_PIN_2#define DC_PORT GPIOA
#define DC_PIN GPIO_PIN_1#define CS_PORT GPIOA
#define CS_PIN GPIO_PIN_3// #define BLK_PORT GPIOB
// #define BLK_PIN GPIO_PIN_0#define LCD_RES_Clr() HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_RESET)//RES
#define LCD_RES_Set() HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_SET)#define LCD_DC_Clr() HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_RESET)//DC
#define LCD_DC_Set() HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_SET)#define LCD_CS_Clr() HAL_GPIO_WritePin(CS_PORT,CS_PIN,GPIO_PIN_RESET)//CS
#define LCD_CS_Set() HAL_GPIO_WritePin(CS_PORT,CS_PIN,GPIO_PIN_SET)// #define LCD_BLK_Clr() HAL_GPIO_WritePin(BLK_PORT,BLK_PIN,GPIO_PIN_RESET)//BLK
// #define LCD_BLK_Set() HAL_GPIO_WritePin(BLK_PORT,BLK_PIN,GPIO_PIN_SET)void LCD_GPIO_Init(void);//初始化GPIO
void LCD_Writ_Bus(u8 dat);//模拟SPI时序
void LCD_WR_DATA8(u8 dat);//写入一个字节
void LCD_WR_DATA(u16 dat);//写入两个字节
void LCD_WR_REG(u8 dat);//写入一个指令
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2);//设置坐标函数
void LCD_Init(void);//LCD初始化
void LCD_ST7789_SleepIn(void);
void LCD_ST7789_SleepOut(void);#endif
lcdinit.c
#include "lcd_init.h"
#include "delay.h"
#include "spi.h"/******************************************************************************函数说明:LCD端口初始化入口数据:无返回值: 无
******************************************************************************/
void LCD_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure = {0};__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStructure.Pin = RES_PIN|CS_PIN|DC_PIN; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//速度50MHzHAL_GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOBHAL_GPIO_WritePin(GPIOB, RES_PIN|CS_PIN|DC_PIN, GPIO_PIN_SET);
}/******************************************************************************函数说明:LCD串行数据写入函数(software SPI)入口数据:dat 要写入的串行数据返回值: 无
******************************************************************************/
void LCD_Writ_Bus(u8 dat)
{ //hard SPIHAL_SPI_Transmit(&hspi1,&dat,1,1);//soft SPI/*u8 i;for(i=0;i<8;i++){ LCD_SCLK_Clr();if(dat&0x80){LCD_MOSI_Set();}else{LCD_MOSI_Clr();}LCD_SCLK_Set();dat<<=1;} */
}/******************************************************************************函数说明:LCD写入数据入口数据:dat 写入的数据返回值: 无
******************************************************************************/
void LCD_WR_DATA8(u8 dat)
{LCD_Writ_Bus(dat);
}/******************************************************************************函数说明:LCD写入数据入口数据:dat 写入的数据返回值: 无
******************************************************************************/
void LCD_WR_DATA(u16 dat)
{
// LCD_Writ_Bus(dat>>8);
// LCD_Writ_Bus(dat);uint8_t temp[2];temp[0]=(dat>>8)&0xff;temp[1]=dat&0xff;HAL_SPI_Transmit(&hspi1,temp,2,1);}/******************************************************************************函数说明:LCD写入命令入口数据:dat 写入的命令返回值: 无
******************************************************************************/
void LCD_WR_REG(u8 dat)
{LCD_DC_Clr();//写命令LCD_Writ_Bus(dat);LCD_DC_Set();//写数据
}/******************************************************************************函数说明:设置起始和结束地址入口数据:x1,x2 设置列的起始和结束地址y1,y2 设置行的起始和结束地址返回值: 无
******************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{LCD_WR_REG(0x2a);//列地址设置LCD_WR_DATA(x1);LCD_WR_DATA(x2);LCD_WR_REG(0x2b);//行地址设置LCD_WR_DATA(y1);LCD_WR_DATA(y2);LCD_WR_REG(0x2c);//储存器写
}/******************************************************************************函数说明:ST7789 SLEEP IN入口数据:无返回值: 无
******************************************************************************/
void LCD_ST7789_SleepIn(void)
{LCD_WR_REG(0x10);delay_ms(100);
}/******************************************************************************函数说明:ST7789 SLEEP OUT入口数据:无返回值: 无
******************************************************************************/
void LCD_ST7789_SleepOut(void)
{LCD_WR_REG(0x11);delay_ms(100);
}/******************************************************************************函数说明:LCD初始化入口数据:无返回值: 无
******************************************************************************/
void LCD_Init(void)
{//LCD_GPIO_Init();//初始化GPIOHAL_GPIO_WritePin(GPIOA, RES_PIN|CS_PIN|DC_PIN, GPIO_PIN_SET);LCD_CS_Clr(); //chip selectLCD_RES_Clr(); //复位delay_ms(100);LCD_RES_Set();delay_ms(100);LCD_WR_REG(0x11); delay_ms(120); LCD_WR_REG(0x36); 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_REG(0x3A);LCD_WR_DATA8(0x05);LCD_WR_REG(0xB2);LCD_WR_DATA8(0x0C);LCD_WR_DATA8(0x0C);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x33);LCD_WR_DATA8(0x33); LCD_WR_REG(0xB7); LCD_WR_DATA8(0x35); LCD_WR_REG(0xBB);LCD_WR_DATA8(0x19);LCD_WR_REG(0xC0);LCD_WR_DATA8(0x2C);LCD_WR_REG(0xC2);LCD_WR_DATA8(0x01);LCD_WR_REG(0xC3);LCD_WR_DATA8(0x12); LCD_WR_REG(0xC4);LCD_WR_DATA8(0x20); LCD_WR_REG(0xC6); LCD_WR_DATA8(0x0F); LCD_WR_REG(0xD0); LCD_WR_DATA8(0xA4);LCD_WR_DATA8(0xA1);LCD_WR_REG(0xE0);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_REG(0xE1);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_REG(0x21); LCD_WR_REG(0x29);
}
lcd.h
#ifndef __LCD_H
#define __LCD_H
#include "sys.h"void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);//指定区域填充颜色
void LCD_Color_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color);
void LCD_DrawPoint(u16 x,u16 y,u16 color);//在指定位置画一个点
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color);//在指定位置画一条线
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);//在指定位置画一个矩形
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color);//在指定位置画一个圆void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示汉字串
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个12x12汉字
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个16x16汉字
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个24x24汉字
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个32x32汉字void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode);//显示一个字符
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode);//显示字符串
u32 mypow(u8 m,u8 n);//求幂
void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey);//显示整数变量
void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey);//显示两位小数变量void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[]);//显示图片//画笔颜色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40 //棕色
#define BRRED 0XFC07 //棕红色
#define GRAY 0X8430 //灰色
#define DARKBLUE 0X01CF //深蓝色
#define LIGHTBLUE 0X7D7C //浅蓝色
#define GRAYBLUE 0X5458 //灰蓝色
#define LIGHTGREEN 0X841F //浅绿色
#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)#endif
lcd.c
#include "lcd.h"
#include "lcd_init.h"
#include "lcdfont.h"
#include "delay.h"
#include "spi.h"#define OFFSET_Y 20/******************************************************************************函数说明:在指定区域填充颜色入口数据:xsta,ysta 起始坐标xend,yend 终止坐标color 要填充的颜色返回值: 无
******************************************************************************/
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{ u16 i,j; LCD_Address_Set(xsta,ysta+OFFSET_Y,xend-1,yend-1+OFFSET_Y);//设置显示范围for(i=ysta;i<yend;i++){ for(j=xsta;j<xend;j++){LCD_WR_DATA(color);}}
}/******************************************************************************函数说明:在指定区域填充颜色入口数据:xsta,ysta 起始坐标xend,yend 终止坐标color 要填充的颜色返回值: 无
******************************************************************************/
void LCD_Color_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color_p)
{u16 i,j,width,height; width = xend-xsta+1;height = yend-ysta+1;uint32_t size = width * height;LCD_Address_Set(xsta,ysta+OFFSET_Y,xend,yend+OFFSET_Y);hspi1.Init.DataSize = SPI_DATASIZE_16BIT;hspi1.Instance->CR1|=SPI_CR1_DFF;//HAL_SPI_Transmit_DMA(&hspi1,(uint8_t*)color_p,size);//while(__HAL_DMA_GET_COUNTER(&hdma_spi1_tx)!=0);hspi1.Init.DataSize = SPI_DATASIZE_8BIT;hspi1.Instance->CR1&=~SPI_CR1_DFF;}/******************************************************************************函数说明:在指定位置画点入口数据:x,y 画点坐标color 点的颜色返回值: 无
******************************************************************************/
void LCD_DrawPoint(u16 x,u16 y,u16 color)
{LCD_Address_Set(x,y,x,y);//设置光标位置 LCD_WR_DATA(color);
} /******************************************************************************函数说明:画线入口数据:x1,y1 起始坐标x2,y2 终止坐标color 线的颜色返回值: 无
******************************************************************************/
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
{u16 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(u16 x1, u16 y1, u16 x2, u16 y2,u16 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(u16 x0,u16 y0,u8 r,u16 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); //5LCD_DrawPoint(x0+a,y0+b,color); //6 LCD_DrawPoint(x0-b,y0+a,color); //7a++;if((a*a+b*b)>(r*r))//判断要画的点是否过远{b--;}}
}/******************************************************************************函数说明:显示汉字串入口数据:x,y显示坐标*s 要显示的汉字串fc 字的颜色bc 字的背景色sizey 字号 可选 16 24 32mode: 0非叠加模式 1叠加模式返回值: 无
******************************************************************************/
void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{while(*s!=0){if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);else return;s+=2;x+=sizey;}
}/******************************************************************************函数说明:显示单个12x12汉字入口数据:x,y显示坐标*s 要显示的汉字fc 字的颜色bc 字的背景色sizey 字号mode: 0非叠加模式 1叠加模式返回值: 无
******************************************************************************/
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{u8 i,j,m=0;u16 k;u16 HZnum;//汉字数目u16 TypefaceNum;//一个字符所占字节大小u16 x0=x;TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;HZnum=sizeof(tfont12)/sizeof(typFNT_GB12); //统计汉字数目for(k=0;k<HZnum;k++) {if((tfont12[k].Index[0]==*(s))&&(tfont12[k].Index[1]==*(s+1))){ LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);for(i=0;i<TypefaceNum;i++){for(j=0;j<8;j++){ if(!mode)//非叠加方式{if(tfont12[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);else LCD_WR_DATA(bc);m++;if(m%sizey==0){m=0;break;}}else//叠加方式{if(tfont12[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点x++;if((x-x0)==sizey){x=x0;y++;break;}}}}} continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响}
} /******************************************************************************函数说明:显示单个16x16汉字入口数据:x,y显示坐标*s 要显示的汉字fc 字的颜色bc 字的背景色sizey 字号mode: 0非叠加模式 1叠加模式返回值: 无
******************************************************************************/
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{u8 i,j,m=0;u16 k;u16 HZnum;//汉字数目u16 TypefaceNum;//一个字符所占字节大小u16 x0=x;TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;HZnum=sizeof(tfont16)/sizeof(typFNT_GB16); //统计汉字数目for(k=0;k<HZnum;k++) {if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1))){ LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);for(i=0;i<TypefaceNum;i++){for(j=0;j<8;j++){ if(!mode)//非叠加方式{if(tfont16[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);else LCD_WR_DATA(bc);m++;if(m%sizey==0){m=0;break;}}else//叠加方式{if(tfont16[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点x++;if((x-x0)==sizey){x=x0;y++;break;}}}}} continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响}
} /******************************************************************************函数说明:显示单个24x24汉字入口数据:x,y显示坐标*s 要显示的汉字fc 字的颜色bc 字的背景色sizey 字号mode: 0非叠加模式 1叠加模式返回值: 无
******************************************************************************/
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{u8 i,j,m=0;u16 k;u16 HZnum;//汉字数目u16 TypefaceNum;//一个字符所占字节大小u16 x0=x;TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;HZnum=sizeof(tfont24)/sizeof(typFNT_GB24); //统计汉字数目for(k=0;k<HZnum;k++) {if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1))){ LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);for(i=0;i<TypefaceNum;i++){for(j=0;j<8;j++){ if(!mode)//非叠加方式{if(tfont24[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);else LCD_WR_DATA(bc);m++;if(m%sizey==0){m=0;break;}}else//叠加方式{if(tfont24[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点x++;if((x-x0)==sizey){x=x0;y++;break;}}}}} continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响}
} /******************************************************************************函数说明:显示单个32x32汉字入口数据:x,y显示坐标*s 要显示的汉字fc 字的颜色bc 字的背景色sizey 字号mode: 0非叠加模式 1叠加模式返回值: 无
******************************************************************************/
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{u8 i,j,m=0;u16 k;u16 HZnum;//汉字数目u16 TypefaceNum;//一个字符所占字节大小u16 x0=x;TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;HZnum=sizeof(tfont32)/sizeof(typFNT_GB32); //统计汉字数目for(k=0;k<HZnum;k++) {if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1))){ LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);for(i=0;i<TypefaceNum;i++){for(j=0;j<8;j++){ if(!mode)//非叠加方式{if(tfont32[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);else LCD_WR_DATA(bc);m++;if(m%sizey==0){m=0;break;}}else//叠加方式{if(tfont32[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点x++;if((x-x0)==sizey){x=x0;y++;break;}}}}} continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响}
}/******************************************************************************函数说明:显示单个字符入口数据:x,y显示坐标num 要显示的字符fc 字的颜色bc 字的背景色sizey 字号mode: 0非叠加模式 1叠加模式返回值: 无
******************************************************************************/
void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
{u8 temp,sizex,t,m=0;u16 i,TypefaceNum;//一个字符所占字节大小u16 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=ascii_1206[num][i]; //调用6x12字体else if(sizey==16)temp=ascii_1608[num][i]; //调用8x16字体else if(sizey==24)temp=ascii_2412[num][i]; //调用12x24字体else if(sizey==32)temp=ascii_3216[num][i]; //调用16x32字体else return;for(t=0;t<8;t++){if(!mode)//非叠加模式{if(temp&(0x01<<t))LCD_WR_DATA(fc);else LCD_WR_DATA(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(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
{ while(*p!='\0'){ LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);x+=sizey/2;p++;}
}/******************************************************************************函数说明:显示数字入口数据:m底数,n指数返回值: 无
******************************************************************************/
u32 mypow(u8 m,u8 n)
{u32 result=1; while(n--)result*=m;return result;
}/******************************************************************************函数说明:显示整数变量入口数据:x,y显示坐标num 要显示整数变量len 要显示的位数fc 字的颜色bc 字的背景色sizey 字号返回值: 无
******************************************************************************/
void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey)
{ u8 t,temp;u8 enshow=0;u8 sizex=sizey/2;for(t=0;t<len;t++){temp=(num/mypow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);continue;}else enshow=1; }LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);}
} /******************************************************************************函数说明:显示两位小数变量入口数据:x,y显示坐标num 要显示小数变量len 要显示的位数fc 字的颜色bc 字的背景色sizey 字号返回值: 无
******************************************************************************/
void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey)
{ u8 t,temp,sizex;u16 num1;sizex=sizey/2;num1=num*100;for(t=0;t<len;t++){temp=(num1/mypow(10,len-t-1))%10;if(t==(len-2)){LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0);t++;len+=1;}LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);}
}/******************************************************************************函数说明:显示图片入口数据:x,y起点坐标length 图片长度width 图片宽度pic[] 图片数组 返回值: 无
******************************************************************************/
void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
{u16 i,j;u32 k=0;LCD_Address_Set(x,y,x+length-1,y+width-1);for(i=0;i<length;i++){for(j=0;j<width;j++){LCD_WR_DATA8(pic[k*2]);LCD_WR_DATA8(pic[k*2+1]);k++;}}
}
2.触摸部分
配置软件IIC
iic_hal.h
#ifndef __IIC_HAL_H
#define __IIC_HAL_H#include "stm32f4xx_hal.h"typedef struct
{GPIO_TypeDef * IIC_SDA_PORT;GPIO_TypeDef * IIC_SCL_PORT;uint16_t IIC_SDA_PIN;uint16_t IIC_SCL_PIN;//void (*CLK_ENABLE)(void);
}iic_bus_t;void IICStart(iic_bus_t *bus);
void IICStop(iic_bus_t *bus);
unsigned char IICWaitAck(iic_bus_t *bus);
void IICSendAck(iic_bus_t *bus);
void IICSendNotAck(iic_bus_t *bus);
void IICSendByte(iic_bus_t *bus, unsigned char cSendByte);
unsigned char IICReceiveByte(iic_bus_t *bus);
void IICInit(iic_bus_t *bus);uint8_t IIC_Write_One_Byte(iic_bus_t *bus, uint8_t daddr,uint8_t reg,uint8_t data);
uint8_t IIC_Write_Multi_Byte(iic_bus_t *bus, uint8_t daddr,uint8_t reg,uint8_t length,uint8_t buff[]);
unsigned char IIC_Read_One_Byte(iic_bus_t *bus, uint8_t daddr,uint8_t reg);
uint8_t IIC_Read_Multi_Byte(iic_bus_t *bus, uint8_t daddr, uint8_t reg, uint8_t length, uint8_t buff[]);
#endif
iic_hal.c
#include "iic_hal.h"
#include "delay.h"/*** @brief SDA线输入模式配置* @param None* @retval None*/
void SDA_Input_Mode(iic_bus_t *bus)
{GPIO_InitTypeDef GPIO_InitStructure = {0};GPIO_InitStructure.Pin = bus->IIC_SDA_PIN;GPIO_InitStructure.Mode = GPIO_MODE_INPUT;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(bus->IIC_SDA_PORT, &GPIO_InitStructure);
}/*** @brief SDA线输出模式配置* @param None* @retval None*/
void SDA_Output_Mode(iic_bus_t *bus)
{GPIO_InitTypeDef GPIO_InitStructure = {0};GPIO_InitStructure.Pin = bus->IIC_SDA_PIN;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStructure.Pull = GPIO_NOPULL;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(bus->IIC_SDA_PORT, &GPIO_InitStructure);
}/*** @brief SDA线输出一个位* @param val 输出的数据* @retval None*/
void SDA_Output(iic_bus_t *bus, uint16_t val)
{if ( val ){bus->IIC_SDA_PORT->BSRR |= bus->IIC_SDA_PIN;}else{bus->IIC_SDA_PORT->BSRR = (uint32_t)bus->IIC_SDA_PIN << 16U;}
}/*** @brief SCL线输出一个位* @param val 输出的数据* @retval None*/
void SCL_Output(iic_bus_t *bus, uint16_t val)
{if ( val ){bus->IIC_SCL_PORT->BSRR |= bus->IIC_SCL_PIN;}else{bus->IIC_SCL_PORT->BSRR = (uint32_t)bus->IIC_SCL_PIN << 16U;}
}/*** @brief SDA输入一位* @param None* @retval GPIO读入一位*/
uint8_t SDA_Input(iic_bus_t *bus)
{if(HAL_GPIO_ReadPin(bus->IIC_SDA_PORT, bus->IIC_SDA_PIN) == GPIO_PIN_SET){return 1;}else{return 0;}
}/*** @brief IIC起始信号* @param None* @retval None*/
void IICStart(iic_bus_t *bus)
{SDA_Output(bus,1);//delay1(DELAY_TIME);delay_us(2);SCL_Output(bus,1);delay_us(1);SDA_Output(bus,0);delay_us(1);SCL_Output(bus,0);delay_us(1);
}/*** @brief IIC结束信号* @param None* @retval None*/
void IICStop(iic_bus_t *bus)
{SCL_Output(bus,0);delay_us(2);SDA_Output(bus,0);delay_us(1);SCL_Output(bus,1);delay_us(1);SDA_Output(bus,1);delay_us(1);}/*** @brief IIC等待确认信号* @param None* @retval None*/
unsigned char IICWaitAck(iic_bus_t *bus)
{unsigned short cErrTime = 5;SDA_Input_Mode(bus);SCL_Output(bus,1);while(SDA_Input(bus)){cErrTime--;delay_us(1);if (0 == cErrTime){SDA_Output_Mode(bus);IICStop(bus);return ERROR;}}SDA_Output_Mode(bus);SCL_Output(bus,0);delay_us(2);return SUCCESS;
}/*** @brief IIC发送确认信号* @param None* @retval None*/
void IICSendAck(iic_bus_t *bus)
{SDA_Output(bus,0);delay_us(1);SCL_Output(bus,1);delay_us(1);SCL_Output(bus,0);delay_us(1);}/*** @brief IIC发送非确认信号* @param None* @retval None*/
void IICSendNotAck(iic_bus_t *bus)
{SDA_Output(bus,1);delay_us(1);SCL_Output(bus,1);delay_us(1);SCL_Output(bus,0);delay_us(2);}/*** @brief IIC发送一个字节* @param cSendByte 需要发送的字节* @retval None*/
void IICSendByte(iic_bus_t *bus,unsigned char cSendByte)
{unsigned char i = 8;while (i--){SCL_Output(bus,0);delay_us(2);SDA_Output(bus, cSendByte & 0x80);delay_us(1);cSendByte += cSendByte;delay_us(1);SCL_Output(bus,1);delay_us(1);}SCL_Output(bus,0);delay_us(2);
}/*** @brief IIC接收一个字节* @param None* @retval 接收到的字节*/
unsigned char IICReceiveByte(iic_bus_t *bus)
{unsigned char i = 8;unsigned char cR_Byte = 0;SDA_Input_Mode(bus);while (i--){cR_Byte += cR_Byte;SCL_Output(bus,0);delay_us(2);SCL_Output(bus,1);delay_us(1);cR_Byte |= SDA_Input(bus);}SCL_Output(bus,0);SDA_Output_Mode(bus);return cR_Byte;
}uint8_t IIC_Write_One_Byte(iic_bus_t *bus, uint8_t daddr,uint8_t reg,uint8_t data)
{ IICStart(bus); IICSendByte(bus,daddr<<1); if(IICWaitAck(bus)) //等待应答{IICStop(bus); return 1; }IICSendByte(bus,reg);IICWaitAck(bus); IICSendByte(bus,data); IICWaitAck(bus); IICStop(bus);delay_us(1);return 0;
}uint8_t IIC_Write_Multi_Byte(iic_bus_t *bus, uint8_t daddr,uint8_t reg,uint8_t length,uint8_t buff[])
{ unsigned char i; IICStart(bus); IICSendByte(bus,daddr<<1); if(IICWaitAck(bus)){IICStop(bus);return 1;}IICSendByte(bus,reg);IICWaitAck(bus); for(i=0;i<length;i++){IICSendByte(bus,buff[i]); IICWaitAck(bus); } IICStop(bus);delay_us(1);return 0;
} unsigned char IIC_Read_One_Byte(iic_bus_t *bus, uint8_t daddr,uint8_t reg)
{unsigned char dat;IICStart(bus);IICSendByte(bus,daddr<<1);IICWaitAck(bus);IICSendByte(bus,reg);IICWaitAck(bus);IICStart(bus);IICSendByte(bus,(daddr<<1)+1);IICWaitAck(bus);dat = IICReceiveByte(bus);IICSendNotAck(bus);IICStop(bus);return dat;
}uint8_t IIC_Read_Multi_Byte(iic_bus_t *bus, uint8_t daddr, uint8_t reg, uint8_t length, uint8_t buff[])
{unsigned char i;IICStart(bus);IICSendByte(bus,daddr<<1);if(IICWaitAck(bus)){IICStop(bus); return 1; }IICSendByte(bus,reg);IICWaitAck(bus);IICStart(bus);IICSendByte(bus,(daddr<<1)+1);IICWaitAck(bus);for(i=0;i<length;i++){buff[i] = IICReceiveByte(bus);if(i<length-1){IICSendAck(bus);}}IICSendNotAck(bus);IICStop(bus);return 0;
}//
void IICInit(iic_bus_t *bus)
{GPIO_InitTypeDef GPIO_InitStructure = {0};//bus->CLK_ENABLE();GPIO_InitStructure.Pin = bus->IIC_SDA_PIN ;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(bus->IIC_SDA_PORT, &GPIO_InitStructure);GPIO_InitStructure.Pin = bus->IIC_SCL_PIN ;HAL_GPIO_Init(bus->IIC_SCL_PORT, &GPIO_InitStructure);
}
屏幕驱动部分
CST816.h
#ifndef __CST816_H
#define __CST816_H#include "stdint.h"
#include "iic_hal.h"
#include "delay.h"/* CST816 dev pin defination */#define TOUCH_RST_PIN GPIO_PIN_11
#define TOUCH_INT_PIN GPIO_PIN_12
#define TOUCH_RST_PORT GPIOB
#define TOUCH_INT_PORT GPIOB/* functions define */
#define TOUCH_RST_0 HAL_GPIO_WritePin(TOUCH_RST_PORT, TOUCH_RST_PIN, GPIO_PIN_RESET)
#define TOUCH_RST_1 HAL_GPIO_WritePin(TOUCH_RST_PORT, TOUCH_RST_PIN, GPIO_PIN_SET)/* 设备地址 */
#define Device_Addr 0x15/* 触摸屏寄存器 */
#define GestureID 0x01
#define FingerNum 0x02
#define XposH 0x03
#define XposL 0x04
#define YposH 0x05
#define YposL 0x06
#define ChipID 0xA7
#define SleepMode 0xE5
#define MotionMask 0xEC
#define IrqPluseWidth 0xED
#define NorScanPer 0xEE
#define MotionSlAngle 0xEF
#define LpAutoWakeTime 0xF4
#define LpScanTH 0xF5
#define LpScanWin 0xF6
#define LpScanFreq 0xF7
#define LpScanIdac 0xF8
#define AutoSleepTime 0xF9
#define IrqCtl 0xFA
#define AutoReset 0xFB
#define LongPressTime 0xFC
#define IOCtl 0xFD
#define DisAutoSleep 0xFE/* 触摸屏坐标结构体 */
typedef struct
{unsigned int X_Pos;unsigned int Y_Pos;
} CST816_Info;extern CST816_Info CST816_Instance;
/* 手势ID识别选项 */
typedef enum
{NOGESTURE = 0x00,DOWNGLIDE = 0x01,UPGLIDE = 0x02,LEFTGLIDE = 0x03,RIGHTGLIDE = 0x04,CLICK = 0x05,DOUBLECLICK = 0x0B,LONGPRESS = 0x0C,
} GestureID_TypeDef;/* 连续动作配置选项 */
typedef enum
{M_DISABLE = 0x00,EnConLR = 0x01,EnConUD = 0x02,EnDClick = 0x03,M_ALLENABLE = 0x07,
} MotionMask_TypeDef;/* 中断低脉冲发射方式选项 */
typedef enum
{OnceWLP = 0x00,EnMotion = 0x10,EnChange = 0x20,EnTouch = 0x40,EnTest = 0x80,
} IrqCtl_TypeDef;/* 触摸屏初始化相关函数 */
void CST816_GPIO_Init(void);
void CST816_RESET(void);
void CST816_Init(void);/* 触摸屏操作函数 */
void CST816_Get_XY_AXIS(void);
uint8_t CST816_Get_ChipID(void);
uint8_t CST816_Get_FingerNum(void);
/* 触摸屏读写函数 */
void CST816_IIC_WriteREG(uint8_t addr, uint8_t dat);
uint8_t CST816_IIC_ReadREG(unsigned char addr);/* 触摸屏有关参数配置函数 */
void CST816_Config_MotionMask(uint8_t mode);
void CST816_Config_AutoSleepTime(uint8_t time);
void CST816_Config_MotionSlAngle(uint8_t x_right_y_up_angle);
void CST816_Config_NorScanPer(uint8_t Period);
void CST816_Config_IrqPluseWidth(uint8_t Width);
void CST816_Config_LpScanTH(uint8_t TH);
void CST816_Wakeup(void);
void CST816_Sleep(void);#endif
CST816.c
#include "CST816.h" #define TOUCH_OFFSET_Y 15CST816_Info CST816_Instance;iic_bus_t CST816_dev =
{.IIC_SDA_PORT = GPIOB,.IIC_SCL_PORT = GPIOB,.IIC_SDA_PIN = GPIO_PIN_9,.IIC_SCL_PIN = GPIO_PIN_8,
};/*
*********************************************************************************************************
* 函 数 名: CST816_GPIO_Init
* 功能说明: CST816 GPIO口初始化
* 形 参:none
* 返 回 值: none
*********************************************************************************************************
*/
void CST816_GPIO_Init(void)
{ GPIO_InitTypeDef GPIO_InitStructure = {0};__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/* 初始化复位引脚 */GPIO_InitStructure.Pin = TOUCH_RST_PIN;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(TOUCH_RST_PORT, &GPIO_InitStructure);HAL_GPIO_WritePin(TOUCH_RST_PORT,TOUCH_RST_PIN,GPIO_PIN_SET);/* 初始化中断引脚,不用中断的话屏蔽掉 *//* 初始化I2C引脚 */IICInit(&CST816_dev);/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 *///IICStop(&CST816_dev);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Init
* 功能说明: CST816初始化
* 形 参:none
* 返 回 值: none
*********************************************************************************************************
*/
void CST816_Init(void)
{CST816_GPIO_Init();CST816_Config_AutoSleepTime(5);
}/*
*********************************************************************************************************
* 函 数 名: CST816_IIC_ReadREG
* 功能说明: 读取触摸屏单个寄存器的数据
* 形 参:reg:寄存器地址
* 返 回 值: 返回寄存器存储的数据
*********************************************************************************************************
*/
uint8_t CST816_IIC_ReadREG(uint8_t addr)
{return IIC_Read_One_Byte(&CST816_dev,Device_Addr,addr);
}/*
*********************************************************************************************************
* 函 数 名: CST816_IIC_WriteREG
* 功能说明: 向触摸屏的寄存器写入数据
* 形 参:addr:寄存器地址
* dat: 写入的数据
* 返 回 值: 返回寄存器存储的数据
*********************************************************************************************************
*/
void CST816_IIC_WriteREG(uint8_t addr, uint8_t dat)
{IIC_Write_One_Byte(&CST816_dev,Device_Addr,addr,dat);
}/*
*********************************************************************************************************
* 函 数 名: TOUCH_RESET
* 功能说明: 触摸屏复位
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_RESET(void)
{TOUCH_RST_0;HAL_Delay(10);TOUCH_RST_1;HAL_Delay(100);
}/*
*********************************************************************************************************
* 函 数 名: TOUCH_READ_X
* 功能说明: 读取触摸屏在触摸时的坐标值
* 形 参:无
* 返 回 值: 无 (数据存储在CST816_Instance结构体中)
*********************************************************************************************************
*/
void CST816_Get_XY_AXIS(void)
{uint8_t DAT[4];IIC_Read_Multi_Byte(&CST816_dev,Device_Addr,XposH,4,DAT);CST816_Instance.X_Pos=((DAT[0]&0x0F)<<8)|DAT[1];//(temp[0]&0X0F)<<4|CST816_Instance.Y_Pos=((DAT[2]&0x0F)<<8)|DAT[3] + TOUCH_OFFSET_Y;//(temp[2]&0X0F)<<4|
}/*
*********************************************************************************************************
* 函 数 名: CST816_Get_FingerNum
* 功能说明: 读取触摸屏的手指触摸个数,0xFF为睡眠
* 形 参:无
* 返 回 值: 返回芯片ID
*********************************************************************************************************
*/
uint8_t CST816_Get_FingerNum(void)
{return CST816_IIC_ReadREG(FingerNum);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Get_ChipID
* 功能说明: 读取触摸屏的芯片ID
* 形 参:无
* 返 回 值: 返回芯片ID
*********************************************************************************************************
*/
uint8_t CST816_Get_ChipID(void)
{return CST816_IIC_ReadREG(ChipID);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Config_MotionMask
* 功能说明: 使能连续动作(连续左右滑动,连续上下滑动,双击)
* 形 参:mode:模式(5种)
* 返 回 值: 无
* 注 意:使能连续动作会增加响应时间
*********************************************************************************************************
*/
void CST816_Config_MotionMask(uint8_t mode)
{CST816_IIC_WriteREG(MotionMask,mode);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Config_AutoSleepTime
* 功能说明: 规定time内无触摸,自动进入低功耗模式
* 形 参:time:时间(s)
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_Config_AutoSleepTime(uint8_t time)
{CST816_IIC_WriteREG(AutoSleepTime,time);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Sleep
* 功能说明: 进入睡眠,无触摸唤醒功能
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_Sleep(void)
{CST816_IIC_WriteREG(SleepMode,0x03);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Wakeup
* 功能说明: 唤醒
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_Wakeup(void)
{CST816_RESET();
}/*
*********************************************************************************************************
* 函 数 名: CST816_Config_MotionSlAngle
* 功能说明: 手势检测滑动分区角度控制。Angle=tan(c)*10 c为以x轴正方向为基准的角度。
* 形 参:x_right_y_up_angle:角度值
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_Config_MotionSlAngle(uint8_t x_right_y_up_angle)
{CST816_IIC_WriteREG(MotionSlAngle,x_right_y_up_angle);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Config_NorScanPer
* 功能说明: 正常快速检测周期配置函数。
* 此值会影响到LpAutoWakeTime和AutoSleepTime。
* 单位10ms,可选值:1~30。默认值为1。
* 形 参:Period:周期值
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_Config_NorScanPer(uint8_t Period)
{if(Period >= 30)Period = 30;CST816_IIC_WriteREG(NorScanPer,Period);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Config_IrqPluseWidth
* 功能说明: 中断低脉冲输出宽度配置函数
* 形 参:Period:周期值
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_Config_IrqPluseWidth(uint8_t Width)
{if(Width >= 200)Width = 200;CST816_IIC_WriteREG(IrqPluseWidth,Width);
}/*
*********************************************************************************************************
* 函 数 名: CST816_Config_NorScanPer
* 功能说明: 低功耗扫描唤醒门限配置函数。越小越灵敏。默认值48
* 形 参:TH:门限值
* 返 回 值: 无
*********************************************************************************************************
*/
void CST816_Config_LpScanTH(uint8_t TH)
{CST816_IIC_WriteREG(LpScanTH,TH);
}
3.sys
delay.h
#ifndef _DELAY_H
#define _DELAY_H
#include "sys.h" void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
#endif
delay.c
#include "delay.h"
#include "sys.h"/*
//roughly delay
void delay_us(u32 nus)
{ u32 i;u16 temp;temp = nus*SYS_CLK/15;for(i=0;i<temp;i++);
}//延时nms
//nms:要延时的ms数
void delay_ms(u16 nms)
{u32 i;for(i=0;i<nms;i++) delay_us(1000);
}
*/void delay_init(void)
{HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);/* Configure the SysTick to have interrupt in 1ms time basis*/HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq));
}#if OS_SUPPORT
void delay_us(u32 nus)
{ u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD; ticks=nus*SYS_CLK; delay_osschedlock(); told=SysTick->VAL; while(1){tnow=SysTick->VAL; if(tnow!=told){ if(tnow<told)tcnt+=told-tnow;//这里注意一下SYSTICK是一个递减的计数器就可以了. else tcnt+=reload-tnow+told; told=tnow;if(tcnt>=ticks)break; } };delay_osschedunlock();
} void delay_ms(u16 nms)
{ if(delay_osrunning&&delay_osintnesting==0) { if(nms>=fac_ms) { delay_ostimedly(nms/fac_ms); }nms%=fac_ms; }delay_us((u32)(nms*1000));
}
#else void delay_us(u32 nus)
{ u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD; ticks=nus*SYS_CLK; told=SysTick->VAL; while(1){tnow=SysTick->VAL; if(tnow!=told){ if(tnow<told)tcnt+=told-tnow; else tcnt+=reload-tnow+told; told=tnow;if(tcnt>=ticks)break; } }
}void delay_ms(u16 nms)
{u32 i;for(i=0;i<nms;i++) delay_us(1000);
}
#endif
sys.h
#ifndef __SYS_H__
#define __SYS_H__#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"#define OS_SUPPORT 0
#define SYS_CLK 100typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;typedef const int32_t sc32;
typedef const int16_t sc16;
typedef const int8_t sc8; typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;typedef __I int32_t vsc32;
typedef __I int16_t vsc16;
typedef __I int8_t vsc8; typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;typedef const uint32_t uc32;
typedef const uint16_t uc16;
typedef const uint8_t uc8; typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;typedef __I uint32_t vuc32;
typedef __I uint16_t vuc16;
typedef __I uint8_t vuc8; #endif
4.字体、图片
图片pic.h
#ifndef _PIC_H
#define _PIC_H
//中间添加所用到的图片#endif
字体lcdfont.h