移植EMWIN STM32F103VET的一些问题(无操作系统

参考资料:正点原子 EMWIN

学习经历
起因:因为贪便宜买了块STM32F103VE的开发板,到货后发现的问题
1.资料不全;导致学习困难度,“挫败度”大大加深;
2.网上查找的资料与板子不对应,对初学者来说困难度变大;
3.视频教程过于庞大,学习过程中若没有动力支持,放弃的可能性很大
参考意见:如果条件允许;1.尽量买资料全(最好有大量资料的,最好是中文的,否则你需要英文能力的支持),技术成熟的,有完整教材的来开始使用;有技术支持,论坛讨论的;所节省下来的时间,往往比所花费的金钱更值得;最好有文档跟视频的;便于快速学习与查找问题
4.代码混乱,无“模块化”,导致无序与混乱;(模块化是一种必然化的需求)

5.版本的差异(固件库),导致不同的版本会有代码上的差异,从而出现错误


学习步骤(学习动力论):
1.实践大于看书,实践比书要简单;前提是你先粗看一遍;
2.初学者,不要去看平台搭建(延后),平台搭建中的大量错误可能挫败积极性;所以第一步先使用已经搭建好的平台,去建立第一个LED灯实验;
3.初学者需要明确目标:所需要的功能;硬件平台中有大量的硬件知识需要学习,知识的前后也有依赖性;导致你找到你希望学习的内容,也必须将前面的知识先学会;如果你没有合理的安排,或是空闲的时间,将导致挫败感;并且前面的依赖性,关联性,导致无法快速学习一个内容的知识(这是需要解决的,但好像没有相应的教材,故学习很累)


单片机对于计算机底层的知识,有利我们更好的理解计算机;现在的个人计算机底层的操作,都已经封装好了,写程序只需要在软件层操作就行;并不需要涉及硬件层,“寄存器”或是“内存映射”等知识(秉火有详细介绍)

基于成本,项目需求等考虑,单片机的种类很多;有带显示屏,触摸的,到ARDUION;有主频1.2G,内存2G的到只有12M,几百KB的;有容易入门到的,如ARDUION简单开发应用的(现已支持STM32,但还不全);到使用ARM处理的LUNUX系统,需要写底层驱动的;需要根据自己的需求进行选择,总体来说STM32的性价比较高,但依现有的资料与技术(注意:STM32一般内存较小,只有几百KB,而外扩也不大,只有几M);学习比较HAO时;如果你使用ARDUION另当别论


学习单片机或嵌入式,一般都是为了对外进行控制操作,使用STM32或是ARM或树莓派,不单单是点LED灯;更希望使用的是他的液晶显示触摸功能;如果是简单的可以自己写就行,如果是比较复杂的,我们自己写也可以,但有现成的更简单的,就是使用EMWIN来完成,只需要几条指令就可以完成;
EMWIN是UCGUI的升级版,不开放源码;源码可以参考UCGUI


EMWIN主要是通过对原来的驱动的调用,来完成更高级的功能,在液晶屏上显示对话框,图片,可以点击操作;他主要通过调用原驱动中的画点,取点函数来隔离化底层的操作,从而使EMWIN更通用化,可以适合更多的平台,开发板

液晶的使用,为了更简便一般使用FMSC接口功能

1.液晶需要按正确的顺序连接开始板
2.开启FMSC功能
3.驱动的编写(你得查看相应的资料DATASHEET,或是厂家已编好的驱动,移植即可)

STM32的使用的主要步骤:

1.开启时钟:
2.设置功能:
3.控制

开启时钟:(他是为了节能而设置的,如可穿戴调备,使用锂电池,导致多了条语句也导致繁琐度增加; 
设置功能:是因为他一个引脚可以有多个功能如PWM,UART,SPI

 

EMWIN屏幕的移植(参考资料:"正点原子EMWIN移植")


前提:需要已有LCD的液晶和触摸驱动,并能正常画点,画线;触摸

下载stm32cubef1:http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/LN1897/PF260820?s_searchtype=partnumber
需要其中的 \stm32cubef1\STM32Cube_FW_F1_V1.0.0\Middlewares\ST\STemWin下的
(1.CONFIG
(2.INC
(3.LIB
(4.OS
这向个文件

(SOFTWARE里函有GUIBUILDER软件,可用于创建界面
(SIMULATION里函有WINDOWS中仿真所需的工具

1.画点函数_SETPIXELINDEX()与取点函数_GETPIXELINDEX()的完成:所在文件 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) {
   				   ili9320_SetPoint(x, y,PixelIndex);  //其它不改只改此一条
}

/*********************************************************************
*
*       _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);
    {

      PixelIndex =ili9320_GetPoint(x,y);   //其它不改只改此一条
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
  return PixelIndex;
}

2.LCD_X_CONFIG() 函数的修改:所在文件LCDCONF_FLEXCOLOR_TEMPLATE.C
并删除 LCDWRITEREG,LCDWRITEDATA,LCDWRITEDATAMULTIPLE,LCDREADDATAMULTIPLE

#include "GUI.h"
//#include "ILI93xx.h"
//#include "touch.h"
#include "GUIDRV_Template.h"
#include "GUIDRV_FlexColor.h"

//与触摸屏有关定义,根据实际情况填写

#define TOUCH_AD_LEFT     377	 
#define TOUCH_AD_RIGHT    3869   
#define TOUCH_AD_TOP      3878 	
#define TOUCH_AD_BOTTOM   	  235



//屏幕大小
#define XSIZE_PHYS  320 //X轴
#define YSIZE_PHYS  240 //Y轴
#define VXSIZE_PHYS	320 
#define VYSIZE_PHYS 240



//配置检查
#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

  

//配置程序,用于创建显示驱动器件,设置颜色转换程序和显示尺寸
void LCD_X_Config(void) {
   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_SetOrientation(GUI_SWAP_XY);
GUI_TOUCH_Calibrate(GUI_COORD_X,0,240,TOUCH_AD_LEFT ,TOUCH_AD_RIGHT);
GUI_TOUCH_Calibrate(GUI_COORD_Y,0,320,TOUCH_AD_TOP ,TOUCH_AD_BOTTOM);
}


//显示器驱动的回调函数
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
  int r;
  (void) LayerIndex;
  (void) pData;
  
  switch (Cmd) {
  case LCD_X_INITCONTROLLER: {
	//当初始化的时候被调用,主要是设置显示控制器,如果显示控制器在外部初始化则需要用户初始化
		
	//	TFTLCD_Init(); //初始化LCD 已经在开始初始化了,所以此处不需要初始化。
    return 0;
  }
		default:
    r = -1;
	}
  return r;
}


3.配置设置GUICONF.H

#ifndef GUICONF_H
#define GUICONF_H

#define GUI_NUM_LAYERS            10   // 显示的最大层数

#define GUI_OS                    (0)  // 使用操作系统
#define GUI_SUPPORT_TOUCH         (1)  // 支持触摸

#define GUI_DEFAULT_FONT          &GUI_Font6x8	//默认字体
#define GUI_SUPPORT_MOUSE             (1)    	//支持鼠标
#define GUI_WINSUPPORT                (1)    	//窗口管理
#define GUI_SUPPORT_MEMDEV            (1)    	//存储设备
#define GUI_SUPPORT_DEVICES           (1)    	//使用设备指针
#endif  

4.需要开启CRC(不开启将导致无显示) 在main.C函数中

int main(void)
{
GUI_PID_STATE TouchState;	 			
int xpos,ypos;
	delay_init();	    	//延时函数初始化

	 LCD24_Init();
	 Touch24_Init();

//	RCC_Configuration1();
//    GPIO_Configuration1();
	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
//	NVIC_Configuration1();
	uart_init(115200);	 	//串口初始化为115200



   

	TIM3_Int_Init(999,71);	//1KHZ 定时器1ms 
	TIM6_Int_Init(999,719);	//10ms中断

			   


	mem_init(); 			//初始化内部内存池
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE);//使能CRC时钟,否则STemWin不能使用 

	WM_SetCreateFlags(WM_CF_MEMDEV);
	GUI_Init();
	GUI_SetBkColor(GUI_RED);
    GUI_Clear();
	GUI_FillCircle(30,30,10);

	SD_Init();
	if (Status == SD_OK)
  {
    /*----------------- Read CSD/CID MSD registers ------------------*/
    Status = SD_GetCardInfo(&SDCardInfo);
	GUI_DispStringAt("SD OK",10,10);
  }


  if (Status == SD_OK)
  {
    /*----------------- Select Card --------------------------------*/
    Status = SD_SelectDeselect((u32) (SDCardInfo.RCA << 16));
	GUI_DispStringAt("SD SELECT OK",10,30);
  }
  
  if (Status == SD_OK)
  {
  //  Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
  }
  
  /* Set Device Transfer Mode to DMA */
  if (Status == SD_OK)
  {  
//    Status = SD_SetDeviceMode(SD_DMA_MODE);//oet
 //   Status = SD_SetDeviceMode(SD_POLLING_MODE);
    Status = SD_SetDeviceMode(SD_INTERRUPT_MODE);
//	printf("\nTEST OK!\n");
	GUI_DispStringAt("SD SETDEVICE OK",10,50);
  }

	 disk_initialize(0);
    
  f_mount(0, &fs);

   gifdisplay_demo();


	GUIDEMO_Main();
//
//			 GUI_DispStringAt("X1:",10,10);
//			 GUI_DispDec(Xs_1,4);
//			 GUI_DispStringAt("X2:",100,10);
//			 GUI_DispDec(Xs_2,4);
//			 GUI_DispStringAt("X3:",10,30);
//			 GUI_DispDec(Xs_3,4);
//			 GUI_DispStringAt("X4:",100,30);
//			 GUI_DispDec(Xs_4,4);
//
//			 GUI_DispStringAt("Y1:",10,60);
//			 GUI_DispDec(Ys_1,4);
//			 GUI_DispStringAt("Y2:",100,60);
//			 GUI_DispDec(Ys_2,4);
//			 GUI_DispStringAt("Y3:",10,120);
//			 GUI_DispDec(Ys_3,4);
//			 GUI_DispStringAt("Y4:",100,120);
//			 GUI_DispDec(Ys_4,4);

	while(1)  
	{



	//	GUI_TOUCH_Exec();
//	xpos = GUI_TOUCH_X_MeasureX();
//	ypos = GUI_TOUCH_X_MeasureY();
//GUI_TOUCH_GetState(&TouchState);
//			 xpos = GUI_TOUCH_GetxPhys();
//		xpos = TouchState.x;
//			 GUI_DispStringAt("X:",10,10);
//			 GUI_DispDec(xpos,4);
//			 
//		//	 ypos = GUI_TOUCH_GetyPhys();
//			 ypos =   TouchState.y;
//			 GUI_DispStringAt("Y:",20,20);
//				GUI_DispDec(ypos,4);
//				GUI_DrawPoint(xpos,ypos);
			//	delay_ms(50);
	}
}


常见的错误:
(1.GUI_NUMBYTES 过大,导致编译通不过:所在文件GUICONF.C
(2.画面不显示:GUI_DEVICE_CREATEANDLINK(&GUIDRV_TEMPLATE_API,GUICC_M565,0,0):此处需设为使用自已的驱动&GUIDRV_TEMPLATE_API:所在文件LCDCONF_FLEXCOLOR_TEMPLATE.C
(3.颜色颜色反了:GUICC_565:所在函数LCDCONF_FLEXCOLOR_TEMPLATE.C-》 GUI_DEVICE_CREATEANDLINK
(4.画面不显示GUIBUILDER创建文件不显示;需要在while中添加GUI_DELAY()或是GUI_EXEC()
 (5.画面不显示,未开启CRC

 

触摸屏的移植

1.需要完成GUI_TOUCH_X_ACTIVEATEX(),GUI_TOUCH_X_ACTIVEATEY()此两个可为空;GUI_TOUCH_X_MEASUREX(),GUI_TOUCH_X_MEASUREY();

#include "stm32f10x.h"
#include "SPI_Flash.h"
#define NotSelect_Flash()    GPIO_SetBits(GPIOA, GPIO_Pin_4)


extern unsigned char AT45_buffer[];

extern unsigned int Xs_1,Xs_2,Xs_3,Xs_4,Ys_1,Ys_2,Ys_3,Ys_4; //记录触坐标值
extern unsigned char dw,A_TP,b,TP_B; //TP_B存放 校准参数  0和1为XY轴  
unsigned char A_TP	=0;
extern unsigned short int X,Y;

void GUI_TOUCH_X_ActivateX(void) {
}

void GUI_TOUCH_X_ActivateY(void) {
}


int  GUI_TOUCH_X_MeasureX(void) 
{
	float Y1,hh;
    u16 xx;
	unsigned char t=0,t1,count=0;
	unsigned short int databuffer[10]={5,7,9,3,2,6,4,0,3,1};//数据组
	unsigned short temp=0,X=0;

	if(TP_B==0)
	{
	while(count<10)//循环读数10次
	{	   	  
		databuffer[count]=TPReadX();
		count++; 
	}  
	if(count==10)//一定要读到10次数据,否则丢弃
	{  
	    do//将数据X升序排列
		{	
			t1=0;		  
			for(t=0;tdatabuffer[t+1])//升序排列
				{
					temp=databuffer[t+1];
					databuffer[t+1]=databuffer[t];
					databuffer[t]=temp;
					t1=1; 
				}  
			}
		}while(t1); 
		if(A_TP==1||A_TP==2)
		{	    		 	 		  
		Y1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
			xx=Xs_3-Xs_1;	//计算出X1,X3距离
			hh=(float)xx/280;	//计算出X比例因子
			xx=(float)((hh*320)-xx)/2;  //X方向偏移量
			X=(Y1-(Xs_1-xx))/hh;	//计算坐标
			X=X*12.79;
		}
		else
		{
		Y1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
			xx=Xs_1-Xs_3;	//计算出X1,X3距离
			hh=(float)xx/280;	//计算出X比例因子
			xx=(float)((hh*320)-xx)/2;  //X方向偏移量
			X=320-(Y1-(Xs_3-xx))/hh;	//计算坐标
			X=X*12.79;

		}	  
	}
	}
	else
	{
	while(count<10)//循环读数10次
	{	   	  
		databuffer[count]=TPReadY();
		count++; 
	}  
	if(count==10)//一定要读到10次数据,否则丢弃
	{  
	    do//将数据X升序排列
		{	
			t1=0;		  
			for(t=0;tdatabuffer[t+1])//升序排列
				{
					temp=databuffer[t+1];
					databuffer[t+1]=databuffer[t];
					databuffer[t]=temp;
					t1=1; 
				}  
			}
		}while(t1); 	    		 	 		  
		if(A_TP==1||A_TP==3)
		{	    		 	 		  
		Y1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
				xx=Ys_2-Ys_1;	//计算出Y1,Y2距离
				hh=(float)xx/280;		//计算出X比例
				xx=(float)((hh*320)-xx)/2;	//Y方向偏移量
				X=(Y1-(Ys_1-xx))/hh;		  //计算坐标
				X=X*12.79;

		}
		else
		{
		Y1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
				xx=Ys_1-Ys_2;	//计算出Y1,Y2距离
				hh=(float)xx/280;		//计算出X比例
				xx=(float)((hh*320)-xx)/2;	//Y方向偏移量
				X=320-(Y1-(Ys_2-xx))/hh;		  //计算坐标
				X=X*12.79;

		}	  

	}
	}
	return(X);  
}

int  GUI_TOUCH_X_MeasureY(void) {
	float X1,hh;
    u16 xx;
  	unsigned char t=0,t1,count=0;
	unsigned short int databuffer[10]={5,7,9,3,2,6,4,0,3,1};//数据组
	unsigned short temp=0,Y=0;	


	if(TP_B==0)
 	{
    while(count<10)	//循环读数10次
	{	   	  
		databuffer[count]=TPReadY();
		count++;  
	}  
	if(count==10)//一定要读到10次数据,否则丢弃
	{  
	    do//将数据X升序排列
		{	
			t1=0;		  
			for(t=0;tdatabuffer[t+1])//升序排列
				{
					temp=databuffer[t+1];
					databuffer[t+1]=databuffer[t];
					databuffer[t]=temp;
					t1=1; 
				}  
			}
		}while(t1);
		if(A_TP==1||A_TP==3)
		{
		X1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
			xx=Ys_2-Ys_1;	//计算出Y1,Y2距离
			hh=(float)xx/200;		//计算出X比例
			xx=(float)((hh*240)-xx)/2;	//Y方向偏移量
			Y=(X1-(Ys_1-xx))/hh;		  //计算坐标
			Y=Y*17.06;
		}
		else
		{
		X1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
			xx=Ys_1-Ys_2;	//计算出Y1,Y2距离
			hh=(float)xx/200;		//计算出X比例
			xx=(float)((hh*240)-xx)/2;	//Y方向偏移量
			Y=240-(X1-(Ys_2-xx))/hh;		  //计算坐标
			Y=Y*17.06;  
		}

	}
	}
	else
	{
    while(count<10)	//循环读数10次
	{	   	  
		databuffer[count]=TPReadX();
		count++;  
	}  
	if(count==10)//一定要读到10次数据,否则丢弃
	{  
	    do//将数据X升序排列
		{	
			t1=0;		  
			for(t=0;tdatabuffer[t+1])//升序排列
				{
					temp=databuffer[t+1];
					databuffer[t+1]=databuffer[t];
					databuffer[t]=temp;
					t1=1; 
				}  
			}
		}while(t1); 	    		 	 		  
		if(A_TP==1||A_TP==2)
		{
		X1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
			xx=Xs_3-Xs_1;	//计算出X1,X3距离
			hh=(float)xx/200;	//计算出X比例因子
			xx=(float)((hh*240)-xx)/2;  //X方向偏移量
			Y=(X1-(Xs_1-xx))/hh;	//计算坐标
			Y=Y*17.06;  
		}
		else
		{
		X1=(databuffer[3]+databuffer[4]+databuffer[5])/3;
			xx=Xs_1-Xs_3;	//计算出X1,X3距离
			hh=(float)xx/200;	//计算出X比例因子
			xx=(float)((hh*240)-xx)/2;  //X方向偏移量
			Y=240-(X1-(Xs_3-xx))/hh;	//计算坐标
			Y=Y*17.06;
		}


	}
	}

	return(Y); 
}	

 

2.LCD_X_CONFIG():所在文件:LCDCONF_FLEXCOLOR_TEMPLATE.C
使用GUI_TOUCH_CALIBRATE()函数,对触摸屏进行设置方向,位置的校正; 

//配置程序,用于创建显示驱动器件,设置颜色转换程序和显示尺寸
void LCD_X_Config(void) {
   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_SetOrientation(GUI_SWAP_XY);
GUI_TOUCH_Calibrate(GUI_COORD_X,0,240,TOUCH_AD_LEFT ,TOUCH_AD_RIGHT);
GUI_TOUCH_Calibrate(GUI_COORD_Y,0,320,TOUCH_AD_TOP ,TOUCH_AD_BOTTOM);
}

3.添加两个中断,在每个中断中完成 所在文件 HARDWARE\TIMER:
OS_TIMEMS++
GUI_TOUCH_EXEC();

#include "timer.h"
//#include "led.h"
#include "GUI.h"
#include "usart.h"

//////////////////////////////////////////////////////////////////////////////////	 								  
////////////////////////////////////////////////////////////////////////////////// 	 

extern __IO int32_t OS_TimeMS;
void TIM3_Int_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启TIM3时钟 

	TIM_TimeBaseInitStructure.TIM_Prescaler=psc;   //分频值
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;	   //计数模式
	TIM_TimeBaseInitStructure.TIM_Period=arr;		   //自动重装数值
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;  //设置时钟分割
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//允许更新中断

	NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	TIM_Cmd(TIM3,ENABLE);		  //使能TIM3
}

void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
	{	
		OS_TimeMS++;
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}

//基本定时器6中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器6!
void TIM6_Int_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE); //定时器6时钟使能
	
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  //设置分频值,10khz的计数频率
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseInitStructure.TIM_Period=arr;  //自动重装载值 计数到5000为500ms
	TIM_TimeBaseInitStructure.TIM_ClockDivision=0; //时钟分割:TDS=Tck_Tim
	TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStructure);
	
	TIM_ITConfig(TIM6,TIM_IT_Update|TIM_IT_Trigger,ENABLE); //使能TIM6的更新中断

	NVIC_InitStructure.NVIC_IRQChannel=TIM6_IRQn; //TIM6中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //先占优先级1级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能通道
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM6,ENABLE); //定时器6使能
}


void TIM6_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM6,TIM_IT_Update)!=RESET)
	{
		GUI_TOUCH_Exec();
	}
	TIM_ClearITPendingBit(TIM6,TIM_IT_Update); //清除中断标志位
}




 

 

 

常见问题:
触摸无反应:测试触摸驱动正常,使用GUI_TOUCH_GETXPHYS()无反应:需开头处添加GUI_TOUCH_EXEC()引用
GUI_TOUCH_CALIBRATE()设置后GUI_TOUCH_GETXPHYS()获取值为物理植,对GUI_TOUCH_GETXPHYS()无效;需使用GUI_TOUCH_GETSTATE() 获取效正的值
应用的触摸无反应:需设置OS_TIMEMS++;和GUI_TOUCH_EXEC()中断服务
应用的触摸无反应:使用GUIBUILDER创建的为DIALOG界面,而非WINDOW界面

 

无操作系统状态下:操作界面也允许点击,触摸,鼠标操作,使用GUIBUILDER时,需使用WINDOW界面,而不是DIALOG否则消息函数无反应,无法点击操作

 

 

 

https://blog.csdn.net/wangyijieonline/article/details/76795084

你可能感兴趣的:(单片机)