51核类型单片机是目前应用较为广泛的一款MCU,编写单片机程序常常成为嵌入式软件开发软件入门级的训练。一般而言,51程序代码量少,考虑模块化程序相对较少。一种常规做法就是主程序采用while循环,再者通过中断中设置一些标志位;笔者在51单片机程序开发过程,发现公司的单片机程序更新很快,基本每个人都要修改一点,一段时间后原有代码想法都很难找到。还有一种是移植操作系统后,然后进行代码规范化,比如移植UCOS-ii等嵌入式操作系统,但是往往代码量增加很快,对存储容量本来就少的51单片机有较大的压力。电子园51单片机学习网r)U\/Wt6|:l0@
51模块化程序设计的最重要问题,笔者认为就是找到一种合理的程序结构,而且它能胜任实际的51单片机程序开发。考虑到文中前面提到的问题,笔者主要针对第一种主程序while循环结构进行修改。首先增加任务结构体定义,其中函数指针pFun指向实际的任务函数,nDelay表示延时时间,以ms为单位,以下涉及时间都一样的。而nRunme表示运行的次数,nPeriod表示运行的时间周期。电子园51单片机学习网.?!u ~-P~6XV
…
vB \Us6W]b5d8B0struct _TASK_DEFINE
/CS/mv+Ip0{
N(S;od1XUc0void (code *pTask)(void); //指向实际任务函数
+y.Z0E&mnw[0UINT16 nDelay; // 延时时间电子园51单片机学习网l"KF,Q#I2o2Z3L e%w;S
UBYTE8 nRunme; // 运行次数
Z8u%|A6V4S0UINT16 nPeriod; // 运行周期
4hYqL1y;MP&V h0} S_TASK , *pS_TASK;电子园51单片机学习网[#E&g!J&c
…
b i `)qG/^F0系统中设定全局的任务列表变量S_TASK SCH_TASK_G[TASK_TOTAL_NUM];其中TASK_TOTAL_NUM为系统设定的任务最大数量。在进入while主循环前,需要添加相应的任务,采用函数SCH_ADD_TASK(…),后面再详细阐述。系统的主循环采用遍历的方法,实现实际任务的运行。
O y4A-{7L%K*C#Y+R0…
/f9C)Z2m1Ta0while(1)
L }v;bI0g0{电子园51单片机学习网/} [nk"r4w)a];B"F:V
SCH_DISPATCH_TASK(); /*遍历实现任务切换*/电子园51单片机学习网J3\(F1XL:WO
/*51系统进入空闲模式,定时中断能唤醒*/
aLY;V d4REn }0SCH_Goto_Sleep();
@w$E$N?k6b5i9@:GRf0}
TTZ3rN {,o%[0…
jN9k#hb!Y.l:A^`_7K0SCH_DISPATCH_TASK遍历函数的主要实现代码如下,
"m%v.W7|6T] dF0…电子园51单片机学习网m NPo7z.E'dq
UBYTE nIndex;
x+HL.Qj|/o i0for(nIndex=0; nIndex < TASK_TOTAL_NUM; nIndex++)
#kbvzJ1t0{
{.FN#Dgu3Sn$g \0if( (SCH_TASK_G+nIndex)-> nRunme > 0)
f!dlf^J5V5d {0{电子园51单片机学习网!}V,TEM MW$@/V,V
(*(SCH_TASK_G+nIndex)->pTask)(); //运行实际的任务
0D B8a r0o1Q8C"kD0(SCH_TASK_G+nIndex)-> nRunme--; //运行次数减1
3Q3E f!^%oc0/d"SPbE0
if((SCH_TASK_G+nIndex)-> nPeriod == 0) /*执行一次型任务后删除之*/电子园51单片机学习网!`O8G&q+y
{ SCH_DEL_TASK(nIndex); }
im\O:["M0Dx0}
*YLnh@s M1}!\u0…
2I a/n W1_GQ,y'V-b'T8d0定时器实现1ms定时中断,在中断中进行任务刷新(SCH_UPDATE_TASK函数),这也是实现系统结构关键一步。定时器可以采用定时Timer0,有的52型单片机也可以采用定时器Timer2,总之实现1ms时间的定时中断。电子园51单片机学习网X@pg?
SCH_UPDATE_TASK()的主要实现代码如下
+t;M`W&J:S6J0…
;nK DX"^,ve0UBYTE8 nIndex;
~Qd&l&[C s7Im0for(nIndex=0; nIndex < TASK_TOTAL_NUM; nIndex++)电子园51单片机学习网)e|:|kAi E#H/j
{电子园51单片机学习网,M"yr&EBP4?D
if( (SCH_TASK_G+nIndex)-> nDelay == 0)
"f qv9JuOA"J"O0{电子园51单片机学习网@"B V FJC,}!iL
(SCH_TASK_G+nIndex)-> nRunme++; //运行次数加1电子园51单片机学习网D1e;k [!Fm o
/*获得实际的时间周期*/
6k0AK9K;li ?0if((SCH_TASK_G+nIndex)-> nPeriod > 0)
!O*L{[]Q0{
H8nRBOV0(SCH_TASK_G+nIndex)-> nDelay = (SCH_TASK_G+nIndex)-> nPeriod;
kVW[/Y~B0}电子园51单片机学习网$vna^q
}电子园51单片机学习网|6tN`c2WF
else电子园51单片机学习网bl4s1[G#meu3G.f
{ (SCH_TASK_G+nIndex)-> nDelay--; }
uQ9_ zq3@Vx;s(y0<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Yws#Y,Ms yV;GQp0
}
Z'_PQ*y u?0…
[m ]4W6ht;N"l*X0在进行主程序while循环前,必须要添加相应的任务函数SCH_ADD_TASK,其主要的实现代码如下:
O$| sT6I0…电子园51单片机学习网@7g7B?dMU A
UBYTE8 SCH_ADD_TASK( void (code *pFun)(void),
U@ {(jIX G%G0const UINT16 tDelay,电子园51单片机学习网HW*{b y"L%Ni;j
const UINT16 tPeriod)电子园51单片机学习网G1?z!HH\
{
Vde(Vev A)k0UBYTE8 nIndex;
~4tVz]1_AF^?0t5l GyS])|0
nIndex=0;电子园51单片机学习网`xa$~ LJtm
while( (SCH_TASK_G+nIndex)-> pTask != NULL ) && (nIndex < TASK_TOTAL_NUM) )
X$k Kz-gJ0{ nIndex ++ ; }电子园51单片机学习网Gj6@6q[ j9[3r.j3qu
if( nIndex == TASK_TOTAL_NUM)电子园51单片机学习网h+F6j|0@].H9N2u
{ return TASK_OVER_FLOW; }电子园51单片机学习网3H3oq0a`7ouA_
/* 增加任务到列表中*/
$g-^}JB%k0SCH_TASK_G[nIndex] ->pTask = pFun;
D.B ~)P!p&r8hw0SCH_TASK_G[nIndex]->nDelay = tDelay;电子园51单片机学习网.b,s[+AI-G*vC
SCH_TASK_G[nIndex]->nRunme = 0;电子园51单片机学习网|sH"g0ry
SCH_TASK_G[nIndex]->nPeriod = tPeriod;电子园51单片机学习网$I$n*L$^r6uh
return nIndex;电子园51单片机学习网6M8vOB6n-Z-Jy
}
)f/ZK*v&C B c0…电子园51单片机学习网5Gp^D \;G#UF? f-p
主体代码基本实现,51系统开发主要的工作就是增加一个任务函数,在实际的任务实现相应的功能,这样构成的单片机系统就比较好控制,维护代码也很简单。
*a)NO`_1f;~`0当然还有就是任务函数的执行时间必须控制1ms以内,即是每1ms时间标度中要执行的任务时间不超过1ms。如果执行时间较长的任务,总有一些办法对其划分为较小的若干个小任务。
DVvl8^a)sR%O C0笔者在实际开发中也设想过一个问题,假定A任务每2ms执行一次,执行需要的时间为0.5ms;而B任务每4ms执行一次,执行所需的时间为0.5ms。如果两个任务运行在同一个时标(1ms)中,就可能导致运行单个时标运行任务超过1ms的限制;由于4ms的间隔也是2ms延时的整数倍关系,执行完全有可能。一种常见的解决方法是加大定时中断时间的时标,把1ms修改成2ms,但是同时系统的时间敏感度减少了。笔者想到一种方法,设置 两个任务结构体中延时nDelay不同,A任务延时初值0,而B任务延时初值为1;这样实际A任务执行时间标度为2*n,而B为4*m+1(n, m为正整数),而2*n != 4*m+1(奇偶数),从而使A与B任务永远不可能同时在一个时标(1ms)中执行。电子园51单片机学习网EO~0^ Iv
以上是在51单片机开发模块化设计的一些想法,在几个实际项目开发也得到较好的应用,当然可能还会有一些没有考虑的问题,欢迎各位提出更好的建议!
'q z?1So ~-MhPQ0电子园51单片机学习网0Y%zyu.NW,J~
参考文章及网站:
*H Z#U(tgL p6r1J01. Keilc开发文档C51,A51电子园51单片机学习网z(P'g7YvQ6H
2. 基于时间触发系统的嵌入式系统模式设计Chaper9, Chapter 13, Michael J. Pont
~n^ ~#Ut _ ?03. www.21ic.com的单片机论坛电子园51单片机学习网"Z j~uV1ny|*Nl3O0L
文章评论(0条评论)
登录后参与讨论