STM32定时器定时时长计算公式

T =(TIM_Period + 1)*(TIM_Prescaler + 1)/ TIMxCLK
// 设置单发模式
LL_TIM_SetOnePulseMode(TIM17, LL_TIM_ONEPULSEMODE_SINGLE);

// 开启关闭 Update 中断
LL_TIM_EnableIT_UPDATE(TIM17);
LL_TIM_DisableIT_UPDATE(TIM17);

// 启用停用 tim
LL_TIM_EnableCounter(TIM17);
LL_TIM_DisableCounter(TIM17);

// 设置计数器
LL_TIM_SetCounter(TIM17, 0);

异步编程
  Ebay技术架构倡导到处异步,异步能够提高系统的可伸缩性,有一种误解:认为异步就会慢于同步,其实异步后才能并行并发,利用多CPU的并行并发处理要比同步串联处理无疑性能要提升多。 异步的目的是从设计上解耦,从执行顺序上进行切分,将串行变成并行。

  传统的同步编程是一种请求响应模型,调用一个方法,等待其响应返回,异步编程就是要重新考虑是否需要响应的问题,也就是缩小需要响应的地方。因为越快获得响应,就是越同步化,顺序化,事务化,性能差化。

  异步编程通常是通过fire and forget方式实现,发射事件后即忘记,做别的事情了,无需立即等待刚才发射的响应结果了。(发射事件的地方称为生产者,而将在另外一个地方响应事件的处理者称为消费者)

  关键问题是我们为什么要等待响应呢?因为希望基于响应再继续执行一些逻辑,换一个思路,将这些逻辑移植到事件的消费者那里去做,而不是在当前生产者实现,这其实也是reactive编程的一个特点。

  比如x是1,y=x+1,那么y是2, 如果x变为3,y还是3,通过reactive函数编程,时刻观察x变化,x一旦变为3,观察者也就是消费者响应将y变成3+1。

  所以,异步编程是一种事件驱动编程,需要完全改变思路,将“请求响应”的思路转变到“事件驱动”思路上,是一种软件编程思维的转变。

  基于异步通信的应用程序实现了松耦合的设计,好过于纯粹基于同步的方法调用。生产者和消费者可以各自实现调用,不要关心事件是如何传播的细节,通过接口实现通信。这就易于延伸,发展和维护,带来更多的灵活性,并降低了维护成本。

  一个非阻塞的异步应用程序在重负载下可以拥有更低的延迟和更高的吞吐量,这将导致更低的运营成本,提高了资源利用率以及良好的终端用户体验。

  当应用程序遭遇高性能和可扩展性的要求时,这时很难预测会出现瓶颈的地方。因此,重要的是,将整个解决方案都设计为异步和非阻塞(整个系统都是)。

参考资料:
https://www.jdon.com/asynchronous.html
https://www.sohu.com/a/305434146_120104204

// 发送广播消息
process_post(PROCESS_BROADCAST, serial_line_event_message, buf);

// 给自己发送消息
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL));

// 根据消息队列的特性,如果收到自己发送的消息,说明上一条广播消息肯定被所有进程执行完毕了。
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE);

睡眠:关闭mcu核心
停机:关闭mcu核心,关闭1.8v区域时钟,关闭振荡器,电压调节器开启节能模式(可选)
待机:关闭mcu核心,关闭1.8v区域时钟,关闭振荡器,关闭电压调节器

L系列低功耗运行模式,降低电压调节器输出功率 (LPRUN)
L系列range,调整电压调节器输出电压 (VOS)

唤醒电路只有在待机模式启用时才启用,唤醒后待机电路就停止了。(WIC)

相关寄存器:
SEVONPEND
PDDS
LPDS
SLEEPDEEP
ULP (关闭参考电压)