在学习UCOS过程中,想通过串口中断将接收到的数据放到消息队列中去,编写代码如下:
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "stdio.h"
#include "string.h"
#include "includes.h"
//设置任务堆栈大小
#define LED_STK_SIZE 64
#define LED1_STK_SIZE 64
#define LCD_STK_SIZE 64
#define KEY_STK_SIZE 64
#define START_STK_SIZE 512
//设置任务优先级
#define LED_TASK_Prio 6
#define LED1_TASK_Prio 5
#define LCD_TASK_Prio 4
#define KEY_TASK_Prio 2
#define START_TASK_Prio 10
//常量定义
#define N_MESSAGES 200
//任务堆栈
OS_STK TASK_LED1_STK[LED_STK_SIZE];
OS_STK TASK_LED_STK[LED1_STK_SIZE];
OS_STK TASK_LCD_STK[LCD_STK_SIZE];
OS_STK TASK_START_STK[START_STK_SIZE];
OS_STK TASK_KEY_STK[KEY_STK_SIZE];
//声明信号量
OS_EVENT *Str_Q;
//声明队列
void *MsgGrp[N_MESSAGES];
//任务申明
void TaskStart(void *pdata);
void TaskLed(void *pdata);
void TaskLed1(void *pdata);
void TaskLCD(void *pdata);
void TaskKey(void *pdata);
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
OSIntEnter();
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
OSQPost(Str_Q,&Res);
}
OSIntExit();
}
int main(void)
{
SystemInit(); //系统初始化 72M
delay_init(72); //延时初始化
NVIC_Configuration();
uart_init(9600);//串口初始化,波特率9600
LED_Init(); //LED0,LED1端口初始化
KEY_Init(); //KEY端口初始化
delay_ms(500);
OSInit();
OSTaskCreate( TaskStart, //task pointer
(void *)0, //parameter
(OS_STK *)&TASK_START_STK[START_STK_SIZE-1], //task stack top pointer
START_TASK_Prio ); //task priority
OSStart();
return 0;
}
//开始任务
void TaskStart(void * pdata)
{
pdata = pdata;
OS_ENTER_CRITICAL();
Str_Q = OSQCreate(&MsgGrp[0],N_MESSAGES);//创建消息队列
OSTaskCreate(TaskLed, (void * )0, (OS_STK *)&TASK_LED_STK[LED_STK_SIZE-1], LED_TASK_Prio);
OSTaskCreate(TaskLed1, (void * )0, (OS_STK *)&TASK_LED1_STK[LED1_STK_SIZE-1], LED1_TASK_Prio);
OSTaskCreate(TaskKey, (void * )0, (OS_STK *)&TASK_KEY_STK[KEY_STK_SIZE-1], KEY_TASK_Prio);
OSTaskSuspend(START_TASK_Prio); //suspend but not delete
OS_EXIT_CRITICAL();
}
//任务1
//控制DS0的亮灭.
void TaskLed(void *pdata)
{
while(1)
{
LED0=!LED0;
OSTimeDlyHMSM(0,0,0,500);
}
}
//任务2
//控制DS1的亮灭.
void TaskLed1(void *pdata)
{
while(1)
{
LED1=!LED1;
OSTimeDlyHMSM(0,0,1,0);
}
}
//任务3
//按键检测
void TaskKey(void *pdata)
{
u8 *rec;
u8 err;
while(1)
{
rec = OSQPend(Str_Q,0,&err);
printf("%c,",*rec);
}
}
出现问题:使用串口助手每次发送一个字符,可以显示出来,但是连续发送时却全部显示逗号。
请原子老师和各位高手指教为谢!
//***************************************分割线*******************************************************************//
第一次修改:将任务中的局部变量改为static修饰 删除TaskKey中的OSTimeDlyHMSM(0,0,0,200);程序可以接收到数据,但是会丢帧
//***************************************分割线*******************************************************************//
第二次修改:加入OSMutex信号量对串口进行资源共享控制,还是会出现部分的丢帧现象。参考小苗开发板的环形队列,放弃OS的消息队列。代码如下:
使用串口调试助手9600的波特率 20毫秒间隔发送数据未发现丢帧现象!