Cube移植 (版本6.4)
我的板子是正点原子的,自己的板子要根据原理图配置引脚
只需要配置PB15,lcd背光调节,其他的引脚会在后面的touch.c里面配置
修改时钟基准
开启tim6,用作delay_us延时
根据原理图A6用作命令线
串口3调试信息,在freertos打开后就没法用keildebug了不知道为啥
开启crc,st购买了emwin版权,为了不让别人用就加了crc校验,打开才能使用emwin
开启freertos
创建2个任务
调大堆空间
LCD+Touch移植
LCD
使用正点原子提供的lcd历程
注意要将lcd.c和lcd.h改名,我改成了tftlcd.c和tftlcd.h,因为emwin里有LCD.h不能有重复的
EMWIN_LIB里面没东西不用加
进入keil后要进行一些修改,我的cube是6.4版本有些问题
main.c
注释MX_FATFS_Init();
重定向printf,串口3输出
int fputc(int ch,FILE *f){
while((USART3->SR&0x40)==0);
USART3->DR=(uint8_t)ch;
return ch;
}
tftlcd.c
注释HAL_SRAM_MspInit
中间省略的直接复制正点原子里面的代码
void LCD_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
FSMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim;
FSMC_NORSRAM_TimingTypeDef FSMC_WriteTim;
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
GPIO_Initure.Pin=GPIO_PIN_15; //PB15,背光控制
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
TFTSRAM_Handler.Instance=FSMC_NORSRAM_DEVICE;
TFTSRAM_Handler.Extended=FSMC_NORSRAM_EXTENDED_DEVICE;
TFTSRAM_Handler.Init.NSBank=FSMC_NORSRAM_BANK4; //使用NE4
TFTSRAM_Handler.Init.DataAddressMux=FSMC_DATA_ADDRESS_MUX_DISABLE; //地址/数据线不复用
TFTSRAM_Handler.Init.MemoryType=FSMC_MEMORY_TYPE_SRAM; //SRAM
TFTSRAM_Handler.Init.MemoryDataWidth=FSMC_NORSRAM_MEM_BUS_WIDTH_16; //16位数据宽度
TFTSRAM_Handler.Init.BurstAccessMode=FSMC_BURST_ACCESS_MODE_DISABLE; //是否使能突发访问,仅对同步突发存储器有效,此处未用到
TFTSRAM_Handler.Init.WaitSignalPolarity=FSMC_WAIT_SIGNAL_POLARITY_LOW;//等待信号的极性,仅在突发模式访问下有用
TFTSRAM_Handler.Init.WaitSignalActive=FSMC_WAIT_TIMING_BEFORE_WS; //存储器是在等待周期之前的一个时钟周期还是等待周期期间使能NWAIT
TFTSRAM_Handler.Init.WriteOperation=FSMC_WRITE_OPERATION_ENABLE; //存储器写使能
TFTSRAM_Handler.Init.WaitSignal=FSMC_WAIT_SIGNAL_DISABLE; //等待使能位,此处未用到
TFTSRAM_Handler.Init.ExtendedMode=FSMC_EXTENDED_MODE_ENABLE; //读写使用不同的时序
TFTSRAM_Handler.Init.AsynchronousWait=FSMC_ASYNCHRONOUS_WAIT_DISABLE;//是否使能同步传输模式下的等待信号,此处未用到
TFTSRAM_Handler.Init.WriteBurst=FSMC_WRITE_BURST_DISABLE; //禁止突发写
TFTSRAM_Handler.Init.ContinuousClock=FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC;
//FMC读时序控制寄存器
FSMC_ReadWriteTim.AddressSetupTime=0x0F; //地址建立时间(ADDSET)为16个HCLK 1/168M=6ns*16=96ns
FSMC_ReadWriteTim.AddressHoldTime=0;
FSMC_ReadWriteTim.DataSetupTime=60; //数据保存时间为60个HCLK =6*60=360ns
FSMC_ReadWriteTim.AccessMode=FSMC_ACCESS_MODE_A;//模式A
//FMC写时序控制寄存器
FSMC_WriteTim.BusTurnAroundDuration=0; //总线周转阶段持续时间为0,此变量不赋值的话会莫名其妙的自动修改为4。导致程序运行正常
FSMC_WriteTim.AddressSetupTime=9; //地址建立时间(ADDSET)为9个HCLK =54ns
FSMC_WriteTim.AddressHoldTime=0;
FSMC_WriteTim.DataSetupTime=8; //数据保存时间为6ns*9个HCLK=54n
FSMC_WriteTim.AccessMode=FSMC_ACCESS_MODE_A; //模式A
HAL_SRAM_Init(&TFTSRAM_Handler,&FSMC_ReadWriteTim,&FSMC_WriteTim);
delay_ms(50); // delay 50 ms
//尝试9341 ID的读取
LCD_WR_REG(0XD3);
lcddev.id=LCD_RD_DATA(); //dummy read
lcddev.id=LCD_RD_DATA(); //读到0X00
lcddev.id=LCD_RD_DATA(); //读取93
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA(); //读取41
if(lcddev.id!=0X9341) //非9341,尝试是不是7789
{
LCD_WR_REG(0X04);
lcddev.id = LCD_RD_DATA(); //dummy read
lcddev.id = LCD_RD_DATA(); //读到0X85
lcddev.id = LCD_RD_DATA(); //读取0X85
lcddev.id <<= 8;
lcddev.id |= LCD_RD_DATA(); //读取0X52
if (lcddev.id == 0X8552) //将8552的ID转换成7789
{
lcddev.id = 0x7789;
}
if (lcddev.id != 0x7789) //也不是ST7789, 尝试是不是 7789
{
LCD_WR_REG(0XD4);
lcddev.id=LCD_RD_DATA();//dummy read
lcddev.id=LCD_RD_DATA();//读回0X01
lcddev.id=LCD_RD_DATA();//读回0X53
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA(); //这里读回0X10
if(lcddev.id!=0X5310) //也不是NT35310,尝试看看是不是NT35510
{
//发送秘钥(厂家提供,照搬即可)
LCD_WriteReg(0xF000, 0x0055);
LCD_WriteReg(0xF001, 0x00AA);
LCD_WriteReg(0xF002, 0x0052);
LCD_WriteReg(0xF003, 0x0008);
LCD_WriteReg(0xF004, 0x0001);
LCD_WR_REG(0xC500); //读取ID高8位
lcddev.id = LCD_RD_DATA(); //读回0X55
lcddev.id <<= 8;
LCD_WR_REG(0xC501); //读取ID低8位
lcddev.id |= LCD_RD_DATA(); //读回0X10
delay_ms(5);
if(lcddev.id==0x8000)lcddev.id=0x5510;//NT35510读回的ID是8000H,为方便区分,我们强制设置为5510
if(lcddev.id!=0X5510) //也不是NT5510,尝试看看是不是SSD1963
{
LCD_WR_REG(0XA1);
lcddev.id=LCD_RD_DATA();
lcddev.id=LCD_RD_DATA(); //读回0X57
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA(); //读回0X61
if(lcddev.id==0X5761)lcddev.id=0X1963;//SSD1963读回的ID是5761H,为方便区分,我们强制设置为1963
}
}
}
}
printf(" LCD ID:%x\r\n",lcddev.id); //打印LCD ID
if(lcddev.id==0X9341) //9341初始化
{
...
}
else if(lcddev.id==0x5510)
{
...
}
else if(lcddev.id==0X1963)
{
...
}
//初始化完成以后,提速
if(lcddev.id==0X9341||lcddev.id==0X7789||lcddev.id==0X5310||lcddev.id==0X5510||lcddev.id==0X1963)//如果是这几个IC,则设置WR时序为最快
{
//重新配置写时序控制寄存器的时序
FSMC_Bank1E->BWTR[6]&=~(0XF<<0);//地址建立时间(ADDSET)清零
FSMC_Bank1E->BWTR[6]&=~(0XF<<8);//数据保存时间清零
FSMC_Bank1E->BWTR[6]|=3<<0; //地址建立时间(ADDSET)为4个HCLK =24ns
if(lcddev.id==0X7789) //7789独立设置,否则摄像头实验可能有问题
{
FSMC_Bank1E->BWTR[6]|=3<<8; //数据保存时间(DATAST)为6ns*4个HCLK=24ns
}
else
{
FSMC_Bank1E->BWTR[6]|=2<<8; //数据保存时间(DATAST)为6ns*3个HCLK=18ns
}
}
LCD_Display_Dir(0); //默认为竖屏
HAL_GPIO_WritePin(LCD_BLD_GPIO_Port, LCD_BLD_Pin, GPIO_PIN_SET); //点亮背光
LCD_Clear(WHITE);
}
tftlcd.h
开头添加
#include "stdint.h"
#include "sys.h"
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
fsmc.c
在HAL_SRAM_MspInit中添加代码
注意加的位置避免重新生成代码时消失
void HAL_SRAM_MspInit(SRAM_HandleTypeDef* sramHandle){
/* USER CODE BEGIN SRAM_MspInit 0 */
/* USER CODE END SRAM_MspInit 0 */
HAL_FSMC_MspInit();
/* USER CODE BEGIN SRAM_MspInit 1 */
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_FSMC_CLK_ENABLE(); //使能FSMC时钟
__HAL_RCC_GPIOD_CLK_ENABLE(); //使能GPIOD时钟
__HAL_RCC_GPIOE_CLK_ENABLE(); //使能GPIOE时钟
__HAL_RCC_GPIOF_CLK_ENABLE(); //使能GPIOF时钟
__HAL_RCC_GPIOG_CLK_ENABLE(); //使能GPIOG时钟
//初始化PD0,1,4,5,8,9,10,14,15
GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|\
GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15;
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
GPIO_Initure.Alternate=GPIO_AF12_FSMC; //复用为FSMC
HAL_GPIO_Init(GPIOD,&GPIO_Initure); //初始化
//初始化PE7,8,9,10,11,12,13,14,15
GPIO_Initure.Pin=GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|\
GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
HAL_GPIO_Init(GPIOE,&GPIO_Initure);
//初始化PF12
GPIO_Initure.Pin=GPIO_PIN_12;
HAL_GPIO_Init(GPIOF,&GPIO_Initure);
//初始化PG12
GPIO_Initure.Pin=GPIO_PIN_12;
HAL_GPIO_Init(GPIOG,&GPIO_Initure);
/* USER CODE END SRAM_MspInit 1 */
}
还要修改sys.h
为了兼容标准库,也方便移植,我把一些接口移植了过来,这样就可以减少修改其他的文件
/** Function prototype for thread functions */
typedef void (*lwip_thread_fn)(void *arg);
typedef signed char err_t;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414
#define GPIOG_ODR_Addr (GPIOG_BASE+20) //0x40021814
#define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14
#define GPIOI_ODR_Addr (GPIOI_BASE+20) //0x40022014
#define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010
#define GPIOB_IDR_Addr (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410
#define GPIOG_IDR_Addr (GPIOG_BASE+16) //0x40021810
#define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10
#define GPIOI_IDR_Addr (GPIOI_BASE+16) //0x40022010
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入
#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //输出
#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //输入
#define GPIO_A 0
#define GPIO_B 1
#define GPIO_C 2
#define GPIO_D 3
#define GPIO_E 4
#define GPIO_F 5
#define GPIO_G 6
#define GPIO_H 7
#define GPIO_I 8
#define FTIR 1 //下降沿触发
#define RTIR 2 //上升沿触发
//GPIO设置专用宏定义
#define GPIO_MODE_IN 0 //普通输入模式
#define GPIO_MODE_OUT 1 //普通输出模式
#define GPIO_MODE_AF 2 //AF功能模式
#define GPIO_MODE_AIN 3 //模拟输入模式
#define GPIO_SPEED_2M 0 //GPIO速度2Mhz
#define GPIO_SPEED_25M 1 //GPIO速度25Mhz
#define GPIO_SPEED_50M 2 //GPIO速度50Mhz
#define GPIO_SPEED_100M 3 //GPIO速度100Mhz
#define GPIO_PUPD_NONE 0 //不带上下拉
#define GPIO_PUPD_PU 1 //上拉
#define GPIO_PUPD_PD 2 //下拉
#define GPIO_PUPD_RES 3 //保留
#define GPIO_OTYPE_PP 0 //推挽输出
#define GPIO_OTYPE_OD 1 //开漏输出
//GPIO引脚编号定义
#define PIN0 1<<0
#define PIN1 1<<1
#define PIN2 1<<2
#define PIN3 1<<3
#define PIN4 1<<4
#define PIN5 1<<5
#define PIN6 1<<6
#define PIN7 1<<7
#define PIN8 1<<8
#define PIN9 1<<9
#define PIN10 1<<10
#define PIN11 1<<11
#define PIN12 1<<12
#define PIN13 1<<13
#define PIN14 1<<14
#define PIN15 1<<15
delay.c/delay.h
使用rtos
要开启INCLUDE_vTaskDelayUntil宏为1
#include "delay.h"
void delay_us(uint16_t us)
{
__HAL_TIM_SET_COUNTER(&htim6, 0); // 将计数器值重置为0
HAL_TIM_Base_Start(&htim6); // 启动定时器
while (__HAL_TIM_GET_COUNTER(&htim6) < us); // 等待计数器值达到 us
HAL_TIM_Base_Stop(&htim6); // 停止定时器
}
void delay_ms(uint16_t nms){
#if(INCLUDE_vTaskDelayUntil==1)
TickType_t lasttick=xTaskGetTickCount();
vTaskDelayUntil(&lasttick,nms);
#else
HAL_Delay(nms);
#endif
}
至此tftlcd移植完毕,可以复制正点原子的main到freertos中实验
要将MX_FSMC_Init();加入到Touch_Task中,可以添加一些打印信息看是否移植成功
TOUCH
复制正点原子的
可以新建一个文件夹HAREWARE方便管理
LCD不用加,自己建一个DELAY就存放上面写的delay.c和.h
这几个里面都不用改,加一下路径就好了,吧sys.h和delay.h加上去之后就不会有报错了
可以测试一下
把这些加在
/* 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 Load_Drow_Dialog(void)
{
LCD_Clear(WHITE);//清屏
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(lcddev.width-24,0,200,16,16,"RST");//显示清屏区域
POINT_COLOR=RED;//设置画笔蓝色
}
//电容触摸屏专有部分
//画水平线
//x0,y0:坐标
//len:线长度
//color:颜色
void gui_draw_hline(u16 x0,u16 y0,u16 len,u16 color)
{
if(len==0)return;
LCD_Fill(x0,y0,x0+len-1,y0,color);
}
//画实心圆
//x0,y0:坐标
//r:半径
//color:颜色
void gui_fill_circle(u16 x0,u16 y0,u16 r,u16 color)
{
u32 i;
u32 imax = ((u32)r*707)/1000+1;
u32 sqmax = (u32)r*(u32)r+(u32)r/2;
u32 x=r;
gui_draw_hline(x0-r,y0,2*r,color);
for (i=1;i<=imax;i++)
{
if ((i*i+x*x)>sqmax)// draw lines from outside
{
if (x>imax)
{
gui_draw_hline (x0-i+1,y0+x,2*(i-1),color);
gui_draw_hline (x0-i+1,y0-x,2*(i-1),color);
}
x--;
}
// draw lines from inside (center)
gui_draw_hline(x0-x,y0+i,2*x,color);
gui_draw_hline(x0-x,y0-i,2*x,color);
}
}
//两个数之差的绝对值
//x1,x2:需取差值的两个数
//返回值:|x1-x2|
u16 my_abs(u16 x1,u16 x2)
{
if(x1>x2)return x1-x2;
else return x2-x1;
}
//画一条粗线
//(x1,y1),(x2,y2):线条的起始坐标
//size:线条的粗细程度
//color:线条的颜色
void lcd_draw_bline(u16 x1, u16 y1, u16 x2, u16 y2,u8 size,u16 color)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
if(x1<size|| x2<size||y1<size|| y2<size)return;
delta_x=x2-x1; //计算坐标增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
else if(delta_x==0)incx=0;//垂直线
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平线
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//画线输出
{
gui_fill_circle(uRow,uCol,size,color);//画点
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//5个触控点的颜色(电容触摸屏用)
const u16 POINT_COLOR_TBL[5]={RED,GREEN,BLUE,BROWN,GRED};
//电阻触摸屏测试函数
void rtp_test(void)
{
}
//电容触摸屏测试函数
void ctp_test(void)
{
u8 t=0;
u8 i=0;
u16 lastpos[5][2]; //最后一次的数据
while(1)
{
tp_dev.scan(0);
for(t=0;t<5;t++)
{
if((tp_dev.sta)&(1<<t))
{
printf("X坐标:%d,Y坐标:%d\r\n",tp_dev.x[0],tp_dev.y[0]);
if(tp_dev.x[t]<lcddev.width&&tp_dev.y[t]<lcddev.height)
{
if(lastpos[t][0]==0XFFFF)
{
lastpos[t][0] = tp_dev.x[t];
lastpos[t][1] = tp_dev.y[t];
}
lcd_draw_bline(lastpos[t][0],lastpos[t][1],tp_dev.x[t],tp_dev.y[t],2,POINT_COLOR_TBL[t]);//画线
lastpos[t][0]=tp_dev.x[t];
lastpos[t][1]=tp_dev.y[t];
if(tp_dev.x[t]>(lcddev.width-24)&&tp_dev.y[t]<20)
{
Load_Drow_Dialog();//清除
}
}
}else lastpos[t][0]=0XFFFF;
}
delay_ms(5);i++;
}
}
然后再任务Touch_Task中,就只测试不切换任务,循环在ctp_test中(我的是电容屏)
void Touch_Task(void const * argument)
{
/* init code for LWIP */
// MX_LWIP_Init();
/* USER CODE BEGIN Touch_Task */
//
// MX_FATFS_Init();
// printf("fatfs is running\r\n");
MX_FSMC_Init();
LCD_Init(); //初始化LCD
tp_dev.init(); //触摸屏初始化
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
LCD_ShowString(30,70,200,16,16,"TOUCH TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2017/4/14");
if(tp_dev.touchtype!=0XFF)
{
LCD_ShowString(30,130,200,16,16,"Press KEY0 to Adjust");//电阻屏才显示
}
delay_ms(1500);
Load_Drow_Dialog();
if(tp_dev.touchtype&0X80)ctp_test();//电容屏测试
else rtp_test(); //电阻屏测试
}
至此touch移植完毕
STemWin移植
根据路径找到官方提供的文件我的是
C:\Users\Gideon\STM32Cube\Repository\STM32Cube_FW_F4_V1.26.2\Middlewares\ST\STemWin
复制emwin到projectemwin\Middlewares\Third_Party
在keil里面新建一个group改名为下面这个,然后添加以下的
修改文件属性
为libray file
加一下文件路径
编译一遍,会有找不到LCDConf.h的问题,直接在这里面新建一个空的LCDConf.h文件就好了
修改文件
GUI_Conf.c
#define GUI_NUMBYTES 1024*50
LCDConf_FlexColor_Template.c
LCD_X_Config
#define XSIZE_PHYS 480 // To be adapted to x-screen size
#define YSIZE_PHYS 800 // To be adapted to y-screen size
void LCD_X_Config(void) {
// Set display driver and color conversion
//
GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0);
//
// Display driver configuration, required for Lin-driver
//
LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
//
// Orientation
//
GUI_TOUCH_Calibrate(GUI_COORD_X,0,lcddev.height-1,0,lcddev.height-1);
GUI_TOUCH_Calibrate(GUI_COORD_Y,0,lcddev.width-1,0,lcddev.width-1);
}
LCD_X_DisplayDriver
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
printf("LCD_X_DisplayDriver \r\n");
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_Init();
tp_dev.init();
// ...
return 0;
}
default:
r = -1;
}
return r;
}
GUIDRV_Template.c
_SetPixelIndex
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_Fast_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
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
//
// TBD by customer...
//
PixelIndex = LCD_ReadPoint(x,y);
PixelIndex = 0;
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
return PixelIndex;
}
_FillRect
static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) {
LCD_PIXELINDEX PixelIndex;
int x;
PixelIndex = LCD__GetColorIndex();
if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) {
for (; y0 <= y1; y0++) {
for (x = x0; x <= x1; x++) {
_XorPixel(pDevice, x, y0);
}
}
} else {
LCD_Fill(x0,y0,x1,y1,PixelIndex);
}
}
GUI_X_Touch_Analog.c
#include "GUI.h"
#include "touch.h"
#include "stdio.h"
void GUI_TOUCH_X_ActivateX(void){
}
void GUI_TOUCH_X_ActivateY(void){
}
int GUI_TOUCH_X_MeasureX(void){
tp_dev.scan(0);
return tp_dev.x[0];
}
int GUI_TOUCH_X_MeasureY(void){
return tp_dev.y[0];
}
注意在修改的这些文件中添加头文件touch.c和tftlcd.c
在freertos中添加测试代码
void Touch_Task(void const * argument)
{
/* init code for LWIP */
// MX_LWIP_Init();
/* USER CODE BEGIN Touch_Task */
//
// MX_FATFS_Init();
// printf("fatfs is running\r\n");
char buf[]="hello world";
MX_FSMC_Init();
LCD_Init(); //初始化LCD
tp_dev.init(); //触摸屏初始化
GUI_Init();
printf("GUI init ok\r\n");
GUI_SetBkColor(GUI_BLUE);
GUI_SetFont(GUI_FONT_32_1);
GUI_SetColor(GUI_YELLOW);
GUI_Clear();
GUI_PID_STATE State;
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,26);
GUI_DispDecAt(State.y,32,26,4);
GUI_DispStringAt("L:",0,52);
GUI_DispDecAt(State.Layer,32,52,4);
GUI_DispStringAt("P:",0,78);
GUI_DispDecAt(State.Pressed,32,78,4);
printf("Touch detected at (%d, %d)\n", State.x, State.y);
}
osDelay(20);
}
}
结果,屏幕会打印触摸位置坐标