门锁系统——屏幕显示

接上篇1.门锁系统——项目简介_only_print的博客-CSDN博客

本节主要先简单实现屏幕的显示功能,以供后期的显示需要。

设想先实现上部为显示整个信息,下部显示密码的选项。

目录

显示部分

程序设计

触摸部分

CobeMX设置

程序设计


显示部分

本实验采用的是2.8寸TFTLCD,有关LCD的基本操作过程可以参考我之前的博客:使用FSMC连接TFT LCD_only_print的博客-CSDN博客

接下来我们就基于这个地方开始进行开发。

CobeMX中的设置已经完成,直接进入程序

程序设计

为了整个项目的整洁,我们将自己实现的LCD相关程序放在一个新的文件中,在文件目录下创建一个新的文件夹,在其中创建一个bsp_LCD.c和bsp_LCD.h文件,将其分别添加到文件目录中。

然后就可以初步实现显示功能了,先在下方显示LCD的数字显示功能,具体功能实现下:

// 画出下方的屏幕中按键

void LCD_Partition(void)

{

       uint16_t i,x= 0,y = 170;

       POINT_COLOR=RED;

       LCD_Fill(x,y,x+240,y+150,WHITE);

       /* 此处就是画一些条条框框来放置相应的UI值 */

       LCD_DrawRectangle(x,y,x+240,y+150); //画竖线                                    

       LCD_DrawRectangle(x+80,y,x+160,y+150); 

       LCD_DrawRectangle(x,y+30,x+240,y+60);

       LCD_DrawRectangle(x,y+90,x+240,y+120);

       POINT_COLOR=BLUE;

       LCD_ShowString(x+4,y+7,80,16,16,(uint8_t *)"Del FinPt");// 删除指纹按键  

       LCD_ShowString(x+4+80,y+7,80,16,16,(uint8_t *)"Cge PasWd");// 修改密码

       LCD_ShowString(x+4+80*2,y+7,80,16,16,(uint8_t *)"Cre FinPt");// 新建指纹按键  

       for(i=1;i<10;i++)//数字键盘

       {

              // 显示1至9

              LCD_ShowNum(x+36+((i-1)%3)*80,y+7+30*(((i-1)/3)+1),i,1,16);

       }

       // 显示剩下的# 0 *

       LCD_ShowString(36, y+7+30*4, 8,16,16, (uint8_t *)"*");  // 这个按键用来触摸时,删除错误的按键。

       LCD_ShowNum(80+36, y+7+30*4, 0, 1, 16);

       LCD_ShowString(160+36, y+7+30*4, 8,16,16,(uint8_t *)"#");  // 这个按键用来触摸时,提交密码。

}

再显示上方的按键功能信息,这部分留于以后模块实现时完成这部分二级菜单,具体实现如下:

// 绘制上方的部分,这部分用来展示按键的作用

/* 按键的作用

key1-密码设置

key2-指纹设置

key3-卡片设置

key4-忘记密码

*/

void Key_Press(void)

{

       LCD_ShowString(10,0, 240,16,16,(uint8_t*)"[1] Password settings");

       LCD_ShowString(10,20,240,16,16, (uint8_t*)"[2] Fingerprint settings");

       LCD_ShowString(10,40,240,16,16, (uint8_t*)"[3] IDCard settings");

       LCD_ShowString(10,60, 240,16,16,(uint8_t*)"[4] Forgot password");

}

最后为了方便将之前的两个初始化添加到一个初始化函数中:

// 屏幕显示初始化函数

void Bsp_Lcd_Init(void)

{

       LCD_Partition();

       Key_Press();

}

将函数在bsp_lcd.h中声明,在主函数中调用即可。

然后将各个按键的作用分别定义为函数:

// 触摸设置

void Touch_Set(void)

{

       // 清除y方向上从0到80的区域

       LCD_Fill(0, 0, 280, 80, WHITE);

       // 最上方显示选择的按键

       LCD_ShowString(10,0, 240,16,16,(uint8_t*)"[1] Touch settings");

       // 触摸校正函数,在touch.c中定义

       TouchCalibrate();

       // 显示完成后重新显示主界面

       HAL_Delay(2000);

       Bsp_Lcd_Init();

}



// 指纹设置

void Finger_Set(void)

{

       LCD_Fill(0, 0, 280, 80, WHITE);

       LCD_ShowString(10,0,240,16,16, (uint8_t*)"[2] Fingerprint settings");

       // 画出按键对应的选项

       uint16_t x= 0,y = 20;

       POINT_COLOR=RED;  // 将颜色设置为红色

       /* 此处就是画一些条条框框来放置相应的UI值 */

       LCD_DrawRectangle(x,y,x+120,y+60);   // 画矩形                                   

       LCD_DrawRectangle(x+120,y,x+240,y+60);

       POINT_COLOR=BLUE;  // 将颜色设置为蓝色

       // 设置方框内显示内容

       LCD_ShowString(x+20,y+10,80,16,16,(uint8_t *)"View the");

       LCD_ShowString(x+20,y+30,80,16,16,(uint8_t *)"password");  // 查看密码(将密码发送到手机上)

       LCD_ShowString(x+20+120,y+10,80,16,16,(uint8_t *)"Change the");

       LCD_ShowString(x+20+120,y+30,80,16,16,(uint8_t *)"password");  // 修改密码

}



// 卡片设置

void IDCard_Set(void)

{

       LCD_Fill(0, 0, 280, 80, WHITE);

       LCD_ShowString(10,0,240,16,16, (uint8_t*)"[3] IDCard settings");

       // 画出按键对应的选项

       uint16_t x= 0,y = 20;

       POINT_COLOR=RED;  // 将颜色设置为红色

       /* 此处就是画一些条条框框来放置相应的UI值 */

       LCD_DrawRectangle(x,y,x+120,y+60);   // 画矩形                                   

       LCD_DrawRectangle(x+120,y,x+240,y+60);

       POINT_COLOR=BLUE;  // 将颜色设置为蓝色

       // 设置方框内显示内容

       LCD_ShowString(x+20,y+10,80,16,16,(uint8_t *)"View the");

       LCD_ShowString(x+20,y+30,80,16,16,(uint8_t *)"password");  // 查看密码(将密码发送到手机上)

       LCD_ShowString(x+20+120,y+10,80,16,16,(uint8_t *)"Change the");

       LCD_ShowString(x+20+120,y+30,80,16,16,(uint8_t *)"password");  // 修改密码

}



// 密码设置

void Password_Set(void)

{

       LCD_Fill(0, 0, 280, 100, WHITE);

       LCD_ShowString(10,0, 240,16,16,(uint8_t*)"[4] Password settings");

       // 画出按键对应的选项

       uint16_t x= 0,y = 20;

       POINT_COLOR=RED;  // 将颜色设置为红色

       /* 此处就是画一些条条框框来放置相应的UI值 */

       LCD_DrawRectangle(x,y,x+239,y+60);   // 画矩形                                   

       POINT_COLOR=BLUE;  // 将颜色设置为蓝色

       // 设置方框内显示内容

       LCD_ShowString(x+20,y+10,240,16,16,(uint8_t *)"View the password");

       LCD_ShowString(x+20,y+30,240,16,16,(uint8_t *)"Please check your phone");  // 查看密码(将密码发送到手机上)

      

}

注意:这里的函数只是初步的设置,在之后需要为各个函数添加自己相应的函数操作.。

触摸部分

显示完成后,就需要可以触摸实现第一种解锁方式了

基本原理:

    电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层、它的内表面也涂有一层涂层、在他们之间有许多细小的(小于 1/1000 英寸)的透明隔离点把两层导电层隔开绝缘 当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在 X Y 两个方向上产生信号,然后送触摸屏控制器。控制器侦测到这一接触并计算出(XY)的位置,再根据获得的位置模拟鼠标的方式运作。这就是电阻技术触摸屏的最基本的原理,具体情况如下图所示:

 24CXX系列芯片属于EEPROM(Electrically Erasable Programmable read only memory)掉电可擦可编程只读存储器,是一种掉电后数据不丢失(不挥发)存储芯片。

该系列芯片由美国Mcrochip公司出品,1-512K位的支持I2C总线数据传送协议的串行CMOS E2PROM,可用电擦除,可编程自定时写周期(包括自动擦除时间不超过10ms,典型时间为5ms)的。串行E2PROM一般具有两种写入方式,一种是字节写入方式,还有另一种页写入方式。允许在一个写周期内同时对1个字节到一页的若干字节的编程写入,1页的大小取决于芯片内页寄存器的大小。其中,AT24C01具有8字节数据的页面写能力,AT24C02/04/08/16具有16字节数据的页面写能力,AT24C32/64具有32字节数据的页面写能力。

CobeMX设置

这一块需要用到之前的按键和24C02芯片(EEPROM),这个芯片的作用是用来储存屏幕的校准信息和密码的。这个芯片是我这块开发板自带的,这个每个开发板可能不太一样,需要根据自己的板子来使用,但是实现的功能都一样,是为了在掉电后还可以储存信息。

触摸是使用SPI方式进行通讯的,这里选择软件触发方式,同时提供4个按键的GPIO设置:

这里的KEY经过测试,只有这样才能正常使用。

在使用软件模拟SPI时需要使用到微秒级延时,这里需要打开TIM7,并设置为71分频,具体操作如图:

接下来配置EEPROM,这块需要选择I2C方式通信,这里因为我的开发板中设计的接口只能选择I2C2(如果发现自己的屏幕数据在复位后无法保存,大概率是I2C接口选择错误),选择模式为I2C模式。

这些配置完成后就可以生成代码了。

程序设计

这部分我们仍然需要创建文件夹来存放EEPROM,KEY和触摸的程序,分别创建24C02_EEPROM,KEY和touch文件,在其中创建相应的.c和.h文件,添加到主函数中。

在key.c中我们实现按键的识别功能:

// 轮询4个按键,返回按键值

KEYS ScanKeys(uint32_t timeout)

{

       KEYS key = KEY0;

       // 按下按键1

       if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET)

       {

              HAL_Delay(10);

              if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET)

              {

              key = KEY1;

              }

       }

       else if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET)

       {

             

              HAL_Delay(10);

              if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET)

              {

              key = KEY2;

              }

       }

       else if((HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET))

       {

              HAL_Delay(10);

              if((HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET))

              {

              key = KEY3;

              }

       }

       else if((HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == GPIO_PIN_SET))

       {

              HAL_Delay(10);

              if((HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == GPIO_PIN_SET))

              {

              key = KEY4;

              }

       }



       return key;

}

相应的在key.h中需要设置一些对应的定义:

#include "main.h"

// 按键的枚举变量

typedef enum

{

                     KEY0 = 0,   // 没有按键按下

                     KEY1,

                     KEY2,

                     KEY3,    

                     KEY4,

} KEYS;
#define KEY_WAIT_ALWAYS   0  // 作为ScanKeys的输入参数,表示一直等待按键输入

KEYS ScanKeys(uint32_t timeout);

这样对按键的识别就完成了,接下来我们需要对按键做出反应,在主函数中对按键做出反应:

KEYS curKey;

  /* USER CODE END 2 */



  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

       while(1)

       {

    /* USER CODE END WHILE */



    /* USER CODE BEGIN 3 */

              curKey=ScanKeys(KEY_WAIT_ALWAYS);

              switch(curKey)

              {

                     case  KEY0:

                            break;

                     case       KEY1:

                     {

                            Touch_Set();

                            break;

                     }

                     case       KEY2:

                     {

                            Finger_Set();

                            break;

                     }

                     case       KEY3:

                     {

                            IDCard_Set();

                            break;

                     }

                     // 修改密码

                     case       KEY4:

                     {

                            Password_Set();

                            break;

                     }

              }//end switch

              HAL_Delay(300);

       }

switch函数中的各个函数组成在上边的显示部分中.

接下来我们对触摸做出反应,触摸函数实际上就是将按下屏幕的位置进行计算,然后得出坐标.这部分函数有很多实现的方法,这里只是其中的一种,这些函数厂商会提供,可以直接复制厂商的,这里我就不进行详细讲解了,剩下的自己识别部分我们再详细说明:

#include "touch.h"

#include "tim.h"

#include      "touch.h"

#include      "lcd.h"

#include "24C02_EEPROM.h"



/* 触摸校正因数设置 */

#define LCD_ADJX_MIN (10)                      //读取四个点的最小X值

#define LCD_ADJX_MAX (240 -  LCD_ADJX_MIN) //读取四个点的最大X值

#define LCD_ADJY_MIN (10)                      //读取四个点的最小Y值

#define LCD_ADJY_MAX (320 - LCD_ADJY_MIN) //读取四个点的最大Y值



#define LCD_ADJ_X (LCD_ADJX_MAX - LCD_ADJY_MIN)//读取方框的宽度

#define LCD_ADJ_Y (LCD_ADJY_MAX - LCD_ADJY_MIN)//读取方框的高度



#define TOUCH_READ_TIMES 5     //一次读取触摸值的次数



#define TOUCH_X_CMD      0xD0  //读取X轴命令

#define TOUCH_Y_CMD      0x90  //读取Y轴命令



#define TOUCH_MAX        20    //预期差值

#define TOUCH_X_MAX      4000  //X轴最大值

#define TOUCH_X_MIN      100   //X轴最小值

#define TOUCH_Y_MAX      4000  //Y轴最大值

#define TOUCH_Y_MIN      100   //Y轴最小值



//电阻屏SPI接口的基本输入输出

#define MISO_Read()             HAL_GPIO_ReadPin(T_MISO_GPIO_Port,T_MISO_Pin)



#define MOSI_Out0()              HAL_GPIO_WritePin(T_MOSI_GPIO_Port,T_MOSI_Pin,GPIO_PIN_RESET)

#define MOSI_Out1()              HAL_GPIO_WritePin(T_MOSI_GPIO_Port,T_MOSI_Pin,GPIO_PIN_SET)



#define SCK_Out0()         HAL_GPIO_WritePin(T_SCK_GPIO_Port,T_SCK_Pin,GPIO_PIN_RESET)

#define SCK_Out1()         HAL_GPIO_WritePin(T_SCK_GPIO_Port,T_SCK_Pin,GPIO_PIN_SET)



#define TCS_Out0()          HAL_GPIO_WritePin(TP_CS_GPIO_Port,TP_CS_Pin,GPIO_PIN_RESET)

#define TCS_Out1()          HAL_GPIO_WritePin(TP_CS_GPIO_Port,TP_CS_Pin,GPIO_PIN_SET)



#define TOUCH_AdjDelay500ms()  HAL_Delay(500)



TouchPointDef TouchPoint;   //触摸点数据



TouchParaDef TouchPara;     //触摸屏校正参数,全局静态变量





//SPI写数据

//向触摸屏写入1byte数据

//num:要写入的数据

void TOUCH_Write_Byte(uint8_t num)

{ 

       uint8_t count=0;

       for(count=0;count<8;count++) 

       {       

              if(num & 0x80)

                     MOSI_Out1();

              else

                     MOSI_Out0();



              num<<=1;   

              SCK_Out0();

              Delay_us(1);

              SCK_Out1();        //上升沿有效

       }

}



//SPI读数据 ,软件模拟SPI

//从触摸屏IC读取adc值

//CMD:指令

//返回值:读到的数据        

uint16_t TOUCH_Read_AD(uint8_t CMD)

{      

       uint8_t count=0;

       uint16_t Num=0;



       SCK_Out0(); //TCLK=0;            //先拉低时钟

       MOSI_Out0();      //TDIN=0;           //拉低数据线

       TCS_Out0();         //TCS=0;             //选中触摸屏IC

       TOUCH_Write_Byte(CMD);//发送命令字

       Delay_us(6); //delay_us(6);     //ADS7846的转换时间最长为6us



       SCK_Out0(); //TCLK=0;

       Delay_us(1); //delay_us(1);

       SCK_Out1(); //TCLK=1;                   //给1个时钟,清除BUSY

       Delay_us(1); //delay_us(1);

       SCK_Out0(); //TCLK=0;



       for(count=0;count<16;count++)//读出16位数据,只有高12位有效

       {                            

              Num<<=1;    

              SCK_Out0(); //TCLK=0;     //下降沿有效

              Delay_us(1); //delay_us(1);

              SCK_Out1(); //TCLK=1;

              if (MISO_Read()) //if(DOUT)

                     Num++;

       }

       Num>>=4;               //只有高12位有效.

       TCS_Out1();         //TCS=1;              //释放片选

       return(Num);  

}



uint16_t TOUCH_ReadData(uint8_t cmd)

{

       uint8_t i, j;

       uint16_t readValue[TOUCH_READ_TIMES], value;

       uint32_t totalValue;



    /* 读取TOUCH_READ_TIMES次触摸值 */

    for(i=0; i<TOUCH_READ_TIMES; i++)

    {   /* 打开片选 */

//       TCS_Out0();         //TCS=0;

        /* 在差分模式下,XPT2046转换需要24个时钟,8个时钟输入命令,之后1个时钟去除 */

        /* 忙信号,接着输出12位转换结果,剩下3个时钟是忽略位 */   

        readValue[i]=TOUCH_Read_AD(cmd); // 发送命令,选择X轴或者Y轴

//        TCS_Out1();          //TCS=1;

    }



    /* 滤波处理 */

    /* 首先从大到小排序 */

    for(i=0; i<(TOUCH_READ_TIMES - 1); i++)

    {

          for(j=i+1; j<TOUCH_READ_TIMES; j++)

          {

                 /* 采样值从大到小排序排序 */

                 if(readValue[i] < readValue[j])

                 {

                        value = readValue[i];

                        readValue[i] = readValue[j];

                        readValue[j] = value;

                 }

          }

    }

  

    /* 去掉最大值,去掉最小值,求平均值 */

    j = TOUCH_READ_TIMES - 1;

    totalValue = 0;

    for(i=1; i<j; i++)     //求y的全部值

    {

          totalValue += readValue[i];

    }

    value = totalValue / (TOUCH_READ_TIMES - 2);



    return value;

}



//返回值为0表示有触摸操作

uint8_t TOUCH_ReadXY(uint16_t *xValue, uint16_t *yValue)

{  

       uint16_t xValue1, yValue1, xValue2, yValue2;



       xValue1 = TOUCH_Read_AD(TOUCH_X_CMD);

       yValue1 = TOUCH_Read_AD(TOUCH_Y_CMD);

       xValue2 = TOUCH_Read_AD(TOUCH_X_CMD);

       yValue2 = TOUCH_Read_AD(TOUCH_Y_CMD);



       /* 查看两个点之间的采样值差距 */

       if(xValue1 > xValue2)

              *xValue = xValue1 - xValue2;

       else

              *xValue = xValue2 - xValue1;



       if(yValue1 > yValue2)

              *yValue = yValue1 - yValue2;

       else

              *yValue = yValue2 - yValue1;



       /* 判断采样差值是否在可控范围内 */

       if((*xValue > TOUCH_MAX+0) || (*yValue > TOUCH_MAX+0)) 

              return 0xFF;



       /* 求平均值 */

       *xValue = (xValue1 + xValue2) / 2;

       *yValue = (yValue1 + yValue2) / 2;



       /* 判断得到的值,是否在取值范围之内 */

       if((*xValue > TOUCH_X_MAX+0) || (*xValue < TOUCH_X_MIN)

                     || (*yValue > TOUCH_Y_MAX+0) || (*yValue < TOUCH_Y_MIN))

              return 0xFF;

       else

              return 0;      //读取成功,有触控操作

}



uint8_t TOUCH_ReadAdjust(uint16_t x, uint16_t y, uint16_t *xValue, uint16_t *yValue)

{

       uint8_t i;

       uint32_t timeCont=0;



       /* 读取校正点的坐标 */

       LCD_Clear(WHITE);

       LCD_DrowSign(x, y, RED);

       i = 0;

       while(1)

       {

              if(!TOUCH_ReadXY(xValue, yValue))

              {

                     i++;

                     if(i > 10)         //延时一下,以读取最佳值

                     {

                            LCD_DrowSign(x, y, WHITE);

                            return 0;

                     }



              }

              timeCont++;

              /* 超时退出 */

              if(timeCont > 0xFFFFFFFE)

              {

                     LCD_DrowSign(x, y, WHITE);

                     return 0xFF;

              }

       }

}



//触摸屏校准,依次在LCD的4个角上显示十字符号,用户点击后获取输出,计算触摸屏参数

void TOUCH_Adjust(void)

{

       uint16_t px[2], py[2], xPot[4], yPot[4];

       float xFactor, yFactor;



       /* 读取第一个点 */

       if(TOUCH_ReadAdjust(LCD_ADJX_MIN, LCD_ADJY_MIN, &xPot[0], &yPot[0]))

              return;

       TOUCH_AdjDelay500ms();



       /* 读取第二个点 */

       if(TOUCH_ReadAdjust(LCD_ADJX_MIN, LCD_ADJY_MAX, &xPot[1], &yPot[1]))

              return;

       TOUCH_AdjDelay500ms();



       /* 读取第三个点 */

       if(TOUCH_ReadAdjust(LCD_ADJX_MAX, LCD_ADJY_MIN, &xPot[2], &yPot[2]))

              return;

       TOUCH_AdjDelay500ms();



       /* 读取第四个点 */

       if(TOUCH_ReadAdjust(LCD_ADJX_MAX, LCD_ADJY_MAX, &xPot[3], &yPot[3]))

              return;

       TOUCH_AdjDelay500ms();



       /* 处理读取到的四个点的数据,整合成对角的两个点 */

       px[0] = (xPot[0] + xPot[1]) / 2;

       py[0] = (yPot[0] + yPot[2]) / 2;

       px[1] = (xPot[3] + xPot[2]) / 2;

       py[1] = (yPot[3] + yPot[1]) / 2;



       /* 求出比例因数 */

       xFactor = (float)LCD_ADJ_X / (px[1] - px[0]);

       yFactor = (float)LCD_ADJ_Y / (py[1] - py[0]);



       /* 求出偏移量 */

       TouchPara.xOffset = (int16_t)LCD_ADJX_MAX - ((float)px[1] * xFactor);

       TouchPara.yOffset = (int16_t)LCD_ADJY_MAX - ((float)py[1] * yFactor);



       /* 将比例因数进行数据处理,然后保存 */

       TouchPara.xFactor = xFactor ;

       TouchPara.yFactor = yFactor ;



       TouchPara.isSaved = TOUCH_PARA_SAVED;

}



uint8_t TOUCH_Scan(void)

{

       if(TOUCH_ReadXY(&TouchPoint.Vx, &TouchPoint.Vy)) //没有触摸

              return 0xFF;



       /* 根据物理坐标值,计算出彩屏坐标值 */

       TouchPoint.Lcdx = TouchPoint.Vx * TouchPara.xFactor + TouchPara.xOffset;

       TouchPoint.Lcdy = TouchPoint.Vy * TouchPara.yFactor + TouchPara.yOffset;



       /* 查看彩屏坐标值是否超过彩屏大小 */

       if(TouchPoint.Lcdx > 240)

              TouchPoint.Lcdx = 240;



       if(TouchPoint.Lcdy > 320)

              TouchPoint.Lcdy = 320;



       return 0;  

}



void TOUCH_ScanAfterINT(void)    // T_PEN中断后读取

{

       TouchPoint.Vx = TOUCH_ReadData(TOUCH_X_CMD);

       TouchPoint.Vy = TOUCH_ReadData(TOUCH_Y_CMD);



       /* 根据物理坐标值,计算出彩屏坐标值 */

       TouchPoint.Lcdx = TouchPoint.Vx * TouchPara.xFactor + TouchPara.xOffset;

       TouchPoint.Lcdy = TouchPoint.Vy * TouchPara.yFactor + TouchPara.yOffset;



       /* 查看彩屏坐标值是否超过彩屏大小 */

       if(TouchPoint.Lcdx > 240)

              TouchPoint.Lcdx = 240;



       if(TouchPoint.Lcdy > 320)

              TouchPoint.Lcdy = 320;

}

uint16_t LCD_CurX=0;      //当前位置X

uint16_t LCD_CurY=0;      //当前位置Y

void ShowTouchPara(void)//显示触摸屏参数

{



       uint16_t  IncY=16;   //Y间距



       LCD_ShowString(10,0,240,16,16,(uint8_t*)"**Parameters of touch screen:");

       LCD_ShowString(0,16,240,16,16,(uint8_t*)"xOffset= ");

       LCD_ShowChar(80, 16,TouchPara.xOffset,16,0);



       LCD_ShowString(0,32,240,16,16,(uint8_t*)"yOffset= ");

       LCD_ShowChar(80, 32,TouchPara.yOffset,16,0);



       LCD_ShowString(0,32+IncY,240,16,16,(uint8_t*)"xFactor= ");

       LCD_ShowxNum(80, 32+IncY,TouchPara.xFactor, 4,16,0);



       LCD_ShowString(0,32+IncY+IncY,240,16,16,(uint8_t*)"yFactor= ");

       LCD_ShowxNum(80, 32+IncY+IncY,TouchPara.yFactor, 4,16,0);

}



void TouchCalibrate(void)//进行触摸屏测试,获取参数

{

       LCD_ShowString(10,0,240,16,16,(uint8_t*)"**Touch screen calibration");



       LCD_ShowString(10,16,240,16,16,(uint8_t*)"A red cross will display on");

       LCD_ShowString(10,32,240,16,16,(uint8_t*)"the 4 corners of LCD. ");

       LCD_ShowString(10,48,240,16,16,(uint8_t*)"Touch red cross one by one.");

       LCD_ShowString(10,64,240,16,16,(uint8_t*)"Press any key to start...");



       HAL_Delay(3000);

       TOUCH_Adjust(); //触摸屏校正时会清屏

       EP24C_WriteLongData(TOUCH_PARA_ADDR, &TouchPara.isSaved, sizeof(TouchPara));



       LCD_CurY=40;

       ShowTouchPara();//显示触摸屏参数



       LCD_ShowString(10,80,240,16,16,(uint8_t*)"Press any key to enter GUI");

       HAL_Delay(3000);

}

在这些函数之后,我们需要对之前的屏幕下方的按键部分进行识别,这些按键分为数字和命令,所以得分成两个单独的函数,这些函数的实现部分,我在注释中有详细说明,但是这个是之前写的,实现的逻辑不太好,但是还能用,也就不太想改了(就是懒):

// a用来储存当前的数字,c用来检测位置

uint8_t a,c = 0;

extern uint8_t Password[6];

// 位置和第几个数字对应

uint8_t a_c(uint8_t x)

{

       if(c == 0)

              return 0;

       if(c == 1)

              return 20;

       if(c == 2)

              return 40;

       if(c == 3)

              return 60;

       if(c == 4)

              return 80;

       if(c == 5)

              return 100;

       if(c == 6)  // 密码过长了

              LCD_ShowString(10,130,240,16,16,(uint8_t*)"The password is too long!");

              HAL_Delay(3000);

              LCD_Fill(10,130, 240, 170, WHITE);

       return 0;

}

// 定义一个储存密码的数组

uint8_t PasswordIn[6];

// 这个函数用来检测触摸的位置以及做出反应

uint8_t Touch_Num(void)

{

       // 返回值

       uint8_t i;

       if(TOUCH_Scan() == 0)  // 触摸屏扫描

       {

              // 1

              if(TouchPoint.Lcdx < 80 && TouchPoint.Lcdy > 200&&TouchPoint.Lcdy<230)

              {

                     a = a_c(c);

                     PasswordIn[c] = 1;

                     LCD_ShowNum(a, 150, 1, 1, 16);

                     c+=1;

                     i = 1;

                     return i;

              }

              // 2

              else if(TouchPoint.Lcdx<160&&TouchPoint.Lcdy > 200&&TouchPoint.Lcdy<230&&TouchPoint.Lcdx>80)

              {

                     a = a_c(c);

                     PasswordIn[c] = 2;

                     LCD_ShowNum(a, 150, 2, 1, 16);

                     c+=1;

                     i = 2;

                     return i;

              }

              // 3

              else if(TouchPoint.Lcdx>160&&TouchPoint.Lcdy > 200&&TouchPoint.Lcdy<230)

              {

                     a = a_c(c);

                     PasswordIn[c] = 3;

                     LCD_ShowNum(a, 150, 3, 1, 16);

                     c+=1;

                     i = 3;

                     return i;

              }

              // 4

             else if(TouchPoint.Lcdx< 80&&TouchPoint.Lcdy > 230&&TouchPoint.Lcdy<260)

              {

                     a = a_c(c);

                     PasswordIn[c] = 4;

                     LCD_ShowNum(a, 150, 4, 1, 16);

                     c+=1;

                     i = 4;

                     return i;

              }

              // 5

              else if(TouchPoint.Lcdx<160&&TouchPoint.Lcdy > 230&&TouchPoint.Lcdy<260&&TouchPoint.Lcdx>80)

              {

                     a = a_c(c);

                     PasswordIn[c] = 5;

                     LCD_ShowNum(a, 150, 5, 1, 16);

                     c+=1;

                     i = 5;

                     return i;

              }

              // 6

              else if(TouchPoint.Lcdx>160&&TouchPoint.Lcdy > 230&&TouchPoint.Lcdy<260)

              {

                     a = a_c(c);

                     PasswordIn[c] = 6;

                     LCD_ShowNum(a, 150, 6, 1, 16);

                     c+=1;

                     i = 6;

                     return i;

              }

              // 7

              else if(TouchPoint.Lcdx<80&&TouchPoint.Lcdy>260&&TouchPoint.Lcdy<290)

              {

                     a = a_c(c);

                     PasswordIn[c] = 7;

                     LCD_ShowNum(a, 150, 7, 1, 16);

                     c+=1;

                     i = 7;

                     return i;

              }

              // 8

              else if(TouchPoint.Lcdx<160&&TouchPoint.Lcdx>80&&TouchPoint.Lcdy>260&&TouchPoint.Lcdy<290)

              {

                     a = a_c(c);

                     PasswordIn[c] = 8;

                     LCD_ShowNum(a, 150, 8, 1, 16);

                     c+=1;

                     i = 8;

                     return i;

              }

              // 9

             else if(TouchPoint.Lcdx>160&&TouchPoint.Lcdy>260&&TouchPoint.Lcdy<290)

              {

                     a = a_c(c);

                     PasswordIn[c] = 9;

                     LCD_ShowNum(a, 150, 9, 1, 16);

                     c+=1;

                     i = 9;

                     return i;

              }

              // *——表示输入错误,重新输入上一位

              else if(TouchPoint.Lcdx<80&&TouchPoint.Lcdy>290)

              {

                    

                     c-=1;

                     a = a_c(c);

                     LCD_Fill(a, 150, a+20, 166, WHITE);

                     i = 0;

                     return i;

              }

              // 0

              else if(TouchPoint.Lcdx<160&&TouchPoint.Lcdx>80&&TouchPoint.Lcdy>290)

              {

                     a = a_c(c);

                     PasswordIn[c] = 0;

                     LCD_ShowNum(a, 150, 0, 1, 16);

                     c+=1;

                     i = 0;

                     return i;

              }

              // #——表示确定密码输入

              else if(TouchPoint.Lcdx>160&&TouchPoint.Lcdy>290)

              {

                     c = 0;

                     for(uint8_t i = 0;i<6;i++)

                     {

                            // 输出密码错误

                            if(PasswordIn[i] != Password[i])

                            {

                                   LCD_ShowString(10,130,240,16,16,(uint8_t*)"The password is incorrect!");

                                   HAL_Delay(3000);

                                   LCD_Fill(0,130, 239, 170, WHITE);

                                   return 0;

                            }

                     }

                     // 密码正确

                    LCD_ShowString(10,130,240,16,16,(uint8_t*)"The password is correct!");

                     HAL_Delay(3000);

                     LCD_Fill(0,130, 239, 170, WHITE);

                    

              }

       }

       return 0;

}

// 触摸位置是命令的位置

void TOUCH_Command(void)

{

       // 删除指纹

       if(TouchPoint.Lcdx < 80 && TouchPoint.Lcdy > 170&&TouchPoint.Lcdy<200)

       {

              // 请选择想删除的指纹

             LCD_ShowString(10,100,240,16,16,(uint8_t*)"Please select the fingerprint!");

              HAL_Delay(3000);

              LCD_Fill(0,100, 240, 170, WHITE);

              // 这个函数用来检测触摸的位置以及做出反应

              uint8_t i = Touch_Num();

              // 删除想要删除的指纹ID

              if(i>0)

              {

//                  Del_FR(i);

              }

       }

       // 修改密码

       else if(TouchPoint.Lcdx<160&&TouchPoint.Lcdy > 170&&TouchPoint.Lcdy<200&&TouchPoint.Lcdx>80)

       {

              LCD_ShowString(10,100,240,16,16,(uint8_t*)"Please enter previous password!");

//           c = 0;

              for(c = 0;c<6;)

              {

                     Touch_Num();

                     HAL_Delay(200);

              }

             

              for(uint8_t i = 0;i<6;i++)

              {

                     // 输入密码错误

                     if(PasswordIn[i] != Password[i])

                     {

                            LCD_ShowString(10,130,240,16,16,(uint8_t*)"The password is incorrect!");

                            HAL_Delay(3000);

                            LCD_Fill(0, 130,240, 165, WHITE);  //清除信息显示区

                            return;

                     }

              }

              // 密码正确

              LCD_ShowString(10,130,240,16,16,(uint8_t*)"The password is correct!");

              HAL_Delay(3000);

              LCD_Fill(0, 130,240, 165, WHITE);  //清除信息显示区

              // 输出请输入新密码

              LCD_ShowString(10,130,240,16,16,(uint8_t*)"Please enter a new password!");

              for(c = 0;c<6;)

              {

//                  c = 0;

                     Touch_Num();

                     HAL_Delay(200);

              }

              LCD_Fill(0, 130,240, 146, WHITE);  //清除信息显示区

              // 输出密码修改成功

              LCD_ShowString(10,130,240,16,16,(uint8_t*)"The password is OK!");

             

              HAL_Delay(3000);

              LCD_Fill(0, 130,240, 165, WHITE);  //清除信息显示区

              EP24C_WriteLongData(PASSWORD_PARA_ADDR, PasswordIn,sizeof(PasswordIn));

              c = 0;

       }

       // 新建指纹

       else if(TouchPoint.Lcdx>160&&TouchPoint.Lcdy > 170&&TouchPoint.Lcdy<200)

       {

              // 请选择新建指纹的位置

              LCD_ShowString(10,100,240,16,16,(uint8_t*)"Select the new fingerprint");

              HAL_Delay(3000);

              LCD_Fill(0,100, 240, 170, WHITE);

              // 这个函数用来检测触摸的位置以及做出反应

              uint8_t i = Touch_Num();

              if(i>0)

              {

                     // 录入指纹ID

//                  Add_FR(i);

              }

       }



}

void Touch_Point(void)  // 将之前的函数进行合并,主函数中只需要调用这个函数就足够了.

{

       if(TOUCH_Scan() == 0)  // 触摸屏扫描

       {

              TOUCH_Command();

              Touch_Num();

       }

}



// 微秒级延时(上边会用到)

void Delay_us(uint16_t delay)

{

       __HAL_TIM_DISABLE(&htim7);

       __HAL_TIM_SET_COUNTER(&htim7,0);  // 设置计数值初值

       __HAL_TIM_ENABLE(&htim7);

       uint16_t curCnt = 0;

       while(1)  // 开始计数

       {

              curCnt = __HAL_TIM_GET_COUNTER(&htim7);

              if(curCnt>delay)

                     break;

       }

      

       __HAL_TIM_DISABLE(&htim7);

}

Touch.c所对应的touch.h中的程序如下:

#ifndef __TOUCH_H

#define __TOUCH_H 



#include "main.h"

#include      "lcd.h"

// 微秒级延时

void Delay_us(uint16_t delay);



/* 定义数据类型 */

// 触摸点数据结构体定义

typedef struct

{

       uint16_t Vx; //XPT2046输出的X轴电压值

       uint16_t Vy; //XPT2046输出的Y轴电压值

       uint16_t Lcdx;     //计算的LCD坐标X

       uint16_t Lcdy;     //计算的LCD坐标Y

} TouchPointDef;

extern TouchPointDef TouchPoint; //触摸点数据全局变量



// 电阻触摸屏校正参数, 需要保存到EEPROM

typedef struct{

       uint8_t isSaved;    // 参数是否已保存到EEPROM

       int16_t xOffset;   //偏移量

       int16_t yOffset;

       float xFactor;             //相乘因子

       float yFactor;

} TouchParaDef;

extern TouchParaDef TouchPara;     //触摸屏校准参数全局变量



#define TOUCH_PARA_SAVED      'S'    //表示触摸校准参数准备好了

#define TOUCH_PARA_ADDR        80    //校正参数在24C02中的首地址,必须是页的起始地址,也就是8的整数倍





//触摸屏校正,会清除屏幕,依次在屏幕四个角上显示红色十字符号,点击进行测试。

//计算的校准参数保存在变量TouchPara里,并保存到EEPROM

void TOUCH_Adjust(void);



//触摸屏扫描,返回值为0表示有触摸操作,触摸点保存到变量TouchPoint里

uint8_t TOUCH_Scan(void);



void TOUCH_ScanAfterINT(void);   //T_PEN中断后读取



// 新定义的两个函数

//显示触摸屏参数,即全局变量TouchPara的数据

void ShowTouchPara(void);



//进行触摸屏测试,内部会调用TOUCH_Adjust()

void TouchCalibrate(void);







// 这个函数用来检测触摸的位置以及做出反应

void Touch_Point(void);





#endif /* __TOUCH_H */

在上边的函数中使用的EEPROM,这些使用的地方实际上就是将屏幕的坐标存入只读存储器中.接下来就进入24C02.c文件中,这个文件主要定义存储的实现过程,具体这些实现方法如下程序,这些也是厂商提供:

#include "24C02_EEPROM.h"



#define   EP24C_TIMEOUT      200  //超时等待时间,单位:节拍数

#define   EP24C_MEMADD_SIZE  I2C_MEMADD_SIZE_8BIT  //存储器地址大小,8位地址





//检查设备是否准备好 I2C 通信,返回HAL_OK 表示OK

HAL_StatusTypeDef EP24C_IsDeviceReady(void)

{

       uint32_t  Trials=10;  //尝试次数

       HAL_StatusTypeDef result=HAL_I2C_IsDeviceReady(&I2C_HANDLE,DEV_ADDR_24CXX,Trials,EP24C_TIMEOUT);

      

       return result;

}



//向任意地址写入1字节的数据,memAddr 是存储器内部地址,byteData 是需要写入的1字节数据

HAL_StatusTypeDef EP24C_WriteOneByte(uint16_t memAddress, uint8_t byteData)

{

       HAL_StatusTypeDef result=HAL_I2C_Mem_Write(&I2C_HANDLE,DEV_ADDR_24CXX, memAddress, EP24C_MEMADD_SIZE, &byteData, 1,EP24C_TIMEOUT);

       return result;



}





//从任意地址读出1字节的数据,memAddr 是存储器内部地址,byteData是读出的1字节数据

HAL_StatusTypeDef EP24C_ReadOneByte(uint16_t memAddress, uint8_t byteData)

{

       HAL_StatusTypeDef result=HAL_I2C_Mem_Read(&I2C_HANDLE,DEV_ADDR_24CXX, memAddress, EP24C_MEMADD_SIZE, &byteData, 1,EP24C_TIMEOUT);

       return result;



}





//连续读取数据,任意地址,任意长度,不受页的限制

HAL_StatusTypeDef EP24C_ReadBytes(uint16_t memAddress, uint8_t *pBuffer,uint16_t bufferLen)

{

       if (bufferLen>MEM_SIZE_24CXX)   //超过总存储容量

              return HAL_ERROR;

       HAL_StatusTypeDef result=HAL_I2C_Mem_Read(&I2C_HANDLE,DEV_ADDR_24CXX,memAddress,EP24C_MEMADD_SIZE,pBuffer,bufferLen,EP24C_TIMEOUT);

       return result;

      

}



//限定在一个页内写入连续数据,最多 8 字节。从任意起始地址开始,但起始地址+数据长度不能超过页边界

HAL_StatusTypeDef EP24C_WriteInOnePage(uint16_t memAddress, uint8_t *pBuffer,uint16_t bufferLen)

{

       if (bufferLen>MEM_SIZE_24CXX)   //超过总存储容量

              return HAL_ERROR;

       HAL_StatusTypeDef result=HAL_I2C_Mem_Write(&I2C_HANDLE,DEV_ADDR_24CXX,memAddress,EP24C_MEMADD_SIZE,pBuffer,bufferLen,EP24C_TIMEOUT);      

       return result;     

             

}



//写任意长的数据,可以超过8字节,但数据地址必须从页首开始,即8XN。自动分解为多次写入

HAL_StatusTypeDef EP24C_WriteLongData(uint16_t memAddress, uint8_t *pBuffer,uint16_t bufferLen)

{

       if (bufferLen>MEM_SIZE_24CXX)   //超过总存储容量

              return HAL_ERROR;

       HAL_StatusTypeDef result=HAL_ERROR;

       if (bufferLen<=PAGE_SIZE_24CXX)  //不超过1个page,直接写入后退出

       {

       result=HAL_I2C_Mem_Write(&I2C_HANDLE,DEV_ADDR_24CXX,memAddress,EP24C_MEMADD_SIZE,pBuffer,bufferLen,EP24C_TIMEOUT);      

              return result;

       }

       uint8_t *pt=pBuffer;  //临时指针,不能改变传入的指针

       uint16_t pageCount=bufferLen/PAGE_SIZE_24CXX;   //Page个数

       for(uint16_t i=0;i<pageCount;i++)  //一次写入一个page 的数据

       {

       result=HAL_I2C_Mem_Write(&I2C_HANDLE,DEV_ADDR_24CXX,memAddress,EP24C_MEMADD_SIZE,pt, PAGE_SIZE_24CXX,EP24C_TIMEOUT);  

              pt += PAGE_SIZE_24CXX;

              memAddress += PAGE_SIZE_24CXX;

              HAL_Delay(5);   //必须有延时,以等待页写完

              if (result != HAL_OK)

                     return result;

      

       }

       uint16_t leftBytes=bufferLen%PAGE_SIZE_24CXX; //余数

       if (leftBytes>0)   //写入剩余的数据

       result=HAL_I2C_Mem_Write(&I2C_HANDLE,DEV_ADDR_24CXX,memAddress,EP24C_MEMADD_SIZE,pt, leftBytes,EP24C_TIMEOUT);   

       return result;     

             



}

对应的.h文件程序:

#ifndef __24C02_EEPROM_H

#define __24C02_EEPROM_H



#include "main.h"

#include "i2c.h"



#define    I2C_HANDLE     hi2c2  // I2C接口外设对象变量

#define    DEV_ADDR_24CXX 0x00A0  // 24c02的写地址





#define    PASSWORD_PARA_ADDR        16    //密码在24C02中的首地址,必须是页的起始地址,也就是8的整数倍



#define    PAGE_SIZE_24CXX  0x0008  // 24c02的page大小为8字节

#define    MEM_SIZE_24CXX  (uint16_t)256  // 24c02总容量为256字节







//检查设备是否准备好 I2C 通信,返回HAL_OK 表示OK

HAL_StatusTypeDef EP24C_IsDeviceReady(void);



//向任意地址写入1字节的数据,memAddr 是存储器内部地址,byteData 是需要写入的1字节数据

HAL_StatusTypeDef EP24C_WriteOneByte(uint16_t memAddress, uint8_t byteData);





//从意地址读出1字节的数据,memAddr 是存储器内部地址,byteData是读出的1字节数据

HAL_StatusTypeDef EP24C_ReadOneByte(uint16_t memAddress, uint8_t byteData);





//连续读取数据,任意地址,任意长度,不受页的限制

HAL_StatusTypeDef EP24C_ReadBytes(uint16_t memAddress, uint8_t *pBuffer, uint16_t bufferLen);





//限定在一个页内写入连续数据,最多 8 字节。从任意起始地址开始,但起始地址+数据长度不能超过页边界

HAL_StatusTypeDef EP24C_WriteInOnePage(uint16_t memAddress, uint8_t *pBuffer,uint16_t bufferLen);





//写任意长的数据,可以超过8字节,但数据地址必须从页首开始,即8XN。自动分解为多次写入

HAL_StatusTypeDef EP24C_WriteLongData(uint16_t memAddress, uint8_t *pBuffer,uint16_t bufferLen);

#endif /* __24C02_EEPROM_H */

这些完成后,我们就可以将之前的密码存入rom中了(下面的部分在main.c中):

//====1. 读取保存在EEPROM中的电阻触摸屏参数

       EP24C_ReadBytes(TOUCH_PARA_ADDR, &TouchPara.isSaved, sizeof(TouchPara));

       if (TouchPara.isSaved ==TOUCH_PARA_SAVED)

             LCD_ShowString(10,80,240,12,12,(uint8_t*)"Touch-Res has been calibrated");

       else

              LCD_ShowString(10,80,240,12,12,(uint8_t*)"Touch-Res has not been calibrated");

             

       // 向EEPROM中写入初始密码

//    EP24C_WriteLongData(PASSWORD_PARA_ADDR, Password,sizeof(Password));

       // 从EEPROM中读取密码

       EP24C_ReadBytes(PASSWORD_PARA_ADDR,Password,sizeof(Password));

       // 检验读取的密码

//    for(uint8_t i = 0;i<6;i++)

//    {

//           LCD_ShowxNum(10,80,Password[i],1,16,0);

//           HAL_Delay(500);

//    }

至此就完成了屏幕和密码部分的所有操作,但是这些操作在主函数中实现的效率不高,所以我们将主函数中的内容转到freertos中.

打开CobeMX,找到FREERTOS,选择模式为:CMSIS_V2.然后先创建两个任务,分别为Key和Touch,这里设置Key的优先级高于Touch,具体设置如图:

设置完成后,这里需要将SYS的时钟更改为TIM6, 因为之前没有使用FreeRTOS时HAL时钟默认是SysTick,但是现在FreeRTOS使用了SysTick,所以我们要为HAL时钟重新配置基础时钟.完成时钟配置后生成代码.

将之前main.c中的while循环的key相关代码放入Key的for循环中,将触摸相关的代码放入Touch的循环中,

现在main函数中的代码如下:

int main(void)

{

  /* USER CODE BEGIN 1 */



  /* USER CODE END 1 */



  /* MCU Configuration--------------------------------------------------------*/



  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();



  /* USER CODE BEGIN Init */

      

  /* USER CODE END Init */



  /* Configure the system clock */

  SystemClock_Config();



  /* USER CODE BEGIN SysInit */



  /* USER CODE END SysInit */



  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_FSMC_Init();

  MX_I2C2_Init();

  MX_TIM7_Init();

  /* USER CODE BEGIN 2 */

       LCD_Init();

       // 屏幕显示初始化

       Bsp_Lcd_Init();

       //====1. 读取保存在EEPROM中的电阻触摸屏参数

       EP24C_ReadBytes(TOUCH_PARA_ADDR, &TouchPara.isSaved, sizeof(TouchPara));

       if (TouchPara.isSaved ==TOUCH_PARA_SAVED)

             LCD_ShowString(10,80,240,12,12,(uint8_t*)"Touch-Res has been calibrated");

       else

              LCD_ShowString(10,80,240,12,12,(uint8_t*)"Touch-Res has not been calibrated");

             

       // 向EEPROM中写入初始密码

//    EP24C_WriteLongData(PASSWORD_PARA_ADDR, Password,sizeof(Password));

       // 从EEPROM中读取密码

       EP24C_ReadBytes(PASSWORD_PARA_ADDR,Password,sizeof(Password));

       // 检验读取的密码

//    for(uint8_t i = 0;i<6;i++)

//    {

//           LCD_ShowxNum(10,80,Password[i],1,16,0);

//           HAL_Delay(500);

//    }

      

      

  /* USER CODE END 2 */



  /* Init scheduler */

  osKernelInitialize();  /* Call init function for freertos objects (in freertos.c) */

  MX_FREERTOS_Init();



  /* Start scheduler */

  osKernelStart();

  /* We should never get here as control is now taken by the scheduler */

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

       while(1)

       {

    /* USER CODE END WHILE */



    /* USER CODE BEGIN 3 */

             

       }

  /* USER CODE END 3 */

}

Freertos.c中各个函数如下:

void Key(void *argument)

{

  /* USER CODE BEGIN Key */

       KEYS      curKey;

  /* Infinite loop */

  for(;;)

  {

    curKey=ScanKeys(KEY_WAIT_ALWAYS);

              switch(curKey)

              {

                     case  KEY0:

                            break;

                     case       KEY1:

                     {

                            Touch_Set();

                            break;

                     }

                     case       KEY2:

                     {

                            Finger_Set();

                            break;

                     }

                     case       KEY3:

                     {

                            IDCard_Set();

                            break;

                     }

                     // 修改密码

                     case       KEY4:

                     {

                            Password_Set();

                            break;

                     }

              }//end switch

              vTaskDelay(300);

  }

  /* USER CODE END Key */

}



/* USER CODE BEGIN Header_Touch */

/**

* @brief Function implementing the Task_Touch thread.

* @param argument: Not used

* @retval None

*/

/* USER CODE END Header_Touch */

void Touch(void *argument)

{

  /* USER CODE BEGIN Touch */

      

  /* Infinite loop */

  for(;;)

  {

    Touch_Point();

              vTaskDelay(300);

  }

  /* USER CODE END Touch */

}

当然在这之前需要添加这些函数的头文件:

#include "bsp_lcd.h"

#include "24C02_EEPROM.h"

#include "bsp_key.h"

#include "touch.h"

至此,有关屏幕的部分已经全部完成了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值