本帖最后由 湛只为无双 于 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, 下载次数: 12)
请大家解压后进行查看。
四、触摸和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实现的屏幕截图不能够接下来鼠标,可以看到确实能够显示任意的数字和汉字,效果不错。
|