|
楼主 |
发表于 2017-2-8 16:55:47
|
显示全部楼层
30.4 实验例程说明(RTOS)
配套例子:
V6-540_STemWin实验_光标(RTOS)
实验目的:
1. 学习emWin的光标,可以手动触摸界面来看光标的移动。
2. emWin功能的实现在MainTask.c文件里面。
实验内容:
1. K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
2. K2按键按下,实现截图功能,将图片以BMP格式保存到SD卡中。
3. 各个任务实现的功能如下:
App Task Start 任务:实现按键和触摸扫描。
App Task MspPro任务 :实现截图功能,将图片以BMP格式保存到SD卡中。
App Task UserIF 任务:按键消息处理。
App Task COM 任务:暂未使用。
App Task GUI 任务:GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
STemWin界面显示效果:
800*480分辨率界面效果(emWin截图的时候,光标是无法截图出来的)。
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"
-
-
- /*
- *********************************************************************************************************
- * 条件编译
- *********************************************************************************************************
- */
- #ifndef GUI_CONST_STORAGE
- #define GUI_CONST_STORAGE const
- #endif
-
- /*
- *********************************************************************************************************
- * 位图数据
- *********************************************************************************************************
- */
- static GUI_CONST_STORAGE unsigned long _acarmfly[] = {
- /* 位图数据省略,未贴出 */
- }
-
- GUI_CONST_STORAGE GUI_BITMAP bmarmfly = {
- 192, // xSize
- 88, // ySize
- 768, // BytesPerLine
- 32, // BitsPerPixel
- (unsigned char *)_acarmfly, // Pointer to picture data
- NULL, // Pointer to palette
- GUI_DRAW_BMP8888
- };
-
- /*
- *********************************************************************************************************
- * 函 数 名: MainTask
- * 功能说明: GUI主函数
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void MainTask(void)
- {
-
- /* 初始化 */
- 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();
-
- /* 显示光标 */
- GUI_CURSOR_Show();
-
- /* 清屏 */
- GUI_SetBkColor(GUI_BLUE);
- GUI_Clear();
-
- /* 设置字体 */
- GUI_SetFont(&GUI_Font24_ASCII);
-
- /* 显示RGB565格式的位图 */
- GUI_DispStringAt("COURSOR_Sample", 2, 2);
- GUI_DrawBitmap(&bmarmfly, 40, 40);
-
- while(1)
- {
- GUI_Delay(10);
- }
- }
复制代码 |
|