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

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

 

  今天在做一个简单的在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);
	}
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

small_planet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值