有问题的打印输出(每次开机只能输出一次,下面是按下复位的):
今天在做一个简单的在ucos系统下采集STM32F103内部温度后用串口打印,用到邮箱缓冲区传递浮点数温度,但在打印的时候出现问题:串口调试助手中只显示一次温度数据,led小灯也不闪,也就是只进行一次调度呗,刚开始以为是调度问题,首先想到的是在进行温度AD转换时用到delay_ms(5)系统延时,这里面会进行任务调度,于是把他换成软件阻塞延时,还是不行,进行多种尝试之后才发现是卡在了打印浮点数上了,因为我试着把温度转成整数就能正常输出,在裸机下打印输出浮点也是OK的,最后使用如下方法解决:
仅仅是把任务堆栈的空间变大!!!
//原来打印输出有问题的
#define PRINT_STK_SIZE 64
//调大到256
#define PRINT_STK_SIZE 256
看网上说的还有任务堆栈8字节对齐:
//就是在普通的前面加上__align(8)
__align(8) OS_STK PRINT_TASK_STK[PRINT_STK_SIZE];
我试过这种方法,如果我仅仅加上__align(8)而堆栈大小不变还是不能正常输出,你们也出现这种情况的话一种方法不行的话就都试试。
下面放出这段成功的代码:
变量、任务堆栈和优先级定义:
#define START_TASK_PRIO 10 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE 64
//任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);
//采集内部温度任务
//设置任务优先级
#define TSENSOR_TASK_PRIO 6
//设置任务堆栈大小
#define TSENSOR_STK_SIZE 256
//任务堆栈
OS_STK TSENSOR_TASK_STK[TSENSOR_STK_SIZE];
//任务函数
void tsensor_task(void *pdata);
//串口输出任务
//设置任务优先级
#define PRINT_TASK_PRIO 7
//设置任务堆栈大小
#define PRINT_STK_SIZE 256 //任务堆栈大小要大一点
//任务堆栈
OS_STK PRINT_TASK_STK[PRINT_STK_SIZE];
//任务函数
void print_task(void *pdata);
OS_EVENT *mbox;
float temp;
u8 err;
主函数:
int main(void)
{
delay_init(); //延时函数初始化
uart_init(9600); //串口初始化为9600
T_Adc_Init(); //ADC初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
LED_Init(); //初始化与LED连接的硬件接口
OSInit();
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
OSStart();
}
开始任务,执行后挂起:
//开始任务
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
pdata = pdata;
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
mbox=OSMboxCreate((void*)0);
OSTaskCreate(tsensor_task,(void *)0,(OS_STK*)&TSENSOR_TASK_STK[TSENSOR_STK_SIZE-1],TSENSOR_TASK_PRIO);
OSTaskCreate(print_task,(void *)0,(OS_STK*)&PRINT_TASK_STK[PRINT_STK_SIZE-1],PRINT_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
采集温度任务:
//采集内部温度任务
void tsensor_task(void *pdata)
{
float adcx; //数字量值
float a=2.2;
while(1)
{
adcx=(float)(T_Get_Adc_Average(ADC_CH_TEMP,1))*(3.3/4096);
temp=(1.43-adcx)/0.0043+25; //计算出当前温度值
LED0=!LED0;
OSMboxPost(mbox,&temp);
delay_ms(500);
}
}
串口输出任务:
//串口输出任务
void print_task(void *pdata)
{
static u8 i=0;
while(1)
{
OSMboxPend(mbox,0,&err);
printf("----第%d次测温:%.2f----\r\n\r\n",i++,temp);
LED1=!LED1;
delay_ms(500);
}
}