freertos 发表于 2015-11-18 15:17:56

例程代码微妙延时事宜请教

在跑freertos的例程中有个I2C延时函数:

*********************************************************************************************************
*    函 数 名: i2c_Delay
*    功能说明: I2C总线位延迟,最快400KHz
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
static void i2c_Delay(void)
{
    uint8_t i;

    /* 
      CPU主频168MHz时,在内部Flash运行, MDK工程不优化。用台式示波器观测波形。
      循环次数为5时,SCL频率 = 1.78MHz (读耗时: 92ms, 读写正常,但是用示波器探头碰上就读写失败。时序接近临界)
      循环次数为10时,SCL频率 = 1.1MHz (读耗时: 138ms, 读速度: 118724B/s)
      循环次数为30时,SCL频率 = 440KHz, SCL高电平时间1.0us,SCL低电平时间1.2us

      上拉电阻选择2.2K欧时,SCL上升沿时间约0.5us,如果选4.7K欧,则上升沿约1us

      实际应用选择400KHz左右的速率即可
    */
    for (i = 0; i < 30; i++);
}

为什么不用下面这个延时函数更准确?

*********************************************************************************************************
*    函 数 名: bsp_DelayUS
*    功能说明: us级延迟。 必须在systick定时器启动后才能调用此函数。
*    形    参:n : 延迟长度,单位1 us
*    返 回 值: 无
*********************************************************************************************************
*/
void bsp_DelayUS(uint32_t n)
{
    uint32_t ticks;
    uint32_t told;
    uint32_t tnow;
    uint32_t tcnt = 0;
    uint32_t reload;

    reload = SysTick->LOAD;               
    ticks = n * (SystemCoreClock / 1000000);   /* 需要的节拍数 */

    tcnt = 0;
    told = SysTick->VAL;             /* 刚进入时的计数器值 */

    while (1)
    {
      tnow = SysTick->VAL;   
      if (tnow != told)
      {   
            /* SYSTICK是一个递减的计数器 */   
            if (tnow < told)
            {
                tcnt += told - tnow;   
            }
            /* 重新装载递减 */
            else
            {
                tcnt += reload - tnow + told;   
            }      
            told = tnow;

            /* 时间超过/等于要延迟的时间,则退出 */
            if (tcnt >= ticks)
            {
                break;
            }
      }
    }
}

shouyuxinyan 发表于 2015-11-18 17:03:41

应该可以的吧,cube里面systick中断里面就包含了两个,一个是freertos的心跳一个是hal的延时 和楼主说的很类似

freertos 发表于 2015-11-18 17:46:41

回 shouyuxinyan 的帖子

shouyuxinyan:应该可以的吧,cube里面systick中断里面就包含了两个,一个是freertos的心跳一个是hal的延时 和楼主说的很类似 (2015-11-18 17:03) images/back.gif

那个延时函数用宏定义限制了只在非freertos中使用

woaiwm 发表于 2021-5-19 14:54:20

楼主问题解决了吗?我也遇到了这个问题

eric2013 发表于 2021-5-20 07:43:46

woaiwm 发表于 2021-5-19 14:54
楼主问题解决了吗?我也遇到了这个问题


这两个用那个都一样,区别不大,只是用for循环更灵活,方便修改。bsp_DelayUS并不准确,有抖动

用下面这个是最优

DWT实现一个精确微秒延迟的参考例程
http://www.armbbs.cn/forum.php?m ... id=89128&fromuid=58
(出处: 硬汉嵌入式论坛)
页: [1]
查看完整版本: 例程代码微妙延时事宜请教