从裸机到操作系统

来源:互联网 发布:氪喷淘宝 编辑:程序博客网 时间:2024/05/16 15:29

开始学习单片机那是大二时候的事了,当时最为困惑的是为什么主函数中要是一个while(1),在windows下写c语言程序不就是主函数里面直接写,到最后return 0不就完了么。到后来随着学习的深入,渐渐明白,单片机下的程序可以认为是一个单线程的程序,只能在这个超级循环中往复的运行,最多加一些中断,处理一些异步事件,组成前后台系统,就这样一直幸福的在while(1)中做了一些事情,如下面的实现一个LED小灯以间隔500ms闪烁,多么令人愉快的事情啊。

while(1){    LED0 = 1;    delay_ms(500);    LED0 = 0;    delay_ms(500);}

直到某一天,当我再次的加入一个LED小灯,想实现两个灯分别以500ms和300ms的间隔依次闪烁的时候,我困惑了,这可怎么办?噢,有定时器么,在定时器中断中实现小灯的闪烁不就完了,如下:

while(1){    ;}/* 定时器中断处理函数,500ms执行一次 */void Led0_handler(void){    static char i = 0;    if(i == 0)    {        LED0 = 0;        i = 1;    }    else    {        LED0 = 1;        i = 0;    }}/* 定时器中断处理函数,300ms执行一次 */void Led1_handler(void){    static char i = 0;    if(i == 0)    {        LED1 = 0;        i = 1;    }    else    {        LED1 = 1;        i = 0;    }}

但似乎又有一些问题,你让我的while(1)干什么,呆呆的在那看着,我的定时器就那么几个,你让小灯都用了,其他设备用什么啊,可不可以就在while(1)里面干活,不要让它们 占用我宝贵的定时器资源了。想想办法,那这样吧,状态机或许是一种不错的解决方案。

int count0 = 500;int count1 = 300;int STA = 4;int last_sta0 = 0;int last_sta1 = 0;while(1){    switch(STA)    {        case 0: LED0 = 1;STA = 4;break;        case 1: LED0 = 0;STA = 4;break;        case 2: LED1 = 1;STA = 4;break;        case 3: LED1 = 0;STA = 4;break;        case 4: count0--;count1--;                if(count0 == 0)                {                    count0 = 500;                    STA = last_sta0;                    last_sta0 = ~last_sta0;                }                if(count1 == 0)                {                    count1 = 300;                    STA = last_sta1 + 2;                    last_sta1 = ~last_sta0;                }                break;        default:break;    }}

很显然,没有用定时器并且全部在while(1)中实现,但是只有两个灯,如果5个8个岂不是逻辑特别混乱,还怎么让人看代码呀。并且这种方式存在一个弊端,定时时间并不完全准确,需要准确的测量case 4的间隔时间,如果又有一些中断事件的话那就造成了时间的不确定性。

基于以上种种问题,终于发现在裸机下有些问题解决起来真是费劲,但不用怕,问题都是先发现后解决,不过早已有人替我们解决了这些问题,试试操作系统怎么样?或许会让你一下子豁然开朗,体验到飞一般的感觉。

阅读全文
1 0
原创粉丝点击