uCOSIII使用DS18b20

本文介绍在uCOSIII操作系统中成功调试DS18b20温度传感器的方法,重点讨论了如何利用SysTick实现精确的us级延时,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在uCOSIII下成功调试完成DS18b20,需要注意的是DS18b20的时序操作延时函数,由于需要us级精确延时,所以需要利用SysTick,延时函数参考正点原子的例程进行了修改,适配野火开发板例程,代码如下:

#include "delay.h"

static uint16_t fac_ms=1;   //ms延时倍乘数,在ucos下,代表每个节拍的ms数

#ifdef  OS_CRITICAL_METHOD                      //OS_CRITICAL_METHOD定义了,说明要支持UCOSII             
#define delay_osrunning     OSRunning           //OS是否运行标记,0,不运行;1,在运行
#define delay_ostickspersec OS_TICKS_PER_SEC    //OS时钟节拍,即每秒调度次数
#define delay_osintnesting  OSIntNesting        //中断嵌套级别,即中断嵌套次数
#endif

//支持UCOSIII
#ifdef  CPU_CFG_CRITICAL_METHOD                 //CPU_CFG_CRITICAL_METHOD定义了,说明要支持UCOSIII   
#define delay_osrunning     OSRunning           //OS是否运行标记,0,不运行;1,在运行
#define delay_ostickspersec OSCfg_TickRate_Hz   //OS时钟节拍,即每秒调度次数
#define delay_osintnesting  OSIntNestingCtr     //中断嵌套级别,即中断嵌套次数
#endif

//调用OS自带的延时函数延时
//ticks:延时的节拍数
void delay_ostimedly(uint32_t ticks)
{
#ifdef CPU_CFG_CRITICAL_METHOD
    OS_ERR err; 
    OSTimeDly(ticks,OS_OPT_TIME_PERIODIC,&err); //UCOSIII延时采用周期模式
#else
    OSTimeDly(ticks);                           //UCOSII延时
#endif 
}

//延时nus
//nus为要延时的us数.                                             
void delay_us(uint32_t nus)
{       
    uint32_t ticks;
    uint32_t told,tnow,tcnt=0;
    uint32_t reload=SysTick->LOAD;//LOAD的值           
    ticks=nus*(SystemCoreClock/1000000);//需要的节拍数             
    tcnt=0;
    told=SysTick->VAL;//刚进入时的计数器值
    for(;;)
    {
        tnow=SysTick->VAL;  
        if(tnow!=told)
        {       
            if(tnow<told) tcnt += told-tnow;//这里注意一下SYSTICK是一个递减的计数器就可以了.
            else tcnt += reload-tnow+told;      
            told = tnow;
            if(tcnt>=ticks) break;//时间超过/等于要延迟的时间,则退出.
        }  
    }
}
//延时nms
//nms:要延时的ms数
void delay_ms(uint16_t nms)
{   
    if(delay_osrunning&&delay_osintnesting==0)  //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)       
    {        
        if(nms>=fac_ms)//延时的时间大于OS的最少时间周期 
        { 
            delay_ostimedly(nms/fac_ms);//OS延时
        }
        nms%=fac_ms;//OS已经无法提供这么小的延时了,采用普通方式延时    
    }
    delay_us((uint32_t)(nms*1000));//普通方式延时  
}

为了保证在系统开始运行前能够正确进行延时,将SysTick_Handler函数修改如下:

void SysTick_Handler(void)
{
    if(OSRunning != 0)//系统没有运行,不进行任务调度
    {
        OSIntEnter();  //用于统计中断的嵌套层数,对对嵌套层数+1
        OSTimeTick();  //统计时间,遍历任务,对延时任务计时减1
        OSIntExit();   //对嵌套层数减1,在退出中断前启动任务调度
    }
}

另外,由于DS18b20的延时操作是us级的,因此在读取温度数据时,应该将其设定一个较高的优先级或者关闭系统的任务调度:

//温度采集任务,每秒采集一次温度信息
void Task_DS18b20(void *p_arg)
{
    OS_ERR err;
    (void)p_arg;  //'p_arg'并没有用到,防止编译器提示警告  

    while(1)
    {       
        OSSchedLock(&err);//关闭系统任务调度

        DS18b20_Data = DS18B20_Get_Temp();
        OSTaskQPost((OS_TCB    *)&LCD_TCB,
                    (void      *)&DS18b20_Data,
                    (OS_MSG_SIZE)sizeof(float),
                    (OS_OPT     )OS_OPT_POST_FIFO,
                    (OS_ERR    *)&err);

        OSSchedUnlock(&err);//恢复调度                              
        OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); 
    }
}

这样就可以正确的读取DS18b20的温度信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值