作业中经过探索试验,总结出单片机大致使用程序的架构有三种:
1. 简略的前后台次序履行程序,这类写法是大多数人运用的办法,不需用考虑程序的具体架构,直接经过履行次序编写使用程序即可。
2. 时刻片轮询法,此办法是介于次序履行与操作体系之间的一种办法。
3. 操作体系,此法应该是使用程序编写的最高境地。
下面就别离谈谈这三种办法的利害和习惯规模等。
一、次序履行法
这种办法,这使用程序比较简略,实时性,并行性要求不太高的情况下是不错的办法,程序规划简略,思路比较明晰。可是当使用程序比较复杂的时分,假如没有一个完好的流程图,恐怕他人很难看懂程序的运转状况,并且跟着程序功用的增加,编写使用程序的工程师的大脑也开端紊乱。即不利于晋级保护,也不利于代码优化。自己写个几个比较复杂一点的使用程序,刚开端便是运用此法,终究尽管能够完结功用,可是自己的思想一向处于紊乱状况。导致程序一向不能让自己满足。

这种办法大多数人都会选用,并且咱们承受的教育也根本都是运用此法。关于咱们这些根本没有学习过数据结构,程序架构的单片机工程师来说,无疑很难在使用程序的规划上有一个很大的进步,也导致了不同工程师编写的使用程序很难彼此利于和学习。
自己主张,假如喜爱运用此法的网友,假如编写比较复杂的使用程序,必定要先理清脑筋,规划好完好的流程图再编写程序,不然结果很严重。当然应该程序自身很简略,此法仍是一个十分有必要的挑选。
下面就写一个次序履行的程序模型,便利和下面两种办法比照:
代 码
/**************************************************************************************
* FuncTIonName : main()
* DescripTIon : 主函数
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
int main(void)
{
uint8 keyValue;
InitSys(); // 初始化
while (1)
{
TaskDisplayClock();
keyValue = TaskKeySan();
switch (keyValue)
{
case x: TaskDispStatus(); break;
。。。
default: break;
}
}
}
二、时刻片轮询法
时刻片轮询法,在许多书本中有说到,并且有许多时分都是与操作体系一同呈现,也便是说许多时分是操作体系中运用了这一办法。不过咱们这儿要说的这个时刻片轮询法并不是挂在操作体系下,而是在前后台程序中运用此法。也是本贴要具体阐明和介绍的办法。
关于时刻片轮询法,尽管有不少书本都有介绍,但大多说得并不体系,仅仅提提概念罢了。下面自己将具体介绍这种形式,并参阅他人的代码树立的一个时刻片轮询架构程序的办法,我想将给初学者有必定的学习性。
在这儿咱们先介绍一下守时器的复用功用。
运用1个守时器,可所以恣意的守时器,这儿不做特别阐明,下面假定有3个使命,那么咱们应该做如下作业:
1. 初始化守时器,这儿假定守时器的守时中止为1ms(当然你能够改成10ms,这个和操作体系相同,中止过于频频功率就低,中止太长,实时性差)。
2. 界说一个数值:
代 码
#define TASK_NUM (3) // 这儿界说的使命数为3,表明有三个使命会运用此守时器守时。
uint16 TaskCount[TASK_NUM] ; // 这儿为三个使命界说三个变量来寄存守时值
uint8 TaskMark[TASK_NUM]; // 相同对应三个标志位,为0表明时刻没到,为1表明守时时刻到。
3. 在守时器中止服务函数中增加:
代 码
/**************************************************************************************
* FuncTIonName : TImerInterrupt()
* Description : 守时中止服务函数
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TimerInterrupt(void)
{
uint8 i;
for (i=0; i《TASKS_NUM; i++)
{
if (TaskCount[i])
{
TaskCount[i]–;
if (TaskCount[i] == 0)
{
TaskMark[i] = 0x01;
}
}
}
}
代码解说:守时中止服务函数,在中止中逐一判别,假如守时值为0了,表明没有运用此守时器或此守时器现已完结守时,不着处理。不然守时器减一,知道为零时,相应标志位值1,表明此使命的守时值到了。
4. 在咱们的使用程序中,在需求的使用守时的当地增加如下代码,下面就以使命1为例:
代 码
TaskCount[0] = 20; // 延时20ms
TaskMark[0] = 0x00; // 发动此使命的守时器
到此咱们只需求在使命中判别TaskMark[0] 是否为0x01即可。其他使命增加相同,至此一个守时器的复用问题就完结了。用需求的朋友能够试试,作用不错哦。。。。。。。。。。。
经过上面临1个守时器的复用咱们能够看出,在等候一个守时的到来的一起咱们能够循环判别标志位,一起也能够去履行其他函数。
循环判别标志位:
那么咱们能够想想,假如循环判别标志位,是不是就和上面介绍的次序履行程序是相同的呢?一个大循环,仅仅这个延时比一般的for循环准确一些,能够完结准确延时。
履行其他函数:
那么假如咱们在一个函数延时的时分去履行其他函数,充分使用CPU时刻,是不是和操作体系有些相似了呢?可是操作体系的使命办理和切换是十分复杂的。下面咱们就将使用此办法架构一向新的使用程序。
时刻片轮询法的架构:
1.规划一个结构体: