ARM 循环阻塞延迟函数

串行驱动的关键是双方能够按照既定的时序进行检测、设置相关引脚上的电平,比如单总线、I2c这样基本的可以用GPIO模拟的时序协议,需要主从双方,必须在链路接口内严格按照微妙级的延迟单位进行时序同步。 所以,在这种对时间要求很敏感的情况下,一般都会考虑到用循环等待检测的方式来拖住时间窗,而且近似微妙的阻塞等待一般也不会对整个系统的用户体验造成太大的影响。 下面是在实际经验中积累的,微妙延迟的方法。

  1. ARM-CORTX-M0

M0 HC32F110L上的延迟,可以精准到微妙。可以用systic,也可用while阻塞循环等待。

复制代码
/******************************************************************************
 * systic 
 * xus:
 *     use this delay function when time >= 20 
*******************************************************************************/
void jbf_systic_us_ex(uint32_t xus)
{ 
 	SysTick->LOAD = (xus - 18) * (JBF_SISTICK_VALUE / 1000000);
	SysTick->VAL = 0;
	SysTick->CTRL = 0x01;
	while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
	SysTick->CTRL &= ~(0x01 << SysTick_CTRL_ENABLE_Pos);
}
/******************************************************************************
 * 24M 1US delay,
 * ??????????????1us??????
*******************************************************************************/
 
void jbf_delay_24M_us(void)
{
	int xus = 1;
	while( xus--)
	{
		__NOP();__NOP();
	}
	 
}

void jbf_delay_24M_xus(uint16_t xus)
{
	uint16_t j;
	while (xus--)
	{
		j = 2; //
		while (j--)
		;
	}
}
  1. ARM-CORTEX-M4

    /**********************************************************

    • DEC: 200M MPLL us delay function.
    • PARAM: n = nus
    • RETURN: none
      **********************************************************/
      void delay_nus(uint16_t n)
      {
      uint16_t j;
      while(n--)
      {
      j = DELAY_ADJUSTMENTS;//
      while(j--);
      }
      }
      extern uint32_t SystemCoreClock; /!< System clock frequency (Core clock) /
      /
    • base interval is 60 when LOAD = 1, LOAD + 1 lead the timme plus 30us
    • if the value lager than 60, and times of 30, then use this function
    • (time - 60) / 30 - 1;
    • time = 180 , load = (180 - 60) / 3 + 1 = 5;

    */

    void delay_30Tnus(uint16_t n)
    {
    uint32 _load = (n - 60) / 10 / 3 + 1;
    SysTick->LOAD = _load;
    SysTick->VAL = 0;
    SysTick->CTRL = 0x01;
    while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
    SysTick->CTRL &= ~(0x01 << SysTick_CTRL_ENABLE_Pos);
    }

    /**********************************************************

    • DEC: 200M MPLL ms delay function.
    • PARAM: n = mus
    • RETURN: none
      ***********************************************************/
      void delay_nms(uint16_t n)
      {
      while(n--)
      {
      delay_nus(1000);
      }
      }

实际就两种方式比较通用的,一个是systic,这个真的要看systic分到的频率了, 如果本身频率很低,那么在微妙的精度行还是有些误差的。

另一种方式就是利用CPU的加法周期来做延迟,这个目前看来也有一定的可用性,关键是要找好指令周期的倍数。拿示波器实际调试可以作证得出最精准的延迟。

/*DELAY HC32F60,pclk 200MHZ*/

#define DELAY_ADJUSTMENTS 12

void delay_nus(uint16_t n)

{

uint16_t j;

while(n--)

{

j = DELAY_ADJUSTMENTS;//

while(j--);

}

}

相关推荐
2CM_Embed5 小时前
Altium Designer 原理图与 PCB 快速相互定位:Cross Probe 交叉探针
嵌入式硬件·pcb·altium designer·c2000
恒锐丰-罗生7 小时前
宽压大电流同步降压优选|CN3906 DC-DC 电源芯片,车载 / 工控 / IoT 全能供电方案
嵌入式硬件·硬件工程
happygrilclh10 小时前
STM32,串口单字节中断接受,每次上电后,会收到一个0x00的解决办法。
单片机·嵌入式硬件
智闲电子设计11 小时前
STM32 独立看门狗 IWDG 实战:系统跑飞,它来兜底复位
stm32·单片机·嵌入式硬件
zcmodeltech12 小时前
智能制造教学实训沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的工业机器人-智慧工厂-数字孪生全场景联动方案
数据库·stm32·嵌入式硬件·机器人·制造·多分类
程序员与背包客_CoderZ13 小时前
Linux D-Bus通信协议详解:从入门到C/C++编码实战
linux·服务器·c语言·c++·嵌入式硬件·嵌入式软件·dbus
嵌入式阿蔡14 小时前
HAL库 vs LL库 vs 寄存器:到底用哪个?
c语言·stm32·单片机·嵌入式硬件·嵌入式实时数据库
天空'之城15 小时前
单片机基础核心知识点汇总(三)
单片机·嵌入式硬件
嵌入式阿蔡15 小时前
CAN总线入门:从协议帧到STM32实战
c语言·stm32·单片机·嵌入式硬件·嵌入式实时数据库
硅农程序猿15 小时前
从需求到硅片| 一文讲清数字芯片设计流程
arm开发·硬件架构·risc-v