uCOS在STM32下打印浮点数问题完美解决

 有问题的打印输出(每次开机只能输出一次,下面是按下复位的):

uCOS在STM32下打印浮点数问题完美解决_第1张图片

 

  今天在做一个简单的在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)而堆栈大小不变还是不能正常输出,你们也出现这种情况的话一种方法不行的话就都试试。

这才是我想要的结果:
uCOS在STM32下打印浮点数问题完美解决_第2张图片

 下面放出这段成功的代码:
 

变量、任务堆栈和优先级定义:

#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);
	}
}

你可能感兴趣的:(#,uCOS,stm32,arm,ucos,uCOS)