|
求助:
硬件:F429+7寸触摸屏。
程序功能:通过自定义的串口协议接收数据包,并把这些数据显示在emwin界面上,串口接收数据采用中断接收方法,但是这样的话就会时不时出现一个乱码的数据包;在不和emwin界面集成到一起时,我自己使用F429例程里的串口收发程序改一改测试串口协议,试了串口数据包收发是没问题的,不会出现乱码,这是什么原因呢,是哪里配置的中断时序影响的吗?
串口相关主要程序:
1.usart.c
void USART1_IRQHandler(void)
{
static uint8_t RxState = 0; //定义表示当前状态机状态的静态变量
static uint8_t pRxPacket = 0; //定义表示当前接收数据位置的静态变量
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判断是否是USART1的接收事件触发的中断
{
uint8_t RxData = USART_ReceiveData(USART1); //读取数据寄存器,存放在接收的数据变量
/*使用状态机的思路,依次处理数据包的不同部分*/
/*当前状态为0,接收数据包包头1*/
if (RxState == 0)
{
if (RxData == 0x7E) //如果数据确实是包头
{
RxState = 1; //置下一个状态
pRxPacket = 0; //数据包的位置归零
}
//中间省略,定义了一些数据格式
/*当前状态为6,接收数据包包尾*/
else if (RxState == 6)
{
if (RxData == 0x23) //如果数据确实是包尾部
{
RxState = 0; //状态归0
Serial_RxFlag = 1; //接收数据包标志位置1,成功接收一个数据包
}
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除标志位
}
}
2.mainTask.c
void MainTask(void)
{
extern uint8_t tstate;
int i = 0;
float X1, Y1, X2, Y2, POWER1, POWER2;
float resultsA[3], resultsB[3], resultsAB[6];
Debug_USART_Config();
while (1)
{
if (Serial_GetRxFlag() == 1)
{
if (tstate == 5)
{
for (i = 0; i < 6; i++) {
resultsAB = hex_array_to_float(&Serial_RxPacketAB[i * 4]);
} //处理串口接收到的数据并显示
X1 = resultsAB[0];
Y1 = resultsAB[1];
POWER1 = resultsAB[2];
X2 = resultsAB[3];
Y2 = resultsAB[4];
POWER2 = resultsAB[5];
printf("X1 = %.4f\n", X1);
printf("Y1 = %.4f\n", Y1);
printf("POWER1 = %.4f\n", POWER1);
printf("X2 = %.4f\n", X2);
printf("Y2 = %.4f\n", Y2);
printf("POWER2 = %.4f\n", POWER2);
}
}
}
}
直接用上述程序测试串口数据接收是没问题的,但是将上面程序集成到emwin程序框架后,数据就会偶尔出现乱码,调试时数据是使用串口调试助手发送的,间隔为100ms。
3.emwin程序框架中的main.c程序,在最后调用了mainTask.c(感觉主要是一些初始化)
#include <stdio.h>
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* 开发板硬件bsp头文件 */
#include "./led/bsp_led.h"
#include "./beep/bsp_beep.h"
#include "./usart/bsp_debug_usart.h"
#include "./TouchPad/bsp_touchpad.h"
#include "./lcd/bsp_lcd.h"
#include "./touch/gt9xx.h"
#include "./key/bsp_key.h"
#include "./sdram/bsp_sdram.h"
/* STemWIN头文件 */
#include "GUI.h"
#include "DIALOG.h"
/* FATFS */
#include "ff.h"
#include "diskio.h"
#include "integer.h"
/**************************** 任务句柄 ********************************/
/*
* 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
* 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
* 这个句柄可以为NULL。
*/
/* 创建任务句柄 */
static TaskHandle_t AppTaskCreate_Handle = NULL;
/* LED任务句柄 */
static TaskHandle_t LED_Task_Handle = NULL;
/* Touch任务句柄 */
static TaskHandle_t Touch_Task_Handle = NULL;
/* GUI任务句柄 */
static TaskHandle_t GUI_Task_Handle = NULL;
/******************************* 全局变量声明 ************************************/
/*
* 当我们在写应用程序的时候,可能需要用到一些全局变量。
*/
FATFS fs; /* FatFs文件系统对象 */
FIL file; /* file objects */
UINT bw; /* File R/W count */
FRESULT result;
FILINFO fno;
DIR dir;
static void AppTaskCreate(void);
static void LED_Task(void* parameter);
static void Touch_Task(void* parameter);
static void GUI_Task(void* parameter);
static void BSP_Init(void);
static void AP6181_PDN_INIT(void);
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
/* 开发板硬件初始化 */
BSP_Init();
xReturn = xTaskCreate((TaskFunction_t)AppTaskCreate,/* 任务入口函数 */
(const char* )"AppTaskCreate",/* 任务名称 */
(uint16_t )512, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )1, /* 任务的优先级 */
(TaskHandle_t )&AppTaskCreate_Handle);/* 任务控制块指针 */
/* 启动任务调度 */
if(pdPASS == xReturn)
vTaskStartScheduler();/* 启动任务,开启调度 */
else
return -1;
while(1);/* 正常不会执行到这里 */
}
/**
* @brief 任务创建函数
* @note 为了方便管理,所有的任务创建都放在这个函数里面
* @param 无
* @retval 无
*/
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
taskENTER_CRITICAL();//进入临界区
// xReturn = xTaskCreate((TaskFunction_t)LED_Task,/* 任务入口函数 */
// (const char* )"LED_Task",/* 任务名称 */
// (uint16_t )128, /* 任务栈大小 */
// (void* )NULL, /* 任务入口函数参数 */
// (UBaseType_t )4, /* 任务的优先级 */
// (TaskHandle_t )&LED_Task_Handle);/* 任务控制块指针 */
// if(pdPASS == xReturn)
// printf("创建LED1_Task任务成功!\r\n");
xReturn = xTaskCreate((TaskFunction_t)Touch_Task,/* 任务入口函数 */
(const char* )"Touch_Task",/* 任务名称 */
(uint16_t )256, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )3, /* 任务的优先级 */
(TaskHandle_t )&Touch_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
printf("创建Touch_Task任务成功!\r\n");
xReturn = xTaskCreate((TaskFunction_t)GUI_Task,/* 任务入口函数 */
(const char* )"GUI_Task",/* 任务名称 */
(uint16_t )1024, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )2, /* 任务的优先级 */
(TaskHandle_t )&GUI_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
printf("创建GUI_Task任务成功!\r\n");
vTaskDelete(AppTaskCreate_Handle);//删除AppTaskCreate任务
taskEXIT_CRITICAL();//退出临界区
}
/**
* @brief LED任务主体
* @note 无
* @param 无
* @retval 无
*/
static void LED_Task(void* parameter)
{
while(1)
{
LED3_TOGGLE;
vTaskDelay(1000);
}
}
/**
* @brief 触摸检测任务主体
* @note 无
* @param 无
* @retval 无
*/
static void Touch_Task(void* parameter)
{
while(1)
{
GT9xx_GetOnePiont();//触摸屏定时扫描
vTaskDelay(20);
}
}
/**
* @brief GUI任务主体
* @note 无
* @param 无
* @retval 无
*/
static void GUI_Task(void* parameter)
{
/* 初始化STemWin */
GUI_Init();
/* 开启多缓冲 */
WM_MULTIBUF_Enable(1);
while(1)
{
MainTask();
}
}
/**
* @brief 板级外设初始化
* @note 所有板子上的初始化均可放在这个函数里面
* @param 无
* @retval 无
*/
static void BSP_Init(void)
{
/* CRC和emWin没有关系,只是他们为了库的保护而做的
* 这样STemWin的库只能用在ST的芯片上面,别的芯片是无法使用的。
*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
/*
* STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15
* 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
* 都统一用同一个优先级分组,千万不要再分组,切记。
*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* LED 初始化 */
LED_GPIO_Config();
/* 串口初始化 */
Debug_USART_Config();
/* 蜂鸣器初始化 */
Beep_GPIO_Config();
/* 初始化触摸屏 */
GTP_Init_Panel();
/* SDRAM初始化 */
SDRAM_Init();
/* LCD初始化 */
LCD_Init();
/* 禁用WiFi模块 */
AP6181_PDN_INIT();
/* 挂载文件系统,挂载时会对SD卡初始化 */
result = f_mount(&fs,"0:",1);
if(result != FR_OK)
{
printf("1\n");
while(1);
}
}
/**
* @brief AP6181_PDN_INIT
* @note 禁止WIFI模块
* @param 无
* @retval 无
*/
static void AP6181_PDN_INIT(void)-省略
|
|