本帖最后由 湛只为无双 于 2016-1-14 14:44 编辑
本次实现的功能比较多,首先还是本人比较趋向于使用标准库的开发,那样就可以和以前的程序无缝连接在一起了,并且减少了工作量,是用标准库比较清晰明了,不会给你很繁琐的感觉,这是hal库所不能做到的。
一、主要实现的功能
①SDRAM外部存储器底层驱动
②QUALSPI外部存储器的内存映射模式设计
③液晶屏的DSI接口设计,主要采用了16位颜色(没有使用24位色,在有限的带宽上增加数据吞吐速度)
④电容触摸屏FT6206的IIC接口设计,实现了读取触摸数据(我敢肯定,大家看了我的代码,会对板子的触摸有质的飞跃)
⑤实现了STemWin的功能移植,包含了常用组件功能和触摸功能
⑥基于SDIO的存储卡驱动设计,并基于此的FATFS文件系统移植(参考了正点原理的FATFS功能)
⑥的补充,支持936格式长文件名,常量数组存储在上面所说的外部的QUALSPI存储器中,采用了内存映射,使用方便
⑦实现了FreeRTOS的功能移植,并与STemWin相结合(ST官方的推荐FreeRTOS+STemWin+FATFS+LwIP)
⑧添加了基于STemWin的任意汉字显示,包含有12*12和16*16的宋体字,其他字体自行添加,同样存储在外部的QUALSPI存储器的内存映射(不得不说,内存映射真好用)
二、一些功能的介绍
第①个功能,已经在之前介绍了,请参考之前的帖子;
第②个功能,我采用了简单粗暴的方式,估计大家看了会说一句FUCK,我也无奈,实在是不想自己一点一点调试了:
void DISCO_QSPI_Init(void)
{
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_QSPI,ENABLE);
QSPI_GPIO_Config();
QUADSPI->CR = 0x01500019;
QUADSPI->DCR = 0x00170100;
QUADSPI->CCR = 0x0f282deb;
QUADSPI->PSMKR = 0x02;
QUADSPI->PSMAR = 0x02;
QUADSPI->PIR = 0x10;
QUADSPI->LPTR = 0x64;
}
其中主要代码是开启时钟,然后配置GPIO,然后就是寄存器的一大堆设置,参考了官方配置好的结果,采用直接赋值,完事……
第③个功能,官方已经集成啦,就不再赘述了,而且已经有很多的帖子介绍了,我也不再多说了,关键是会用即可;
第④⑤个,后面会详细介绍;
第⑥个,关于SD卡的,请参考源码,这个我觉得正点原子哥讲得比我好,我也是直接拿来用的;
第⑦个,也是直接移植好,关键看后续介绍;
第⑧个,这个比较难,但是用起来好用呀,而且不用使用UNICODE编码,直接的ASCII编码,方便串口接收数据的直接显示。
三、FT6206电容触摸的驱动编写
首先,需要向大家介绍,FT6206这个电容触摸芯片,其实查阅到的资料也不是很多,关键是官方提供的资料里面查阅到的,可以看到这个芯片的IIC地址为0x54,通过对这个地址进行读取,就可以实现数据的读取。
接着是FT6206的设备ID寄存器,通过读取0xa8寄存器,可以读取到0x11这个固定值,但是我在读取的过程中发现有的时候能够读取到,有的时候不一定能读取到,所以这个自检的过程直接忽略,但是不耽误后续的数据读取。
然后重点来了:
1、触摸状态寄存器0x02
通过读取此寄存器可以实现当前触摸点的个数,当没有触摸时,读取到的值为0xff或者0x00,当有一个触摸点时,读取到的数值为0x01,同样当有两个触摸点时,读取到数值为0x02。可以通过读取到数值的大小来实现触摸的判断。
2、触摸数据寄存器
当有一个触摸点时,通过从寄存器0x03开始的连续四个寄存器,即为触摸XH/XL/YH/YL的数值大小,当存在第二个触摸点时,从寄存器0x09开始的连续四个寄存器,也是XH/XL/YH/YL的数值大小。
3、程序的编写
通过以上分析可以得到写出来的程序是这样的:
int BSP_FT6205_Detect(void)
{
return I2C_Read(FT6206_I2C_ADDRESS,FT6206_TD_STAT_REG);
}
int BSP_FT6205_GetXY(u16 *pTouchX,u16 *pTouchY)
{
int nNumPoint;
u8 FT6206_Value[8]={0};
nNumPoint = BSP_FT6205_Detect();
if( (nNumPoint!=1) && (nNumPoint!=2))
{
return 0;
}
I2C_Reads(FT6206_I2C_ADDRESS,FT6206_P1_XH_REG,FT6206_Value,4);
*pTouchX=((u16)(FT6206_Value[0]&0x0f)<<8) | FT6206_Value[1];
*pTouchY=((u16)(FT6206_Value[2]&0x0f)<<8) | FT6206_Value[3];
return 1;
}
以上主要实现的功能有触摸点的判定和触摸数值的读取,在读取完毕后一定要有&0x0f的步骤,否则读取到的数据高四位是不能用的,从而导致触摸的不准。
读取到的原始数据即为0~480和0~800不需要进行大小的变换,但是在横屏和竖屏中需要进行简单的转换,这一点需要注意。
4、逻辑分析仪对IIC的数据抓包
在这里向大家提供使用逻辑分析仪抓取到的IIC原始数据包,共大家参考:
FT6206_I2C_DATA.zip
(30.86 KB)
请大家解压后进行查看。
四、触摸和STemWin的结合
使用触摸后还需要和STemWin相结合才可以使用,在这里使用了写入GUI_PID_STATE结构体的方式来实现的,这样可以实现写入的快速性和实时性,使用比较方便。
GUI_PID_STATE TS_State;
u16 touchX,touchY;
void BSP_PointerUpdate(void)
{
portENTER_CRITICAL();
TS_State.Pressed = BSP_FT6205_GetXY(&touchY,&touchX);
portEXIT_CRITICAL ();
TS_State.x = touchX;
TS_State.y = 480-touchY;
TS_State.Layer = 0;
if((TS_State.x >= 0 ) &&
(TS_State.x < LCD_GetXSize())&&
(TS_State.y >= 0 ) &&
(TS_State.y < LCD_GetYSize()))
{
GUI_TOUCH_StoreStateEx(&TS_State);
}
}
在程序中包含了触摸状态和触摸数据的读取,如果检测到触摸,才回执行下一步的触摸数据,避免了不必要的数据操作。
五、主函数的测试功能
主函数的功能主要包含有了触摸,QUALSPI以及外部12*12/16*16任意汉字显示,开启了鼠标显示,通过触摸可以实现鼠标的移动。
#include "main.h"
FATFS my_fs;
void vLCDTask( void *pvParameters );
void vLEDTask( void *pvParameters );
int main(void)
{
LED_Init();
USART3_Init(115200);
DISCO_SDRAM_Init();
DISCO_QSPI_Init();
KEY_Init();
CAN_BUS_Init();
f_mount(&my_fs,"0:",1);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
GUI_SetDefaultFont(&GUI_FontHZ16);
GUI_Init();
//触摸必须要在GUI_Init后初始化,因为GUI的初始化里面调用了LCD复位功能,同样也会复位触摸
xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", 768, NULL, tskIDLE_PRIORITY+8, NULL );
xTaskCreate( vLEDTask, ( signed portCHAR * ) "LED", 512, NULL, tskIDLE_PRIORITY+7, NULL );
vTaskStartScheduler();
while(1);
}
void vLEDTask( void *pvParameters )
{
BSP_FT6206_Init();
while(1)
{
vTaskDelay(50);
LED1^=1;
BSP_PointerUpdate();
}
}
void vLCDTask( void *pvParameters )
{
GUI_CURSOR_Show();
GUI_SetColor(GUI_RED);
GUI_SetBkColor(GUI_YELLOW);
GUI_Clear();
GUI_SetFont(&GUI_FontHZ12);
GUI_DispStringAt("21ic论坛,祝21ic越办越好",350,230);
GUI_SetFont(&GUI_FontHZ16);
GUI_DispStringAt("21ic论坛,祝21ic越办越好",350,250);
while(1)
{
GUI_Delay(100);
}
}
在主函数里面,主要建立了两个任务,第一个任务的作用是LED闪烁已经触摸信息的更新,第二个任务在屏幕固定位置上显示设定汉字后,调用GUI_Delay()实现GUI的调度功能。
这个图片是通过调用STemWin实现的屏幕截图保存下来的,不过STemWin实现的屏幕截图不能够接下来鼠标,可以看到确实能够显示任意的数字和汉字,效果不错。
|