一、引言
这是关于《单片机商业编程之从零搭建低功耗系统》的第一篇章,个人善忘,平常项目设计当中的一些思路,以前年轻的时候习惯性的录制成视频,也算是当作是自己的笔记,无奈现在喉咙实在扛不住,因此先尝试用文章的形式写出来试试。
单片机编程本身并不复杂,由于资源受限,往往最求代码执行效率和代码使用效率优先;在较弱性能的单片机上,平常使用实时操作系统的机会也少,很多时候都是自己写的一个简单框架能够满足大部分应用需求,那么简单的框架怎样才算是比较实用呢,这虽然没有统一的标准,但是却可以借鉴优秀的框架,以前也喜欢研读像ucos、ucgui、lwip、ble相关的内核或者协议栈,会使得自己受益良多,然后将其框架思维做尽量的简化应用于单片机项目中,使得项目编程效率大大提高。对于低功耗系统设计的思路,主要参考了低功耗蓝牙的系统而总结出来的。
既然是从零开始,那么就从最基本的开始讲起,逐渐实现完整的低功耗系统,注意是一个系统,从结构上类似我们的平常的freeRTOS这些,但是它并不是真正的系统,只是用起来看似规范很多,这样既能够保障占用单片机资源最少,又能保障使用规范,使得移植更方便。
二、本文内容
本文主要讲解面向事件编程的逻辑,这也是低功耗设计最关键的编程思维。何为事件,即所有触发需要执行的代码的条件,都是事件,比如某个按键按下算一个事件、按键抬起也算一个事件,一个定时器定时事件到达是一个事件,接收到一个串口数据或者接收到一整包串口数据都算一个事件。
三、事件详解
单片机编程实际就是根据某个条件,然后执行某些动作,这个条件可能是某个按键,也可能是某个定时任务。
在没有达到这个条件的时候,单片机一般都是空闲的,而我们大部分做法就是在mian的while(1)中不断的去轮询是不是有某个条件达到,举个最最简单的例子就是定时器的t_flg是否满足条件,满足就执行指定动作。而这些空闲阶段单片机在死循环中快速执行,就等于单片机时时刻刻在消耗电流,使得达不到低功耗的要求。
#include "stdint.h"
uint8_t t_flag = 0;
int main(void)
{
main_init();
while (1)
{
if(t_flag)
{
t_flag = 0;
//执行指定任务
//...
}
}
}
void timer_interrupt(void)
{
t_flag = 1; //100ms中断
}
对于t_flag=1而言,它就是一个事件,那么100ms内,在while(1)中可能有99.9%的时间都是浪费的,那么怎样把99.9%的能量都节约起来呢?我们只要设定定时器唤醒单片机,然后让单片机进入休眠即可,这样单片机平常只处于休眠中断,在timer中断来临的那一刻,它才进入中断设置t_flag=1,然后while(1)才继续往下执行,就达到了节约99%+的能量。
#include "stdint.h"
uint8_t t_flag = 0;
void set_wakeup_condition(void)
{
//设定定时器中断唤醒单片机
//...
}
void mcu_sleep_and_wait_wakeup(void)
{
//单片机进入休眠状态
//...
}
int main(void)
{
main_init();
while (1)
{
set_wakeup_condition();
mcu_sleep_and_wait_wakeup();
if(t_flag)
{
t_flag = 0;
//执行指定任务
//...
}
}
}
void timer_interrupt(void)
{
t_flag = 1; //100ms中断
}
四、总结
事件编程起始很好理解,而且我们一直都在用,只是要使得事件编程写法更规范,那么我们可以用函数进行封装,利用宏定义进行规范定义,就使得可读性更强,后续章节会慢慢使其更规范。
下一节:02-单片机商业项目编程,从零搭建低功耗系统设计-CSDN博客