D2-补充

1.外设驱动配置上

时钟&SWD

原理图分析

时钟

如下图所示,STM32F407外部高速晶振为25MHz,分别连接到PH0和PH1引脚!
1562578337016

SWD

如下图所示,STM32F407仿真接口SWD分别连接到PA13和PA14引脚!
1562578482088

外设配置

时钟
使能时钟源
  1. 选择RCC外设
  2. 选择高速时钟为外部时钟源
  3. PH0和PH1引脚自动高亮
    1562578912784
配置时钟树
  1. 锁相环时钟源为25MHz外部高速时钟
  2. 高速时钟分频系数配置为25,输出为1MHz
  3. 倍频系数配置为336
  4. 分频系数配置为2,输出为168MHz
  5. 系统时钟源选择PLL
  6. APB1配置为4分频,为42MHz
  7. APB2配置为2分频,为84MHz

1562579325226

SWD
  1. 选择SYS外设
  2. 配置debug接口为串行接口(SWD)
  3. 引脚自动高亮

1562578754437

串口

原理图分析

Zigbee通信接口

如下图所示:

  1. J28为Zigbee模块底座,其中Z_W_R和Z_W_T分别Zigbee串行通信接口
  2. Z_W_R和Z_W_T网络连接到J13,通过J13选择连接STM32还是USB转串口,我们选择连接到STM32上的USART1(PA9和PA10)

1562640598942

1562641360910

串口调试接口

如下图所示:

  1. 板载两个串行通信接口,串口1连接到USART1,串口2连接到USART3,我们选择USART3
  2. 由于USART3可以用于串口和485通信,我们选择485必须要把CON4和CON5拨到串口通信

1562641462004

外设配置

USART1
  1. 配置PA9和PA10为USART1模式
  2. 打开USART1,配置为异步通信模式

1562643378054

USART2
  1. 配置PB10和PB11为USART3模式
  2. 打开USART3外设,并配置为异步通信模式

1562643719006

FSMC配置

SRAM

原理图分析

通过下图所示:

  1. 采用IS61LV51216 SRM 为1MB,其实为了节约成本焊接的为IS61LV25616 为512KB
  2. 占用地址总线为18bit,数据总线为16bit
  3. 内存访问起始地址为0x6800 0000

1562742102105

外设配置
  1. 打开FSMC外设
  2. 配置FSMC
    1. 选择存储块为NE3
    2. 内存类型为SRAM
    3. 寻址长度为18bit
    4. 数据宽度为16bit
  3. 配置FSMC时序
    1. 地址建立时间为1分频
    2. 数据建立时间为3分频
  4. 字节访问使能

1562740191489

1562654016221

1563502897107

LCD

原理图分析
  1. 如下图所示,LCD采用8080接口,CS片选,D/C命令/数据切换,RD读操作,WR写操作,D[23:0]数据总线
1562742456453
  1. 如下图所示,数据总线D[0:15]连接FSMC总线接口处,RS起始就D/C接口,连接到FSMC地址总线A0,CS片选总线连接到FSMC_NE4上,WR写操作连接FSMC_NWE总线上,RD读操作总线连接到FSMC_NOE上,背光控制连接到PC7上
1562742309831
  1. 写命令操作0x6C00 0000
  2. 写数据操作0x6C00 0002
外设配置
  1. 打开FSMC外设
  2. 配置FSMC参数
    1. 内存块为NE4
    2. 内存类型为LCD
    3. LCD数据/命令切换映射到A0
    4. 数据宽度为16bit
1562743085030
  1. 分析LCD驱动芯片时序图,计算得出地址和数据总线建立时间

1562742041324

  1. 配置PC7为输出模式
  2. 上电默认输出高电平
    1562745024538

2.外设驱动配置下

SPI配置

原理图分析

  1. 如下图所示,SPI接口,CS连接到PG15,MISO连接到PI2,MOSI连接到PI3,SCK连接到PI1
  2. 触摸中断连接到PG7

1562745240947

数据手册分析

  1. 通过计算TCH+TCL得出SPI通信速率
  2. 通过时序图分析,SPI不工作时为低电平

1562746030060

  1. 时钟边沿为奇数边沿
  2. 通信速率最小为400ns,大概2Mbit/S左右

1562746203926

外设配置

  1. 配置SPI时钟和数据引脚
  2. 配置SPI为全双工主机模式
  3. 配置SPI参数
    1. 通信速率为系统时钟32分频
    2. 时钟极性为低电平
    3. 相位为奇数边沿

1562746405628

  1. 配置SPI片选引脚
    1. 配置PG15为输出模式
    2. 配置PG15上电默认输出高,SPI低电平有效

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GPIO配置

原理图分析

  1. 如下图所示
    1. PF7 PF8 PF9 P10 控制板载的D6 D7 D8 D9
    2. PF6控制板载蜂鸣器

1562747716702

外设配置

  1. 配置PF6-PF10为输出模式
  2. PF6默认输出低
  3. PF7-PF10默认输出高

1562748180760

SDIO配置

原理图分析

根据原理图分析,我们采用SD总线,4bit

1562749863814

外设配置

  1. 打开SDIO外设
  2. 配置SD总线为4bit位宽
  3. 配置DMA接收和发送

sdio配置

  1. 使能sdio全局中断

sdio中断配置

ETHERNET配置

原理图分析

  1. 如下图所示,以太网PHY采用DP83848芯片,通信模式采用RMII接口

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外设配置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.FreeRTOS配置及使用

##配置内核定时器
由于我们采用STM32HAL库进行开发,HAL库内部使用systick定时器用于系统延时功能,而FreeRTOS也需要一个定时器用于操作系统内核调度使用, 顾需要修改HAL定时器时钟源

  1. 打开SYS选项
  2. 配置时钟源为TIM1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

配置FreeRTOS内核功能

  • 多数功能在后续程序设计中,需要根据具体功能,进行配置
  • 前期只需要配置动态内存空间和创建开始任务就可以

配置动态内存分配空间

  1. 采用FreeRTOS动态内存分配,开发效率高!顾我们程序内存使用,多数使用动态内存分配方式,分配动态内存总空间为23k=23552byte
    2. 使能FreeRTOS功能
    3. 分配内存空间为40960

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建开始任务

STM32cubemx默认已经创建了一个任务,只需要简单修改一下即可。

  1. 打开任务和消息队列选型卡
  2. 双击系统默认任务
  3. 配置任务名称和任务函数名称(保证其不一样)

1563157727469

上电打印启动信息

配置工程信息
  1. 配置工程名称为SmartClassRomm
  2. 配置生成keil5工程

1563159638397
3. 单独为每个外设生成.c和.h文件
1563159894796

####生成keil工程

1563160234235

printf重定向
  1. 在main.c文件内添加fputc函数,采用USART3作为调试接口
int fputc(int ch, FILE *f)
{
    while((USART3->SR & 0X40)==0);
    USART3->DR = (uint8_t) ch;
    return ch;
}
  1. 在freertos.c文件内,Start_Task打印启动信息
/* USER CODE END Header_Start_Task */
void Start_Task(void const * argument)
{

  /* USER CODE BEGIN Start_Task */
   printf("start is runing!\r\n");
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END Start_Task */
}

4.LwIP配置及使用

LwIP配置

LwIP使用,只需要把以太网链路检测功能开启即可,其他后续再添加

  1. 使能LwIP组件
  2. 分配10k内存空间
  3. 使能链路检测回调功能

1566897062225

获取DHCP分配的IP地址

  1. 在lwip.c添加代码
void LwIPTask(void){
	
	struct dhcp *dhcp;
	//等待DHCP获取IP成功
	while(!(dhcp_supplied_address(&gnetif))){
		
		vTaskDelay(200);
	
	}
	  //打印获取到的IP地址
	  printf("GET IP address\n");
	  dhcp = netif_dhcp_data(&gnetif);
      printf("IP address: %s\n", ip4addr_ntoa(&dhcp->offered_ip_addr));
      printf("Subnet mask: %s\n", ip4addr_ntoa(&dhcp->offered_sn_mask));
      printf("Default gateway: %s\n", ip4addr_ntoa(&dhcp->offered_gw_addr));
	  for(;;){
	  
		vTaskDelay(100);
	  }


}
  1. 在lwip.h添加代码
/* USER CODE BEGIN 0 */
void LwIPTask(void);
/* USER CODE END 0 */
  1. 在freertos.c修改代码
#include "lwip.h"
void LwIP_Task(void const * argument)
{
  /* USER CODE BEGIN LwIP_Task */
  /* Infinite loop */
	LwIPTask();
  /* USER CODE END LwIP_Task */
}

链路检测处理

  1. 在lwip.c添加代码
/**
  * @brief  This function notify user about link status changement.
  * @param  netif: the network interface
  * @retval None
  */
__weak void ethernetif_notify_conn_changed(struct netif *netif)
{
  /* NOTE : This is function could be implemented in user file 
            when the callback is needed,
  */
	
	if(netif_is_link_up(netif)){
		
		printf("netif link is up\r\n");
		if(!netif_is_up(netif)){
			netif_set_up(netif);
			printf("netif is up\r\n");
		}
	}else{
		printf("netif link is down\r\n");
		
	}

}
/* USER CODE END 8 */ 

功能测试

检查DHCP是否获取到IP

  1. 设备上电
  2. 等待打印获取到的IP地址,如下图所示

1563178961575
3. ping设备信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以太网断线检测

两种情况,一种是设备通电时断开网线,一种是网线没插,设备通电

  • 第一种,只需要在获取到IP地址后, 断开网线之后再插入,通过ping命令进行检测
  • 第二种,断开网线设备通电,之后再插入网线

1563179561090

5.FatFS配置及使用

FatFS配置

  1. 打开FatFS
  2. 使能磁盘为SD卡
  3. 配置中文编码
  4. 配置命名空间为HEAP
  5. 增大C库堆空间

FatFS代码分析

FATFS模块fatfs中间件模块架构

  • 文件访问
    f_open - 打开/创建文件
    f_close - 关闭一个打开的文件
    f_read - 读取数据
    f_write - 写入数据
    f_lseek - 移动读/写指针,扩展大小
    f_truncate - 截断大小
    f_sync - 刷新缓存的数据
    f_forward - 将数据转发到流
    f_expand - 为文件分配一个连续的块
    f_gets - 读取一个字符串
    f_putc - 写一个字符
    f_puts - 写一个字符串
    f_printf - 写一个格式化的字符串
    f_tell - 获取当前的读/写指针
    f_eof - 测试文件结尾
    f_size - 获取大小
    f_error - 测试错误
  • 目录访问
    f_opendir - 打开目录
    f_closedir - 关闭一个打开的目录
    f_readdir - 读取目录项
    f_findfirst - 打开一个目录并读取匹配的第一个项目
    f_findnext - 读取下一个匹配的项目
  • 文件/目录管理
    f_stat - 检查文件或子目录的存在
    f_unlink - 删除文件或子目录
    f_rename - 重命名或移动文件或子目录
    f_chmod - 更改文件或子目录的属性
    f_utime - 更改文件或子目录的时间戳
    f_mkdir - 创建子目录
    f_chdir - 更改当前目录
    f_chdrive - 更改当前驱动器
    f_getcwd - 检索当前目录和驱动器
  • 卷管理
    f_mount - 注册/取消注册卷的工作区
    f_mkfs - 在逻辑驱动器上创建FAT卷
    f_fdisk - 在物理驱动器上创建逻辑驱动器
    f_getfree - 获取卷上的总大小和可用大小
    f_getlabel - 获取卷标
    f_setlabel - 设置卷标

BSP底层磁盘IO驱动

disk_status - 获取设备状态
disk_initialize - 初始化设备
disk_read - 读取扇区
disk_write - 写扇区
disk_ioctl - 控制设备相关的功能
get_fattime - 获取当前时间

通用底层驱动接口

typedef struct
{
  DSTATUS (*disk_initialize) (BYTE);// 初始化设备
  DSTATUS (*disk_status)     (BYTE); // 获取设备状态
  DRESULT (*disk_read)       (BYTE, BYTE*, DWORD, UINT);    //读取扇区   
#if _USE_WRITE == 1
  DRESULT (*disk_write)      (BYTE, const BYTE*, DWORD, UINT); //写扇区
#endif 
#if _USE_IOCTL == 1
  DRESULT (*disk_ioctl)      (BYTE, BYTE, void*);    //控制设备相关的功能           

}Diskio_drvTypeDef;


typedef struct
{
  uint8_t                 is_initialized[_VOLUMES];	//设备装在状态
  const Diskio_drvTypeDef *drv[_VOLUMES];	//设备驱动结构体
  uint8_t                 lun[_VOLUMES];
  volatile uint8_t        nbr;			//目前驱动的数量

}Disk_drvTypeDef;

BSP驱动层分析

uint8_t BSP_SD_Init(void);
uint8_t BSP_SD_ITConfig(void);
void    BSP_SD_DetectIT(void);
void    BSP_SD_DetectCallback(void);
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
void BSP_SD_IRQHandler(void);
void BSP_SD_DMA_Tx_IRQHandler(void);
void BSP_SD_DMA_Rx_IRQHandler(void);
uint8_t BSP_SD_GetCardState(void);
void    BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo);
uint8_t BSP_SD_IsDetected(void);
void    BSP_SD_AbortCallback(void);
void    BSP_SD_WriteCpltCallback(void);
void    BSP_SD_ReadCpltCallback(void);

#Fatfs使用

uint8_t u8chr[] = "hello";
uint32_t u32Wbytes;

/* USER CODE END Variables */    

void MX_FATFS_Init(void) 
{
  /*## FatFS: Link the SD driver ###########################*/
  retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
  
  

  /* USER CODE BEGIN Init */
  
  if(f_mount(&SDFatFS,SDPath,1) == FR_OK)
  {
    if(f_open(&SDFile,(const char*)"fatfs.txt",FA_CREATE_ALWAYS|FA_WRITE) == FR_OK)
    {
      if(f_write(&SDFile,u8chr,sizeof(u8chr),&u32Wbytes) == FR_OK)
      {
        f_close(&SDFile);
      
      }
    
    }
  
  }
  FATFS_UnLinkDriver(SDPath);
  
  
  /* additional user code for init */     
  /* USER CODE END Init */
}

6.STemWin文件移植

获取STemWin源码文件

STemWin默认在STM32CUBEMX文档下

例如C:\Users\Think\STM32Cube\Repository\STM32Cube_FW_F4_V1.23.0\Middlewares\ST\STemWin

1563775931077

STemWin移植到项目工程

  1. 复制STemWin源码到项目工程中
    工程目录:SmartClassRoom\Middlewares\Third_Party\STemWin

  2. 在keil工程中添加相关文件

    1. 新建工作组:Middlewares/STemWin
      1563776148286
    2. 添加需要编译的C和库文件

    1563776310004

文件名称文件描述
GUI_X_OS.cOS支持文件,不需要修改
GUIConf.cGUI配置文件,主要用于GUI内存块初始化
GUIDRV_Template.cGUI驱动模块,主要针对LCD操作接口
LCDConf_FlexColor_Template.cGUI显示配置文件,主要用于LCD参数配置,初始化
GUI_X_Touch_Analog.c需要自己单独定义,用于触摸笔驱动
STemWin_CM4_OS_wc16_ot.a基于Cortex-M4驱动库,STemWin源码不开放
  1. 修改库文件格式(keil默认不识别.a文件格式,需要我们手动配置)

1563777034388

移植lcd和touch驱动文件

  1. 添加lcd.c和Touch.c到Src目录下

1563777431712

  1. 添加lcd.h和Touch.h到Inc目录下
    1563777506163

修改GUIConf.c

#include "GUI.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES    (512*1024)	//定义外部存储器大小
#define GUI_BLOCKSUZE   (0X80)			//定义最小内存库操作大小
#define SRAM_BANK_ADDR  ((U32)0x68000000)	//定义外部存储器首地址

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       GUI_X_Config
*
* Purpose:
*   Called during the initialization process in order to set up the
*   available memory for the GUI.
*/
void GUI_X_Config(void) {
  //
  // 32 bit aligned memory area
  //
	volatile U32* aMemory = (volatile U32*)(SRAM_BANK_ADDR);
  //
  // Assign memory to emWin
  //分配GUI存储器首地址及最小操作内存块大小
  GUI_ALLOC_AssignMemory((void *)aMemory, GUI_NUMBYTES);
  GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSUZE);
  //
  // Set default font
  //
  GUI_SetDefaultFont(GUI_FONT_6X8);
}

修改GUIDRV_Template.c

只需要完成画点和读取点操作即可

/*********************************************************************
*
*       _SetPixelIndex
*
* Purpose:
*   Sets the index of the given pixel. The upper layers
*   calling this routine make sure that the coordinates are in range, so
*   that no check on the parameters needs to be performed.
*/
static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) {
    //
    // Convert logical into physical coordinates (Dep. on LCDConf.h)
    //
    #if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
      int xPhys, yPhys;

      xPhys = LOG2PHYS_X(x, y);
      yPhys = LOG2PHYS_Y(x, y);
    #else
      #define xPhys x
      #define yPhys y
    #endif
    GUI_USE_PARA(pDevice);
    GUI_USE_PARA(x);
    GUI_USE_PARA(y);
    GUI_USE_PARA(PixelIndex);
    {
      //
      // Write into hardware ... Adapt to your system
      //添加lcd画点接口
      LCD_DrawPoint(x,y,PixelIndex);
      // TBD by customer...
      //
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
}
/*********************************************************************
*
*       _GetPixelIndex
*
* Purpose:
*   Returns the index of the given pixel. The upper layers
*   calling this routine make sure that the coordinates are in range, so
*   that no check on the parameters needs to be performed.
*/
static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
  unsigned int PixelIndex;
    //
    // Convert logical into physical coordinates (Dep. on LCDConf.h)
    //
    #if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
      int xPhys, yPhys;

      xPhys = LOG2PHYS_X(x, y);
      yPhys = LOG2PHYS_Y(x, y);
    #else
      #define xPhys x
      #define yPhys y
    #endif
    GUI_USE_PARA(pDevice);
    GUI_USE_PARA(x);
    GUI_USE_PARA(y);
    {
      //
      // Write into hardware ... Adapt to your system
      //添加lcd读取点接口
      PixelIndex = lcd_read_gram(x,y);
      
      // TBD by customer...
      //
      PixelIndex = 0;
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
  return PixelIndex;
}

修改LCDConf_FlexColor_Template.c

  1. 定义显示尺寸 480*272
  2. 定义触摸笔X,Y AD测量值(需要自己测量获得)
  3. 添加触摸笔校准函数
  4. 添加lcd初始化函数

#include "GUI.h"
#include "GUIDRV_FlexColor.h"
#include "lcd.h"

/*********************************************************************
*
*       Layer configuration (to be modified)
*
**********************************************************************
*/

//
// Physical display size
//
#define XSIZE_PHYS  480 //  屏幕X坐标长度
#define YSIZE_PHYS  272 //  屏幕Y坐标长度


#define GUI_TOUCH_AD_Y_TOP 170		// 屏幕X0点坐标AD值
#define GUI_TOUCH_AD_Y_BOTTOM 1900	// 屏幕X480点坐标AD值
#define GUI_TOUCH_AD_X_LEFT 100		// 屏幕Y0点坐标AD值
#define GUI_TOUCH_AD_X_RIGHT 1930	// 屏幕Y272点坐标AD值

/*********************************************************************
*
*       Configuration checking
*
**********************************************************************
*/
#ifndef   VXSIZE_PHYS
  #define VXSIZE_PHYS XSIZE_PHYS
#endif
#ifndef   VYSIZE_PHYS
  #define VYSIZE_PHYS YSIZE_PHYS
#endif
#ifndef   XSIZE_PHYS
  #error Physical X size of display is not defined!
#endif
#ifndef   YSIZE_PHYS
  #error Physical Y size of display is not defined!
#endif
#ifndef   GUICC_565
  #error Color conversion not defined!
#endif
#ifndef   GUIDRV_FLEXCOLOR
  #error No display driver defined!
#endif

/*********************************************************************
*
*       Public functions
*
**********************************************************************
*/
/*********************************************************************
*
*       LCD_X_Config
*
* Function description:
*   Called during the initialization process in order to set up the
*   display driver configuration.
*
*/
void LCD_X_Config(void) {
  //
  // 配置GUI LCD驱动以及颜色显示方式
  //
  GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0);
  //
  // 显示尺寸配置
  //
  LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
  LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
	
  //触摸笔校准
  GUI_TOUCH_Calibrate(GUI_COORD_X, 0, 480, GUI_TOUCH_AD_X_LEFT , GUI_TOUCH_AD_X_RIGHT);
  GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, 272, GUI_TOUCH_AD_Y_TOP, GUI_TOUCH_AD_Y_BOTTOM);
  //
  // Orientation
  //
  //
  // Set controller and operation mode
  //
}

/*********************************************************************
*
*       LCD_X_DisplayDriver
*
* Function description:
*   This function is called by the display driver for several purposes.
*   To support the according task the routine needs to be adapted to
*   the display controller. Please note that the commands marked with
*   'optional' are not cogently required and should only be adapted if
*   the display controller supports these features.
*
* Parameter:
*   LayerIndex - Index of layer to be configured
*   Cmd        - Please refer to the details in the switch statement below
*   pData      - Pointer to a LCD_X_DATA structure
*
* Return Value:
*   < -1 - Error
*     -1 - Command not handled
*      0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
  int r;
  (void) LayerIndex;
  (void) pData;
  
  switch (Cmd) {
  case LCD_X_INITCONTROLLER: {
    //
    // Called during the initialization process in order to set up the
    // display controller and put it into operation. If the display
    // controller is not initialized by any external routine this needs
    // to be adapted by the customer...
    //
    // ...
		//添加lcd初始化
		lcd_init();
    return 0;
  }
  default:
    r = -1;
  }
  return r;
}

添加GUI_X_Touch_Analog.c

#include "GUI.h"
#include "Touch.h"


void GUI_TOUCH_X_ActivateX(void) 
{

}

void GUI_TOUCH_X_ActivateY(void)
{

}

//获取X坐标AD值
int  GUI_TOUCH_X_MeasureX(void) 
{
	return XPT_Read_XY(CMD_RDX);
}

//获取Y坐标AD值
int  GUI_TOUCH_X_MeasureY(void) 
{	
	return XPT_Read_XY(CMD_RDY);
}

创建touch任务

  1. 创建touch任务
  2. 配置任务优先级为正常
  3. 配置栈大小为256

1563779328024

获取触摸笔X,Y坐标 四点AD值

/* USER CODE BEGIN Header_Touch_Task */
/**
* @brief Function implementing the TouchTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Touch_Task */
void Touch_Task(void const * argument)
{
  /* USER CODE BEGIN Touch_Task */
	int x,y;
	GUI_PID_STATE State;
  /* Infinite loop */
  for(;;)
  {
//		获取TOUCH AD值
		x = GUI_TOUCH_X_MeasureX();
		y = GUI_TOUCH_X_MeasureY();
		//显示X坐标信息
		GUI_DispStringAt("X:",0,0);
		GUI_DispDecAt(x,32,0,4);
		//显示Y坐标信息
		GUI_DispStringAt("Y:",0,24);
		GUI_DispDecAt(y,32,24,4);				
		osDelay(10);
	
  }
  /* USER CODE END Touch_Task */
}

测试程序编写


/* USER CODE BEGIN Header_Touch_Task */
/**
* @brief Function implementing the TouchTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Touch_Task */
void Touch_Task(void const * argument)
{
  /* USER CODE BEGIN Touch_Task */
	int x,y;
	GUI_PID_STATE State;
  /* Infinite loop */
  for(;;)
  {			
  		//执行触摸笔检测
		GUI_TOUCH_Exec();	
        //获取触摸笔状态值
		GUI_TOUCH_GetState(&State);
		//是否按下
		if(State.Pressed){
			//打印触摸笔坐标信息
			GUI_DispStringAt("X:",0,0);
			GUI_DispDecAt(State.x,32,0,4);
			GUI_DispStringAt("Y:",0,24);
			GUI_DispDecAt(State.y,32,24,4);			
		}
		osDelay(10);
	
  }
  /* USER CODE END Touch_Task */
}

测试结果

当触摸笔按下时,显示X(0-480)和Y(0-272)坐标信息

微信图片_20190722151531

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值