[资料分享] AVR单片机程序框架(最简操作系统)

lvhoujun   2014-2-8 15:57 楼主
这是本人以ATMEGA128为例编写的C语言程序框架,做简单的修改即适合AVR所有单片机。可以说是一个单片机最简操作系统,希望各位同仁补充改进。
AVR单片机程序框架.rar (62.21 KB)
(下载次数: 122, 2014-2-8 15:53 上传)

程序框架采用事件触发机制,主程序可以编程为按事件优先级运行,也可以编程为顺序运行。主程序在App.c文件中,框架的核心程序在OSAL_App.h中,程序事件和运行标志定义在App.h文件中。

回复评论 (8)

下来看看 多谢楼主分享

点赞  2014-2-8 16:25
学习,开眼界
点赞  2014-2-8 21:01
有位同学询问按键怎样处理,我今天改写了在程序框架中Hal_Key.h文件,以及心跳中断中增加了按键循环检测功能,在App.h文件中定义按键事件(#define KEY_CHANGE_EVT   0x8000),在App.c主程序中处理按键。作为程序框架的一个改写例子,供大家参考。
AVR单片机程序框架(按键处理例程).rar (68.86 KB)
(下载次数: 53, 2014-2-9 15:09 上传)

点赞  2014-2-9 15:09
感谢楼主分享            
我从不担心我努力了不优秀,只担心优秀的人都比我更努力。如果你无法忍受孤独,就不要追逐梦想。每一个优秀的人,都有一段沉默的时光。在那一段时光,你付出了很多努力,忍受孤独和寂寞,不抱怨不诉苦,最后渡过了这
点赞  2014-2-9 16:55
点赞  2014-2-11 19:04
谢谢分享
点赞  2014-2-12 01:02
有同学询问怎样使主程序按事件优先级处理?怎样按顺序处理?在这里给大家介绍一下:
在程序框架的App.c文件中,主程序:
int main(void)
{
     ......//各种资源初始化
     wdt_enable(WDTO_2S);//使能看门狗   
     while(1)
    {
           wdt_reset();//复位看门狗
           if( events )
          {
                //处理事件函数
               events = process_evts();
          }
     }
}  
可以看出,主程序就是循环查询有无事件发生,如果有事件发生,就运行事件处理函数process_evts();

现在我们看事件处理函数:
int process_evts(void)
{
      if( events & OCCURRED_1_EVT )
     {
            ;//添加事件OCCURRED_1_EVT的处理函数   
           return (events ^= OCCURRED_1_EVT);
      }

       if( events & OCCURRED_2_EVT )
      {
              ;//添加事件OCCURRED_2_EVT的处理函数
              return (events ^= OCCURRED_2_EVT);
       }
       return 0;
}
该函数查询发生了什么事件,假设是OCCURRED_1_EVT 。关键是事件处理完后,有一句: return (events ^= OCCURRED_1_EVT);这句话的意思是,清零该事件,退出process_evts()。如果 OCCURRED_1_EVT事件一直发生,下次进入事件处理时,仍然只处理OCCURRED_1_EVT, OCCURRED_2_EVT永远得不到处理。除非不发生OCCURRED_1_EVT事件,才可能处理 OCCURRED_2_EVT事件。也就是说, OCCURRED_1_EVT比 OCCURRED_2_EVT优先级高。这就是按事件的优先级运行。
这种编程方法的优点是,保证优先级高的事件在最短的时间内得到处理。

那么,程序怎样按顺序运行?
我们把return (events ^= OCCURRED_1_EVT);改成:
events ^= OCCURRED_1_EVT
不用return返回,则处理完OCCURRED_1_EVT事件处理程序后,则继续执行下一个if语句,从而使 OCCURRED_2_EVT 事件得以处理。
这就是按事件顺序执行程序。
如果程序中有两个以上的事件都必须尽快处理,就把顺序运行和优先运行结合起来使用。比如前两个事件处理不加return返回语句,第三个以后再加返回语句等等。

   还有一些状况,虽说事件发生了,但由于某些条件不具备,还不能处理该事件怎么办?比如GSM通信编程时,发生了一个发送短信事件SMS_SEND_EVT,如果此时正在传送TCP报文,必须等到关闭TCP连接后,才能发送短信。那么我们在process_evts()中可以这样处理:
if( events &SMS_SEND_EVT)
{
        if(  TCP连接还没有关闭 )
        {
                continue;
        }
        ......     //发送短信     
        return (events ^= SMS_SEND_EVT);
}
即在这次执行process_evts()的时候,用 continue退出该事件处理程序,保留SMS_SEND_EVT事件,继续执行后边的事件处理程序。等到下次运行process_evts()时再处理SMS_SEND_EVT事件,直到 TCP连接关闭后,发出短信,才能清零SMS_SEND_EVT。      
点赞  2014-2-25 23:09
从大家给我的QQ留言中,看到有些初学者看不懂这个程序框架。下面我想详细讲解一下: 该程序框架的核心程序在OSAL_App.h文件中。请打开该文件参考我下面的讲解阅读程序。 其中,有一个void osal_heartbeat(void)函数,该函数的功能是启动T2定时器,并每10毫秒产生一次定时中断。这是程序框架的心跳,一般在主程序初始化完成之后立即执行该程序,使程序的心脏每10毫秒跳动一次。 SIGNAL(SIG_OUTPUT_COMPARE2)是T2中断的处理程序,即每10毫秒自动执行一次该处理程序。该中断程序首先检查UART0和UART1是否收到一个完整的报文,然后查看是否有新的按键按下,再然后查询是否有延迟事件要启动。 至于检查UART0和UART1是否收到一个完整的报文的机理在后续UART0和UART1驱动中讲解;查看是否有新按键按下的机理在后续按键驱动中讲解。我们首先看中断程序是如何处理事件的。 (待续) 本帖最后由 lvhoujun 于 2014-3-15 09:47 编辑
点赞  2014-3-15 09:45
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复