29.1 触摸屏简介

1.1 电阻式触摸屏检测原理

1.2 电阻触摸屏控制芯片

1.3 电容式触摸屏检测原理

29.2 电阻触摸屏—触摸画板实验

2.1 硬件设计

2.2 软件设计

2.2.1 编程要点

(1) 编写软件模拟 SPI 协议的驱动;

(2) 编写触摸芯片的控制驱动,如发送命令字,获取触摸坐标等;

(3) 编写触摸校正程序;

(4) 编写测试程序检验驱动。

2.2.2 代码分析

1.触摸屏硬件相关宏定义

2.初始化触摸屏控制引脚

3.模拟 SPI 协议的读写时序

4.采集触摸原始数据

5.多次采样求平均值

6.根据原始数据计算坐标值

7.触摸校正

8.触摸检测状态机

9.触摸坐标获取及处理

2.2.3 main 函数

main.c

/********************************************************************************* @file    main.c* @author  fire* @version V1.0* @date    2013-xx-xx* @brief   触摸画板实验******************************************************************************* @attention** 实验平台:野火 F103-指南者 STM32 开发板 * 论坛    :http://www.firebbs.cn* 淘宝    :https://fire-stm32.taobao.com********************************************************************************/ #include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./lcd/bsp_ili9341_lcd.h"
#include "./lcd/bsp_xpt2046_lcd.h"
#include "./flash/bsp_spi_flash.h"
#include "./led/bsp_led.h"
#include "palette.h"
#include <string.h>int main(void)
{       //LCD 初始化ILI9341_Init();  //触摸屏初始化XPT2046_Init();//从FLASH里获取校正参数,若FLASH无参数,则使用模式3进行校正Calibrate_or_Get_TouchParaWithFlash(3,0);/* USART config */USART_Config();  LED_GPIO_Config();printf("\r\n ********** 触摸画板程序 *********** \r\n"); printf("\r\n 若汉字显示不正常,请阅读工程中的readme.txt文件说明,根据要求给FLASH重刷字模数据\r\n"); //其中0、3、5、6 模式适合从左至右显示文字,//不推荐使用其它模式显示文字   其它模式显示文字会有镜像效果          //其中 6 模式为大部分液晶例程的默认显示方向  ILI9341_GramScan ( 3 );   //绘制触摸画板界面Palette_Init(LCD_SCAN_MODE);while ( 1 ){//触摸检测函数,本函数至少10ms调用一次XPT2046_TouchEvenHandler();}}/* ------------------------------------------end of file---------------------------------------- */

palette.h

#ifndef _PALETTE_H
#define _PALETTE_H#include "stm32f10x.h"
#include "./lcd/bsp_ili9341_lcd.h"#define COLOR_BLOCK_WIDTH   40
#define COLOR_BLOCK_HEIGHT  28#define BUTTON_NUM 16
#define PALETTE_START_Y   0
#define PALETTE_END_Y     LCD_Y_LENGTH#if 1     //按钮栏在左边#define BUTTON_START_X      0#define PALETTE_START_X   (COLOR_BLOCK_WIDTH*2+1)#define PALETTE_END_X     LCD_X_LENGTH#else     //按钮栏在右边,(存在触摸按键时也会的bug仅用于测试触摸屏左边界)#define BUTTON_START_X      (LCD_X_LENGTH-2*COLOR_BLOCK_WIDTH)#define PALETTE_START_X      0#define PALETTE_END_X      (LCD_X_LENGTH-2*COLOR_BLOCK_WIDTH)#endif/*LCD 颜色代码,CL_是Color的简写16Bit由高位至低位, RRRR RGGG GGGB BBBB下面的RGB 宏将24位的RGB值转换为16位格式。启动windows的画笔程序,点击编辑颜色,选择自定义颜色,可以获得的RGB值。推荐使用迷你取色器软件获得你看到的界面颜色。
*/
#if LCD_RGB_888
/*RGB888颜色转换*/
#define RGB(R,G,B)  ( (R<< 16) | (G << 8) | (B))    /* 将8位R,G,B转化为 24位RGB888格式 */#else
/*RGB565 颜色转换*/
#define RGB(R,G,B)  (((R >> 3) << 11) | ((G >> 2) << 5) | (B >> 3))   /* 将8位R,G,B转化为 16位RGB565格式 */
#define RGB565_R(x)  ((x >> 8) & 0xF8)
#define RGB565_G(x)  ((x >> 3) & 0xFC)
#define RGB565_B(x)  ((x << 3) & 0xF8)#endifenum
{CL_WHITE    = RGB(255,255,255),   /* 白色 */CL_BLACK    = RGB(  0,  0,  0),    /* 黑色 */CL_RED      = RGB(255, 0,  0), /* 红色 */CL_GREEN    = RGB(  0,255,  0),    /* 绿色 */CL_BLUE     = RGB(  0, 0,255), /* 蓝色 */CL_YELLOW   = RGB(255,255,  0),    /* 黄色 */CL_GREY    = RGB( 98, 98, 98),     /* 深灰色 */CL_GREY1       = RGB( 150, 150, 150),     /* 浅灰色 */CL_GREY2       = RGB( 180, 180, 180),     /* 浅灰色 */CL_GREY3       = RGB( 200, 200, 200),     /* 最浅灰色 */CL_GREY4      = RGB( 230, 230, 230),     /* 最浅灰色 */CL_BUTTON_GREY    = RGB( 195, 195, 195), /* WINDOWS 按钮表面灰色 */CL_MAGENTA      = RGB(255, 0, 255),    /* 红紫色,洋红色 */CL_CYAN         = RGB( 0, 255, 255),   /* 蓝绿色,青色 */CL_BLUE1        = RGB(  0,  0, 240),        /* 深蓝色 */CL_BLUE2        = RGB(  0,  0, 128),      /* 深蓝色 */CL_BLUE3        = RGB(  68, 68, 255),     /* 浅蓝色1 */CL_BLUE4        = RGB(  0, 64, 128),     /* 浅蓝色1 *//* UI 界面 Windows控件常用色 */CL_BTN_FACE         = RGB(236, 233, 216),    /* 按钮表面颜色(灰) */CL_BOX_BORDER1   = RGB(172, 168,153),   /* 分组框主线颜色 */CL_BOX_BORDER2 = RGB(255, 255,255),   /* 分组框阴影线颜色 */CL_MASK               = 0x7FFF   /* RGB565颜色掩码,用于文字背景透明 */
};typedef struct
{uint16_t start_x;   //按键的x起始坐标  uint16_t start_y;   //按键的y起始坐标uint16_t end_x;     //按键的x结束坐标 uint16_t end_y;     //按键的y结束坐标uint32_t para;      //颜色按钮中表示选择的颜色,笔迹形状按钮中表示选择的画刷uint8_t touch_flag; //按键按下的标志void (*draw_btn)(void * btn);     //按键描绘函数void (*btn_command)(void * btn);  //按键功能执行函数,例如切换颜色、画刷}Touch_Button;/*画刷形状列表*/
typedef enum
{LINE_SINGLE_PIXCEL = 0,   //单像素线LINE_2_PIXCEL,  //2像素线LINE_4_PIXCEL,  //4像素线LINE_6_PIXCEL,  //6像素线LINE_8_PIXCEL,  //8像素线LINE_16_PIXCEL, //16像素线LINE_20_PIXCEL, //20像素线LINE_WITH_CIRCLE,  //珠子连线RUBBER,           //橡皮}SHAPE;/*画刷参数*/
typedef struct
{uint32_t color;SHAPE  shape;}Brush_Style;/*brush全局变量在其它文件有使用到*/
extern Brush_Style brush;void Palette_Init(uint8_t LCD_Mode);
void Touch_Button_Init(void);
void Touch_Button_Down(uint16_t x,uint16_t y);
void Touch_Button_Up(uint16_t x,uint16_t y);
void Draw_Trail(int16_t pre_x,int16_t pre_y,int16_t x,int16_t y,Brush_Style* brush);#endif //_PALETTE_H

palette.c

/********************************************************************************* @file    palette.c* @author  fire* @version V1.0* @date    2015-xx-xx* @brief   触摸画板应用函数******************************************************************************* @attention** 实验平台:野火  STM32  F429 开发板* 论坛    :http://www.firebbs.cn* 淘宝    :https://fire-stm32.taobao.com********************************************************************************/#include "palette.h"
#include "./lcd/bsp_xpt2046_lcd.h"
#include "./lcd/bsp_ili9341_lcd.h"/*按钮结构体数组*/
Touch_Button button[BUTTON_NUM];/*画笔参数*/
Brush_Style brush;static void Draw_Color_Button(void *btn);
static void Draw_Clear_Button(void *btn);
static void Draw_Shape_Button(void *btn);static void Command_Select_Color(void *btn);
static void Command_Select_Brush(void *btn);
static void Command_Clear_Palette(void *btn);static void LCD_DrawUniLineCircle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint8_t thick );/**
* @brief  Palette_Init 画板初始化
* @param  无
* @retval 无
*/
void Palette_Init(uint8_t LCD_Mode)
{uint8_t i;ILI9341_GramScan ( LCD_Mode );/* 整屏清为白色 */LCD_SetBackColor(CL_WHITE);ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);   /* 初始化按钮 */Touch_Button_Init();/* 描绘按钮 */for(i=0;i<BUTTON_NUM;i++){button[i].draw_btn(&button[i]);}/* 初始化画笔 */brush.color = CL_BLACK;brush.shape = LINE_SINGLE_PIXCEL;LCD_SetTextColor(brush.color);}/**
* @brief  Touch_Button_Init 初始化按钮参数
* @param  无
* @retval 无
*/
void Touch_Button_Init(void)
{/*第一列,主要为颜色按钮*/button[0].start_x = BUTTON_START_X;button[0].start_y = 0;button[0].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[0].end_y = COLOR_BLOCK_HEIGHT;button[0].para = CL_BLACK;button[0].touch_flag = 0;  button[0].draw_btn = Draw_Color_Button ;button[0].btn_command = Command_Select_Color ;button[1].start_x = BUTTON_START_X;button[1].start_y = COLOR_BLOCK_HEIGHT;button[1].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[1].end_y = COLOR_BLOCK_HEIGHT*2;button[1].para = CL_GREY;button[1].touch_flag = 0;  button[1].draw_btn = Draw_Color_Button ;button[1].btn_command = Command_Select_Color ;button[2].start_x = BUTTON_START_X;button[2].start_y = COLOR_BLOCK_HEIGHT*2;button[2].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[2].end_y = COLOR_BLOCK_HEIGHT*3;button[2].para = CL_BLUE;button[2].touch_flag = 0;  button[2].draw_btn = Draw_Color_Button ;button[2].btn_command = Command_Select_Color ;button[3].start_x = BUTTON_START_X;button[3].start_y = COLOR_BLOCK_HEIGHT*3;button[3].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[3].end_y = COLOR_BLOCK_HEIGHT*4;button[3].para = CL_CYAN;button[3].touch_flag = 0;  button[3].draw_btn = Draw_Color_Button ;button[3].btn_command = Command_Select_Color ;button[4].start_x = BUTTON_START_X;button[4].start_y = COLOR_BLOCK_HEIGHT*4;button[4].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[4].end_y = COLOR_BLOCK_HEIGHT*5;button[4].para = CL_RED;button[4].touch_flag = 0;  button[4].draw_btn = Draw_Color_Button ;button[4].btn_command = Command_Select_Color ;button[5].start_x = BUTTON_START_X;button[5].start_y = COLOR_BLOCK_HEIGHT*5;button[5].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[5].end_y = COLOR_BLOCK_HEIGHT*6;button[5].para = CL_MAGENTA;button[5].touch_flag = 0;  button[5].draw_btn = Draw_Color_Button ;button[5].btn_command = Command_Select_Color ;button[6].start_x = BUTTON_START_X;button[6].start_y = COLOR_BLOCK_HEIGHT*6;button[6].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[6].end_y = COLOR_BLOCK_HEIGHT*7;button[6].para = CL_GREEN;button[6].touch_flag = 0;  button[6].draw_btn = Draw_Color_Button ;button[6].btn_command = Command_Select_Color ;  button[7].start_x = BUTTON_START_X;button[7].start_y = COLOR_BLOCK_HEIGHT*7;button[7].end_x = BUTTON_START_X+COLOR_BLOCK_WIDTH ;button[7].end_y = LCD_Y_LENGTH;button[7].para = CL_BUTTON_GREY;button[7].touch_flag = 0;  button[7].draw_btn = Draw_Clear_Button ;button[7].btn_command = Command_Clear_Palette ;/*第二列,主要为画刷按钮*/button[8].start_x = BUTTON_START_X + COLOR_BLOCK_WIDTH;button[8].start_y = 0;button[8].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[8].end_y = COLOR_BLOCK_HEIGHT;button[8].para = LINE_SINGLE_PIXCEL;button[8].touch_flag = 0;  button[8].draw_btn = Draw_Shape_Button ;button[8].btn_command = Command_Select_Brush ;button[9].start_x = BUTTON_START_X + COLOR_BLOCK_WIDTH;button[9].start_y = COLOR_BLOCK_HEIGHT;button[9].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[9].end_y = COLOR_BLOCK_HEIGHT*2;button[9].para = LINE_2_PIXCEL;button[9].touch_flag = 0;  button[9].draw_btn = Draw_Shape_Button ;button[9].btn_command = Command_Select_Brush ;button[10].start_x =BUTTON_START_X +  COLOR_BLOCK_WIDTH;button[10].start_y = COLOR_BLOCK_HEIGHT*2;button[10].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[10].end_y = COLOR_BLOCK_HEIGHT*3;button[10].para = LINE_4_PIXCEL;button[10].touch_flag = 0;  button[10].draw_btn = Draw_Shape_Button ;button[10].btn_command = Command_Select_Brush ;button[11].start_x = BUTTON_START_X + COLOR_BLOCK_WIDTH;button[11].start_y = COLOR_BLOCK_HEIGHT*3;button[11].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[11].end_y = COLOR_BLOCK_HEIGHT*4;button[11].para = LINE_6_PIXCEL;button[11].touch_flag = 0;  button[11].draw_btn = Draw_Shape_Button ;button[11].btn_command = Command_Select_Brush ;button[12].start_x = BUTTON_START_X + COLOR_BLOCK_WIDTH;button[12].start_y = COLOR_BLOCK_HEIGHT*4;button[12].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[12].end_y = COLOR_BLOCK_HEIGHT*5;button[12].para = LINE_8_PIXCEL;button[12].touch_flag = 0;  button[12].draw_btn = Draw_Shape_Button ;button[12].btn_command = Command_Select_Brush ;button[13].start_x = BUTTON_START_X + COLOR_BLOCK_WIDTH;button[13].start_y = COLOR_BLOCK_HEIGHT*5;button[13].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[13].end_y = COLOR_BLOCK_HEIGHT*6;button[13].para = LINE_16_PIXCEL;button[13].touch_flag = 0;  button[13].draw_btn = Draw_Shape_Button ;button[13].btn_command = Command_Select_Brush ;button[14].start_x = BUTTON_START_X + COLOR_BLOCK_WIDTH;button[14].start_y = COLOR_BLOCK_HEIGHT*6;button[14].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[14].end_y = COLOR_BLOCK_HEIGHT*7;button[14].para = LINE_20_PIXCEL;button[14].touch_flag = 0;  button[14].draw_btn = Draw_Shape_Button ;button[14].btn_command = Command_Select_Brush ;    button[15].start_x = BUTTON_START_X + COLOR_BLOCK_WIDTH;button[15].start_y = COLOR_BLOCK_HEIGHT*7;button[15].end_x = BUTTON_START_X + COLOR_BLOCK_WIDTH*2 ;button[15].end_y = LCD_Y_LENGTH;button[15].para = RUBBER;button[15].touch_flag = 0;  button[15].draw_btn = Draw_Shape_Button ;button[15].btn_command = Command_Select_Brush ;
}/**
* @brief  Touch_Button_Down 按键被按下时调用的函数,由触摸屏调用
* @param  x 触摸位置的x坐标
* @param  y 触摸位置的y坐标
* @retval 无
*/
void Touch_Button_Down(uint16_t x,uint16_t y)
{uint8_t i;for(i=0;i<BUTTON_NUM;i++){/* 触摸到了按钮 */if(x<=button[i].end_x && y<=button[i].end_y && y>=button[i].start_y && x>=button[i].start_x ){if(button[i].touch_flag == 0)     /*原本的状态为没有按下,则更新状态*/{button[i].touch_flag = 1;         /* 记录按下标志 */button[i].draw_btn(&button[i]);  /*重绘按钮*/}        }else if(button[i].touch_flag == 1) /* 触摸移出了按键的范围且之前有按下按钮 */{button[i].touch_flag = 0;         /* 清除按下标志,判断为误操作*/button[i].draw_btn(&button[i]);   /*重绘按钮*/}}}/**
* @brief  Touch_Button_Up 按键被释放时调用的函数,由触摸屏调用
* @param  x 触摸最后释放时的x坐标
* @param  y 触摸最后释放时的y坐标
* @retval 无
*/
void Touch_Button_Up(uint16_t x,uint16_t y)
{uint8_t i; for(i=0;i<BUTTON_NUM;i++){/* 触笔在按钮区域释放 */if((x<button[i].end_x && x>button[i].start_x && y<button[i].end_y && y>button[i].start_y)){        button[i].touch_flag = 0;       /*释放触摸标志*/button[i].draw_btn(&button[i]); /*重绘按钮*/        button[i].btn_command(&button[i]);  /*执行按键的功能命令*/break;}}  }/**
* @brief  Draw_Trail 在画板区域描绘触摸轨迹
* @param  pre_x 上一点的x坐标
* @param  pre_y 上一点的y坐标
* @param  x     最新一点的x坐标
* @param  y     最新一点的y坐标
* @param  brush 画刷参数
* @retval 无
*/
void Draw_Trail(int16_t pre_x,int16_t pre_y,int16_t x,int16_t y,Brush_Style* brush)
{/*设置画板区域为活动窗口,bsp_lcd.c驱动还没有这样的函数,用于限制绘画窗口*/
//  RA8875_SetActiveWindow(PALETTE_START_X,PALETTE_START_Y,PALETTE_END_X,PALETTE_END_Y);/*触摸位置在画板区域*/if(x>PALETTE_START_X && pre_x>PALETTE_START_X ){switch(brush->shape)  /*根据画刷参数描绘不同的轨迹*/{/* 描绘1像素宽度的轨迹线 */case LINE_SINGLE_PIXCEL:                 if(pre_x< 0 || pre_y < 0) //新的笔迹{      ILI9341_SetPointPixel(x,y);              }else //继续上一次的笔迹{      ILI9341_DrawLine(pre_x,pre_y,x,y);} break;case LINE_2_PIXCEL:if(x-1<PALETTE_START_X||pre_x-1<PALETTE_START_X)    //画板左边界break;/* 描绘2像素宽度的轨迹线 */LCD_DrawUniLineCircle(pre_x,pre_y,x,y,1);break;case LINE_4_PIXCEL:if(x-2<PALETTE_START_X||pre_x-2<PALETTE_START_X)  //画板左边界break;LCD_DrawUniLineCircle(pre_x,pre_y,x,y,2);break;case LINE_6_PIXCEL:if(x-3<PALETTE_START_X||pre_x-3<PALETTE_START_X)   //画板左边界break;LCD_DrawUniLineCircle(pre_x,pre_y,x,y,3);break;case LINE_8_PIXCEL:if(x-4<PALETTE_START_X||pre_x-4<PALETTE_START_X)   //画板左边界break;LCD_DrawUniLineCircle(pre_x,pre_y,x,y,4);break;case LINE_16_PIXCEL:if(x-8<PALETTE_START_X||pre_x-8<PALETTE_START_X)  //画板左边界break;LCD_DrawUniLineCircle(pre_x,pre_y,x,y,8);break;case LINE_20_PIXCEL:if(x-10<PALETTE_START_X ||pre_x-10<PALETTE_START_X)   //画板左边界break;LCD_DrawUniLineCircle(pre_x,pre_y,x,y,10);break;/*描绘带珠子的单像素线*/case LINE_WITH_CIRCLE:  if(x-3<PALETTE_START_X||pre_x-3<PALETTE_START_X)   //画板左边界break;           if(pre_x< 0 || pre_y< 0)//新的笔迹{      ILI9341_SetPointPixel(x,y); }else //继续上一次的笔迹{      ILI9341_DrawLine(pre_x,pre_y,x,y);ILI9341_DrawCircle(x,y,3,1);} break;/*橡皮功能*/            case RUBBER:if(x-20<PALETTE_START_X ||                       //画板左边界x+20>LCD_X_LENGTH || x-20<0 || //液晶左右边界y+20>LCD_Y_LENGTH || y-20<0)     //液晶上下边界               break;  //        if(x>PALETTE_START_X+20){LCD_SetColors(CL_WHITE,CL_WHITE);ILI9341_DrawRectangle( x-40/2,y-40/2,40,40,1);   }break;}}/*退出局限画板的绘图窗口,bsp_lcd.c驱动还没有这样的函数,用于限制绘画窗口*/
//  RA8875_SetActiveWindow(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);}/**
* @brief  Draw_Color_Button 颜色按钮的描绘函数
* @param  btn Touch_Button 类型的按键参数
* @retval 无
*/
static void Draw_Color_Button(void *btn)
{Touch_Button *ptr = (Touch_Button *)btn;/*释放按键*/if(ptr->touch_flag == 0){/*背景为功能键相应的颜色*/LCD_SetColors(ptr->para,CL_WHITE);ILI9341_DrawRectangle(  ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,1);}else  /*按键按下*/{/*白色背景*/LCD_SetColors(CL_WHITE,CL_WHITE);ILI9341_DrawRectangle(  ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,1);} /*按钮边框*/LCD_SetColors(CL_BLUE4,CL_WHITE);ILI9341_DrawRectangle(    ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,0);}/**
* @brief  Draw_Clear_Button 清屏按钮的描绘函数
* @param  btn Touch_Button 类型的按键参数
* @retval 无
*/
static void Draw_Clear_Button(void *btn)
{Touch_Button *ptr = (Touch_Button *)btn;/*释放按键*/if(ptr->touch_flag == 0){LCD_SetColors(CL_BUTTON_GREY,CL_WHITE);ILI9341_DrawRectangle(   ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,1);LCD_SetColors(CL_RED,CL_BUTTON_GREY);/*选择字体,使用中英文显示时,尽量把英文选择成8*16的字体,*中文字体大小是16*16的,需要其它字体请自行制作字模*//*这个函数只对英文字体起作用*/LCD_SetFont(&Font8x16);ILI9341_DispString_EN_CH( ptr->start_x + (ptr->end_x - ptr->start_x - 16*2 )/2,
//                                                              ptr->start_y+15,ptr->start_y+ ((ptr->end_y - ptr->start_y-16)/2), "清屏");}else  /*按键按下*/{LCD_SetColors(CL_WHITE,CL_WHITE);ILI9341_DrawRectangle(ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,1);LCD_SetColors(CL_RED,CL_WHITE);/*选择字体,使用中英文显示时,尽量把英文选择成8*16的字体,*中文字体大小是16*16的,需要其它字体请自行制作字模*//*这个函数只对英文字体起作用*/LCD_SetFont(&Font8x16);ILI9341_DispString_EN_CH( ptr->start_x + (ptr->end_x - ptr->start_x - 16*2 )/2,
//                                                              ptr->start_y+15,               ptr->start_y+ ((ptr->end_y - ptr->start_y-16)/2),  "清屏");} /*按钮边框*/LCD_SetColors(CL_BLUE4,CL_WHITE);ILI9341_DrawRectangle(ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,0);}/**
* @brief  Draw_Shape_Button 笔刷按钮的描绘函数
* @param  btn Touch_Button 类型的按键参数
* @retval 无
*/
static void Draw_Shape_Button(void *btn)
{Touch_Button *ptr = (Touch_Button *)btn;uint16_t i;/* 背景颜色 没按下时为灰色,按下时为白色*/                  if(ptr->touch_flag ==0 ){LCD_SetColors(CL_BUTTON_GREY,CL_WHITE);ILI9341_DrawRectangle(   ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,1);/*显示文字时的背景颜色*/     LCD_SetColors(CL_BLUE4,CL_BUTTON_GREY);ILI9341_DrawRectangle( ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,0);}else{LCD_SetColors(CL_WHITE,CL_WHITE);ILI9341_DrawRectangle(    ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,1);/*显示文字时的背景颜色*/     LCD_SetColors(CL_BLUE4,CL_WHITE);ILI9341_DrawRectangle(   ptr->start_x,ptr->start_y,ptr->end_x - ptr->start_x,ptr->end_y - ptr->start_y,0);}LCD_SetColors(CL_BLACK,CL_WHITE);   /*根据画刷形状描绘按钮图案*/switch(ptr->para){case LINE_SINGLE_PIXCEL:      LCD_SetColors(CL_BLACK,CL_WHITE);ILI9341_DrawLine(ptr->start_x+20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-20,ptr->start_y+(ptr->end_y-ptr->start_y)/2);break;   case LINE_2_PIXCEL:LCD_DrawUniLineCircle(ptr->start_x+20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,1);break;case LINE_4_PIXCEL:LCD_DrawUniLineCircle(ptr->start_x+20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,2);break;case LINE_6_PIXCEL:LCD_DrawUniLineCircle(ptr->start_x+20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,3);break;case LINE_8_PIXCEL:LCD_DrawUniLineCircle(ptr->start_x+20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,4);break;case LINE_16_PIXCEL:LCD_DrawUniLineCircle(ptr->start_x+20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,8 );break;case LINE_20_PIXCEL:LCD_DrawUniLineCircle(ptr->start_x+20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-20,ptr->start_y+(ptr->end_y-ptr->start_y)/2,10);break;case LINE_WITH_CIRCLE: LCD_SetColors(CL_BLACK,CL_WHITE);      ILI9341_DrawLine(ptr->start_x+5,ptr->start_y+(ptr->end_y-ptr->start_y)/2,ptr->end_x-5,ptr->start_y+(ptr->end_y-ptr->start_y)/2);for(i=0;i<((ptr->end_x - ptr->start_x-10)/10);i++){ILI9341_DrawCircle( ptr->start_x+5+i*10,ptr->start_y+(ptr->end_y-ptr->start_y)/2,3,1);}break;case RUBBER:LCD_SetColors(CL_WHITE,CL_BLACK);ILI9341_DrawRectangle(     ptr->start_x+((ptr->end_x - ptr->start_x -24)/2),ptr->start_y+ ((ptr->end_y - ptr->start_y-24 -16)/2),24,24,1 );   LCD_SetColors(CL_RED,CL_BUTTON_GREY);    /*选择字体,使用中英文显示时,尽量把英文选择成8*16的字体,*中文字体大小是24*24的,需要其它字体请自行制作字模*//*这个函数只对英文字体起作用*/LCD_SetFont(&Font8x16);ILI9341_DispString_EN_CH( ptr->start_x+(ptr->end_x - ptr->start_x -16*2)/2,ptr->start_y+ ((ptr->end_y - ptr->start_y-24 -16)/2)+24,      "橡皮");break;}}/**
* @brief  Command_Select_Color 切换画刷颜色,颜色按键的功能执行函数
* @param  btn Touch_Button 类型的按键参数
* @retval 无
*/
static void Command_Select_Color(void *btn)
{Touch_Button *ptr = (Touch_Button *)btn;brush.color = ptr->para;  LCD_SetColors(brush.color,CL_WHITE);if(brush.shape == RUBBER){brush.shape = LINE_SINGLE_PIXCEL;}}/**
* @brief  Command_Select_Brush 切换画刷颜色,画刷按键的功能执行函数
* @param  btn Touch_Button 类型的按键参数
* @retval 无
*/
static void Command_Select_Brush(void *btn)
{Touch_Button *ptr = (Touch_Button *)btn;brush.shape =(SHAPE) ptr->para;LCD_SetColors(brush.color,CL_WHITE);
}/**
* @brief  Command_Select_Brush 切换画刷颜色,清屏按键的功能执行函数
* @param  btn Touch_Button 类型的按键参数
* @retval 无
*/
static void Command_Clear_Palette(void *btn)
{LCD_SetColors(CL_WHITE,CL_WHITE);ILI9341_DrawRectangle(    PALETTE_START_X,PALETTE_START_Y,                    PALETTE_END_X-(PALETTE_START_X+1), PALETTE_END_Y-PALETTE_START_Y ,1);}#define ABS(X)  ((X) > 0 ? (X) : -(X))/*** @brief  在两点之间描绘轨迹* @param  x1: specifies the point 1 x position.* @param  y1: specifies the point 1 y position.* @param  x2: specifies the point 2 x position.* @param  y2: specifies the point 2 y position.* @retval None*/
static void LCD_DrawUniLineCircle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint8_t thick )
{int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, curpixel = 0;deltax = ABS(x2 - x1);        /* The difference between the x's */deltay = ABS(y2 - y1);        /* The difference between the y's */x = x1;                       /* Start x off at the first pixel */y = y1;                       /* Start y off at the first pixel */if (x2 >= x1)                 /* The x-values are increasing */{xinc1 = 1;xinc2 = 1;}else                          /* The x-values are decreasing */{xinc1 = -1;xinc2 = -1;}if (y2 >= y1)                 /* The y-values are increasing */{yinc1 = 1;yinc2 = 1;}else                          /* The y-values are decreasing */{yinc1 = -1;yinc2 = -1;}if (deltax >= deltay)         /* There is at least one x-value for every y-value */{xinc1 = 0;                  /* Don't change the x when numerator >= denominator */yinc2 = 0;                  /* Don't change the y for every iteration */den = deltax;num = deltax / 2;numadd = deltay;numpixels = deltax;         /* There are more x-values than y-values */}else                          /* There is at least one y-value for every x-value */{xinc2 = 0;                  /* Don't change the x for every iteration */yinc1 = 0;                  /* Don't change the y when numerator >= denominator */den = deltay;num = deltay / 2;numadd = deltax;numpixels = deltay;         /* There are more y-values than x-values */}for (curpixel = 0; curpixel <= numpixels; curpixel++){//判断边界if(x+thick>LCD_X_LENGTH || x-thick<0 || //液晶左右边界y+thick>LCD_Y_LENGTH || y-thick<0  ) //液晶上下边界continue;ILI9341_DrawCircle(x,y,thick,1);             /* Draw the current pixel */num += numadd;              /* Increase the numerator by the top of the fraction */if (num >= den)             /* Check if numerator >= denominator */{num -= den;               /* Calculate the new numerator value */x += xinc1;               /* Change the x as appropriate */y += yinc1;               /* Change the y as appropriate */}x += xinc2;                 /* Change the x as appropriate */y += yinc2;                 /* Change the y as appropriate */}
}/* ------------------------------------------end of file---------------------------------------- */

**

其他配置:

**

第 29 章 电阻触摸屏—触摸画板相关推荐

  1. 普通电阻触摸屏多点触摸低成本解决方 转载

    苹果公司iPhone的成功将多点触摸技术推到了一个前所未有的高度,经典的弹钢琴应用程序可以支持超过5点的同时触摸,虽然这一性能并不见得有太多的实用价值,但绝对带给了用户技术无限领先的震撼感.苹果公司的 ...

  2. 【正点原子FPGA连载】第三十四章RGB-LCD触摸屏实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

  3. 禾瑞亚USB接口电阻触摸屏控制卡QNX 6.5 RTOS操作系统x86架构驱动安装与配置方法

    禾瑞亚USB接口电阻触摸屏控制卡QNX 6.5 RTOS操作系统x86架构驱动安装与配置方法 前提条件:安装QNX 6.5 RTOS操作系统的主板的USB接口必须能够被操作系统识别,否则连接不到触摸屏 ...

  4. 电阻触摸屏和电容触摸屏的工作原理及优缺点

    随着科技的发展使用需求的增长,触摸屏行业经历了从低档到高档逐步升级的过程,触摸技术已渗透到各行各业中.按照工作原理可以分为电阻触摸屏和电容触摸屏两大类.下面沐渥小编从二者的工作原理和优缺点出发,教大家 ...

  5. RK3288 10.1寸电阻触摸屏调试与校准软件的运行

    作者:Dennis 电话:13349909990(微信同号) 邮箱:dennis@we-signage.com 说明:本文所提供的技术方案适用于 恒耀源科技有限公司 RK3288主板以及使用该主板的所 ...

  6. tsc2007电阻触摸屏调试

    #触摸屏调试 开发环境:ubuntu12.04LTS Android核心板型号:Samsung6818 电阻触摸屏型号:tsc2007 作者:@happyguy96 && @ccxx0 ...

  7. openharmony移植之编写电阻触摸屏驱动

    之前有写过一篇关于Gt911触摸的文章,今天写一篇关于如何在openharmony上调试电阻屏触摸驱动, 首先需要修改如下两个文件,将我们的驱动文件加入驱动编译框架中, diff --git a/dr ...

  8. 【手拉手 带你准备电赛】原来你是这样的触摸屏(电阻触摸屏)

    在我们的生活中,触摸屏可以说是无处不在.在各种触控面板我们都可以看到触摸屏的身影,一些产品也因为有了触摸屏而价值大涨.接下来,小蛋糕带你深入了解触摸屏. 触摸屏可以分为电阻式触摸屏和电容式触摸屏,在这 ...

  9. 1.9.3_ADC和触摸屏_电阻触摸屏硬件原理_P

    如上图示,假设有一个长度为L的电阻,一端接地,另一端接3.3v,如果这个电阻的阻值是均匀分布的,那么根据欧姆定律,电阻某一位置x的电压值就与电阻的长度就会有一个关系式,我们就可以根据这一点的电压推导出 ...

  10. 嵌入式单片机高级篇(二)Stm32F103电阻触摸屏

    Stm32F103电阻触摸屏 1.原理: lcd屏与触摸屏中间有支撑点将两层导电涂料隔开,当某点按下时,使得两层涂料接触,平常绝缘的两层导电层在触摸点位置就有了一个接触,控制器侦测到这个接通后,其中一 ...

最新文章

  1. JFET直耦级联放大电路:MPF102,2SK102
  2. 牛客网 New Game! 建图+最短路
  3. LUA 拾遗(编译-调试-运行)
  4. 《AlwaysRun!团队》第四次作业:项目需求调研与分析
  5. anaconda更新python版本mac_macos - 如何使用conda升级到Python 3.6?
  6. 如何减小与“大牛”的差距
  7. 教育部:麻省理工学院2019年本科生未招收一名中国大陆的学生不属实
  8. CVPR 2021 机器学习及多模态最新进展分享
  9. 数据结构 之 图的存储和遍历
  10. SAP License:再论分摊与分配(含实例)
  11. 012 注解式异常处理器
  12. windows命令总结
  13. 正定矩阵(positive definite matrix)
  14. 免费python自学攻略-给初学者推荐的10个Python免费学习网站!赶紧收藏吧!
  15. 《Windows编程循序渐进》——对话框应用程序
  16. 算法题在我看来都是小意思
  17. java聊天室类图怎么画,UML课程设计(java web网上聊天室附源码)
  18. CentOS 7校准时间–NTP
  19. 移动通信电磁辐射(转)
  20. 浏览美国大学最新排名以便确立目标 备战雅思助力目标达成

热门文章

  1. 将两块球形橡皮泥揉在一起,捏成一个正方体。请编程,完成下述功能:从键盘读入2个球形橡皮泥的直径,直径为浮点数;求正方体的边长,并保留两位小数输出;
  2. P1713 麦当劳叔叔的难题(90分)
  3. 记忆的分类及其理论模型
  4. 巴斯大学计算机科学研究生,巴斯大学计算机科学.pdf
  5. 我的团长我的团分集剧情介绍
  6. 合作动态 | 方正璞华与日立签订战略合作协议,加快推进数字化管理变革!
  7. PHP accesstoken失效,微信开发-ACCESS TOKEN 过期失效解决方案
  8. echarts常见图形-横向柱状图(六)
  9. linux如何安装压缩软件,linux之安装软件,压缩解压文件
  10. 数据库作业8:SQL练习5 - SELECT(嵌套查询EXISTS、集合查询、基于派生表的查询)