|
楼主 |
发表于 2017-1-20 16:44:24
|
显示全部楼层
24.4 实验例程说明(RTOS)
配套例子:
V6-530_STemWin实验_SIF格式全字库的生成和使用方法,Unicode编码(RTOS)
实验目的:
1. 学习emWin的SIF格式全字库的生成和使用方法,Unicode编码。
2. emWin功能的实现在MainTask.c文件里面。
实验内容:
1. K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
2. K2按键按下,实现截图功能,将图片以BMP格式保存到SD卡中。
3. 各个任务实现的功能如下:
App Task Start 任务:实现按键和触摸扫描。
AppTask MspPro任务 :实现截图功能,将图片以BMP格式保存到SD卡中。
App Task UserIF 任务:按键消息处理。
App Task COM 任务:暂未使用。
App Task GUI 任务:GUI任务。
支持点阵:
1. 宋体16点阵,24点阵带2倍抗锯齿的unicode编码全字库。
实验注意:
1. 实验所需的字库文件Song24.sif和Song16.sif已经存储到本工程的Doc文件夹下,请务必将这两个文件存储到SD卡根目录中,并将SD卡插到开发板上面,系统上电后会将其加载到emWin动态内存,即SDRAM里面。
μCOS-III任务调试信息(按K1按键,串口打印):
STemWin界面显示效果:
800*480分辨率界面效果。
STemWin动态内存配置:
GUIConf.c文件中的配置如下:
- #define EX_SRAM 1/*1 used extern sram, 0 used internal sram */
-
- #if EX_SRAM
- #define GUI_NUMBYTES (1024*1024*8)
- #else
- #define GUI_NUMBYTES (100*1024)
- #endif
复制代码 通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
LCDConf_Lin_Template.c文件中共12项emWin配置:
对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
任务栈大小分配:
μCOS-III任务栈大小在os_cfg.h文件中配置:
#define APP_CFG_TASK_START_STK_SIZE 512u
#define APP_CFG_TASK_MsgPro_STK_SIZE 512u
#define APP_CFG_TASK_COM_STK_SIZE 512u
#define APP_CFG_TASK_USER_IF_STK_SIZE 512u
#define APP_CFG_TASK_GUI_STK_SIZE 1024u
任务栈大小的单位是4字节,那么每个任务的栈大小如下:
App Task Start 任务:2048字节。
App Task MspPro任务 :2048字节。
App Task UserIF 任务:2048字节。
App Task COM 任务:2048字节。
App Task GUI 任务:4096字节。
系统栈大小分配:
μCOS-III的系统栈大小在os_cfg_app.h文件中配置:
#define OS_CFG_ISR_STK_SIZE 512u
系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB。
μCOS-III初始化:
- /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: 标准c程序入口。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int main(void)
- {
- OS_ERR err;
-
- /* 初始化uC/OS-III 内核 */
- OSInit(&err);
-
- /* 创建一个启动任务(也就是主任务)。启动任务会创建所有的应用程序任务 */
- OSTaskCreate((OS_TCB *)&AppTaskStartTCB, /* 任务控制块地址 */
- (CPU_CHAR *)"App Task Start", /* 任务名 */
- (OS_TASK_PTR )AppTaskStart, /* 启动任务函数地址 */
- (void *)0, /* 传递给任务的参数 */
- (OS_PRIO )APP_CFG_TASK_START_PRIO, /* 任务优先级 */
- (CPU_STK *)&AppTaskStartStk[0], /* 堆栈基地址 */
- (CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE / 10, /* 堆栈监测区,这里表示后10%作为监测区 */
- (CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE, /* 堆栈空间大小 */
- (OS_MSG_QTY )0, /* 本任务支持接受的最大消息数 */
- (OS_TICK )0, /* 设置时间片 */
- (void *)0, /* 堆栈空间大小 */
- (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
-
- /* 定义如下:
- OS_OPT_TASK_STK_CHK 使能检测任务栈,统计任务栈已用的和未用的
- OS_OPT_TASK_STK_CLR 在创建任务时,清零任务栈
- OS_OPT_TASK_SAVE_FP 如果CPU有浮点寄存器,则在任务切换时保存浮点寄存器的内容
- */
- (OS_ERR *)&err);
-
- /* 启动多任务系统,控制权交给uC/OS-III */
- OSStart(&err);
-
- (void)&err;
-
- return (0);
- }
复制代码 硬件外设初始化
硬件外设的初始化是在bsp.c文件实现:
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_Init
- * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_Init(void)
- {
- /*
- 由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
- 启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
-
- 系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
- */
- /* 使能CRC 因为使用STemWin前必须要使能 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
-
- /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
-
- SystemCoreClockUpdate(); /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
-
- bsp_InitUart(); /* 初始化串口 */
- bsp_InitKey(); /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
-
- bsp_InitExtIO(); /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
- bsp_InitLed(); /* 初始LED指示灯端口 */
-
- bsp_InitI2C(); /* 配置I2C总线 */
- bsp_InitSPIBus(); /* 配置SPI总线 */
-
- bsp_InitSFlash(); /* 初始化SPI Flash */
-
- bsp_InitExtSDRAM(); /* 初始化SDRAM */
- bsp_DetectLcdType(); /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
-
- TOUCH_InitHard(); /* 初始化配置触摸芯片 */
- LCD_ConfigLTDC(); /* 初始化配置LTDC */
-
- result = f_mount(&fs, "0:/", 0); /* 挂载文件系统 */
- }
复制代码 五个μCOS-III任务的实现:
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskStart
- * 功能说明: 这是一个启动任务,在多任务系统启动后,必须初始化滴答计数器。本任务主要实现按键和触摸检测。
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- 优 先 级: 2
- *********************************************************************************************************
- */
- static void AppTaskStart (void *p_arg)
- {
- OS_ERR err;
- uint8_t ucCount = 0;
- uint8_t ucCount1 = 0;
-
- /* 仅用于避免编译器告警,编译器不会产生任何目标代码 */
- (void)p_arg;
-
- /* BSP 初始化。 BSP = Board Support Package 板级支持包,可以理解为底层驱动。*/
- CPU_Init(); /* 此函数要优先调用,因为外设驱动中使用的us和ms延迟是基于此函数的 */
- bsp_Init();
- BSP_Tick_Init();
-
- #if OS_CFG_STAT_TASK_EN > 0u
- OSStatTaskCPUUsageInit(&err);
- #endif
-
- #ifdef CPU_CFG_INT_DIS_MEAS_EN
- CPU_IntDisMeasMaxCurReset();
- #endif
-
- /* 创建应用程序的任务 */
- AppTaskCreate();
-
- /* 创建任务通信 */
- AppObjCreate();
-
- while(1)
- {
- /* 1ms一次触摸扫描,电阻触摸屏 */
- if(g_tTP.Enable == 1)
- {
- TOUCH_Scan();
-
- /* 按键扫描 */
- ucCount++;
- if(ucCount == 10)
- {
- ucCount = 0;
- bsp_KeyScan();
- }
- OSTimeDly(1, OS_OPT_TIME_DLY, &err);
- }
-
- /* 20ms一次触摸扫描,电容触摸屏GT811
- GT811取20ms比较稳定,取10ms偶尔会有跳动。
- */
- if(g_GT811.Enable == 1)
- {
- bsp_KeyScan();
- ucCount1++;
- if(ucCount1 == 2)
- {
- ucCount1 = 0;
- GT811_OnePiontScan();
- }
- OSTimeDly(10, OS_OPT_TIME_DLY, &err);
- }
-
- /* 10ms一次触摸扫描,电容触摸屏FT5X06 */
- if(g_tFT5X06.Enable == 1)
- {
- bsp_KeyScan();
- FT5X06_OnePiontScan();
- OSTimeDly(10, OS_OPT_TIME_DLY, &err);
- }
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskMsgPro
- * 功能说明: 实现截图功能,将图片以BMP格式保存到SD卡中
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- 优 先 级: 3
- *********************************************************************************************************
- */
- static void AppTaskMsgPro(void *p_arg)
- {
- uint32_t ulStart, ulEnd;
- OS_ERR err;
- uint8_t Pic_Name = 0;
- char buf[20];
-
- (void)p_arg;
-
- while(1)
- {
- /* 等待获取信号量同步消息,接收到后执行串口打印 */
- OSSemPend((OS_SEM *)&SEM_SYNCH,
- (OS_TICK )0,
- (OS_OPT )OS_OPT_PEND_BLOCKING,
- (CPU_TS )0,
- (OS_ERR *)&err);
-
- if(err == OS_ERR_NONE)
- {
- sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
-
- /* 记录截图前起始时间 */
- ulStart = OSTimeGet(&err);
-
- /* 开启调度锁 */
- OSSchedLock(&err);
-
- /* 如果SD卡中没有PicSave文件,会进行创建 */
- result = f_mkdir("0:/PicSave");
-
- /* 创建截图 */
- result = f_open(&file,buf, FA_WRITE|FA_CREATE_ALWAYS);
-
- /* 向SD卡绘制BMP图片 */
- GUI_BMP_Serialize(_WriteByte2File, &file);
-
- /* 创建完成后关闭file */
- result = f_close(&file);
-
- /* 开启调度锁 */
- OSSchedUnlock(&err);
-
- /* 记录截图后时间并获取截图过程耗时 */
- ulEnd = OSTimeGet(&err);
- ulEnd -= ulStart;
-
- App_Printf("截图完成,耗时 = %dms\\r\\n", ulEnd);
- Pic_Name++;
- }
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskUserIF
- * 功能说明: 按键消息处理
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- 优 先 级: 4
- *********************************************************************************************************
- */
- static void AppTaskUserIF(void *p_arg)
- {
- OS_ERR err;
- uint8_t ucKeyCode;
-
- (void)p_arg; /* 避免编译器报警 */
-
-
- while (1)
- {
- ucKeyCode = bsp_GetKey();
-
- if (ucKeyCode != KEY_NONE)
- {
- switch (ucKeyCode)
- {
- case KEY_DOWN_K1: /* K1键按下 打印任务执行情况 */
- DispTaskInfo();
- break;
-
- case KEY_DOWN_K2: /* K2键按下 向消息队列发送数据 */
- OSSemPost((OS_SEM *)&SEM_SYNCH,
- (OS_OPT )OS_OPT_POST_1,
- (OS_ERR *)&err);
- break;
-
- default: /* 其他的键值不处理 */
- break;
- }
- }
-
- OSTimeDly(20, OS_OPT_TIME_DLY, &err);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskCom
- * 功能说明: 暂未使用
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- 优 先 级: 5
- *********************************************************************************************************
- */
- static void AppTaskCOM(void *p_arg)
- {
- OS_ERR err;
-
- (void)p_arg;
-
- while(1)
- {
- OSTimeDly(500, OS_OPT_TIME_DLY, &err);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskGUI
- * 功能说明: GUI任务,最低优先级
- * 形 参:p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级:OS_CFG_PRIO_MAX - 4u
- *********************************************************************************************************
- */
- static void AppTaskGUI(void *p_arg)
- {
- (void)p_arg; /* 避免编译器告警 */
-
- while (1)
- {
- MainTask();
- }
- }
复制代码 emWin任务的具体实现(在MainTask.c文件里面):
- #include "MainTask.h"
- #include "includes.h"
-
-
-
- /*
- *********************************************************************************************************
- * 外部声明供本文件使用
- *********************************************************************************************************
- */
- extern GUI_CONST_STORAGE GUI_FONT GUI_FontSong16;
-
-
- /*
- *********************************************************************************************************
- * SIF字体定义
- *********************************************************************************************************
- */
- GUI_FONT SIF_AA2_Font24;
- GUI_FONT SIF_Font16;
-
-
- /*
- *********************************************************************************************************
- * 对话框信息
- *********************************************************************************************************
- */
- static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
- { FRAMEWIN_CreateIndirect, "安富莱电子", 0, 0, 0, 480, 272,FRAMEWIN_CF_MOVEABLE, 0},
- { BUTTON_CreateIndirect, "安富莱电子", GUI_ID_BUTTON0, 10, 150, 400, 50, 0, 0},
- { TEXT_CreateIndirect, "安富莱电子AaAa-16点阵半角全角", GUI_ID_TEXT1, 0, 40, 480, 33, 0,0},
- { TEXT_CreateIndirect, "安富莱电子AaAa-24点阵半全角,2倍抗锯齿", GUI_ID_TEXT3, 0, 100, 480, 72, 0,0},
- };
-
- /*
- *********************************************************************************************************
- * 函 数 名: PaintDialog
- * 功能说明: 重绘
- * 形 参:pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void PaintDialog(WM_MESSAGE * pMsg)
- {
-
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: InitDialog
- * 功能说明: 对话框初始化
- * 形 参: pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void InitDialog(WM_MESSAGE * pMsg)
- {
- WM_HWIN hWin = pMsg->hWin;
-
- //
- // 框架窗口设置
- //
- FRAMEWIN_SetFont(hWin,&SIF_AA2_Font24);
- FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
- FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
- FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
- FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
- FRAMEWIN_SetTitleHeight(hWin,35);
-
- //
- // 按钮控件设置
- //
- BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&SIF_AA2_Font24);
-
- //
- // 文本控件设置
- //
- TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_RED);
- TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&SIF_Font16);
- TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT3), GUI_BLUE);
- TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT3),&SIF_AA2_Font24);
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: _cbCallback
- * 功能说明: 对话框回调函数
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _cbCallback(WM_MESSAGE * pMsg)
- {
- int NCode, Id;
- WM_HWIN hWin = pMsg->hWin;
- switch (pMsg->MsgId)
- {
- case WM_PAINT:
- PaintDialog(pMsg);
- break;
-
- case WM_INIT_DIALOG:
- InitDialog(pMsg);
- break;
-
- case WM_KEY:
- switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
- {
- case GUI_KEY_ESCAPE:
- GUI_EndDialog(hWin, 1);
- break;
- case GUI_KEY_ENTER:
- GUI_EndDialog(hWin, 0);
- break;
- }
- break;
-
- case WM_NOTIFY_PARENT:
- Id = WM_GetId(pMsg->hWinSrc);
- NCode = pMsg->Data.v;
- switch (Id)
- {
- case GUI_ID_OK:
- if(NCode==WM_NOTIFICATION_RELEASED)
- GUI_EndDialog(hWin, 0);
- break;
-
- case GUI_ID_CANCEL:
- if(NCode==WM_NOTIFICATION_RELEASED)
- GUI_EndDialog(hWin, 0);
- break;
- }
- break;
-
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: LoadFontLib()
- * 功能说明: 从SD卡中加载字库文件到SPI FLASH
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void *_LoadSIFFont(const char *sFilename)
- {
- char *_acBuffer;
- GUI_HMEM hMem;
-
- /* 打开文件 */
- result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);
- if (result != FR_OK)
- {
- return 0;
- }
-
- /* 申请一块内存空间 并且将其清零 */
- hMem = GUI_ALLOC_AllocZero(file.fsize);
-
- /* 将申请到内存的句柄转换成指针类型 */
- _acBuffer = GUI_ALLOC_h2p(hMem);
-
- /* 读取文件到动态内存 */
- result = f_read(&file, _acBuffer, file.fsize, &bw);
- if (result != FR_OK)
- {
- return 0;
- }
-
- /* 关闭文件 */
- f_close(&file);
-
- return _acBuffer;
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: MainTask
- * 功能说明: GUI主函数
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void MainTask(void)
- {
- uint8_t *_acBufferFont16;
- uint8_t *_acBufferFont24;
-
- /* 初始化 */
- GUI_Init();
-
- /*
- 关于多缓冲和窗口内存设备的设置说明
- 1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
- WM_MULTIBUF_Enable(1);
- 2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
- 3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
- STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
- 感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
- 4. 所有emWin例子默认是开启三缓冲。
- */
- WM_MULTIBUF_Enable(1);
-
- /*
- 触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
- 此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
- */
- //TOUCH_Calibration();
-
- /* 使能UTF-8编码 */
- GUI_UC_SetEncodeUTF8();
-
- /* 清屏 */
- GUI_SetBkColor(GUI_BLUE);
- GUI_Clear();
-
- /* 设置字体,显示必要的提示 */
- GUI_SetFont(&GUI_FontSong16);
- GUI_DispStringAt("1.请将工程Doc文件夹里面Song24.sif和Song16.sif文件存储SD卡中。", 0, 0);
- GUI_Delay(2000);
- GUI_DispStringAt("2.开始加载SIF字体到emWin动态内存,即SDRAM中,请稍等!", 0, 20);
-
- /* 加载SIF格式字库到emWin动态内存,即SDRAM里面 */
- _acBufferFont16 = _LoadSIFFont("Song16.sif");
-
- /* 创建SIF格式字体,16点阵宋体*/
- GUI_SIF_CreateFont(_acBufferFont16, &SIF_Font16, GUI_SIF_TYPE_PROP);
-
- /* 加载SIF格式字库到emWin动态内存,即SDRAM里面 */
- _acBufferFont24 = _LoadSIFFont("Song24.sif");
-
- /* 创建SIF格式字体,24点阵宋体*/
- GUI_SIF_CreateFont(_acBufferFont24, &SIF_AA2_Font24, GUI_SIF_TYPE_PROP_AA2);
-
- /* 调用此函数会自动的刷新桌面窗口 */
- WM_SetDesktopColor(GUI_BLUE);
-
- /* 创建对话框 */
- GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
-
- while(1)
- {
- GUI_Delay(10);
- }
- }
复制代码 |
|