程序的多使命和资源复用举例
有一台机电设备,有两个按键,操控设备的两个不同部分。
现要求:
每个按键按下,相应操控程序运转。但两个按键能够一起按下,就是说两个操控程序或许
需求一起运转。运用一个89C52,怎么编写程序?
注:此程序不运用RTOS等操作体系。
/*程序阐明:
一)发生波形能够运用中止上钩数来发生准确的波形。
本答案中为更能表现程序的多使命和资源复用问题,选用主程序循环发生。
二)请特别注意,题意是两个程序在并发运转,实践按本答案能够扩展到N个不同使命一起运转,在此就不评论。
(对大程序结构增加了许多其它的概念)
三)由于在论坛上直接贴出,所以程序放在一个文件中。
应该按Timer.c, Key.c, Const.h(寄存常量界说),Task1, Task2, Answer.c寄存
*/
#include
/*Timer*/
bit fTimer0_2ms; /*T0中止发生的标志,预备传递给主循环*/
bit fSYS_2ms; /*体系T0中止发生的标志,12M,主循环运用*/
bit fSYS_20ms; /*每20MS发生一次的音讯*/
#define INT2MSCOUNT 10 /*发生2MS所需求的时刻次数*/
unsigned char da
#define INT20MSCOUNT 10 /*发生20MS所需求的时刻次数,在20MS根底上*/
unsigned char da
/*KEY*/
unsigned char da
unsigned char da
sbit iKey1=P1^0; /*按键的输进口*/
sbit iKey2=P1^1;
bit fKey1; /*为简单化,没运用行列保存键值,运用标志*/
bit fKey2; /*为简单化,没运用行列保存键值,运用标志*/
/*Task1*/
unsigned char da
unsigned char da
unsigned int da
sbit oTask1=P1^2; /*输出方波口*/
/*Task2*/
unsigned char da
unsigned char da
sbit oTask2=P1^3; /*输出方波口*/
/*—————————————————————————*/
/*发生以1MS为根底的体系守时信号,T0作为基准守时器*/
/*************************************************
守时器T0初始化0.2MS,12M
*************************************************/
void Timer0_Init()
{
TMOD|=0x2; /*8位守时器*/
TL0=TH0=~(200)+1; /*12M*/
TR0=1;
ET0=1;
}
/*************************************************
守时器0的中止服务,发生fTimer0_2ms
*************************************************/
void timer0(void) interrupt 1 /*T0中止*/
{
mTimer_2msReg–;
if(mTimer_2msReg==0){
mTimer_2msReg=INT2MSCOUNT; /*发生1MS所需求的寄存器*/
fTimer0_2ms=1;
}
}
/*************************************************
操控音讯fSYS_2ms
*************************************************/
void Timer0_MainLoop()
{
fSYS_2ms=0;
fSYS_20ms=0;
if(fTimer0_2ms){
fTimer0_2ms=0; /*接纳中止过来的时刻标志,转换为音讯*/
fSYS_2ms=1; /*此音讯在一周内有用,被外部程序复用*/
/*发生20MS的音讯*/
mTimer_20msReg–;
if(mTimer_20msReg==0){
mTimer_20msReg=INT20MSCOUNT; /*发生20MS所需求的寄存器,在20MS根底上*/
fSYS_20ms=1;
}
}
}
/*—————————————————————————*/
/*按键扫描,包括两个扫描使命*/
/**********************************************
每次体系时刻进入一次,20ms.这儿把20MS判别放进来,好亮点
按键扫描循环
为简单化,没运用行列保存键值,运用标志
那些重复宣布N键,在这个结构中十分简单加上
**********************************************/
void Key_MainLoop()
{
if(fSYS_20ms==0)return;
switch(mKey1SwapTask){
case 0:/***有按键按下吗?***/
if(iKey1==0){
mKey1SwapTask=1;
}
break;
case 1: /***键按下去抖延时***/
mKey1SwapTask=2; /***延时一个体系时刻***/
break;
case 2: /***键值判别***/
if(iKey1==0){
fKey1=1; /*按键有用*/
mKey1SwapTask=3; /*去按键去抖*/
}
else mKey1SwapTask=0; /*颤动*/
break;
case 3: /***有松开吗?***/
if(iKey1==1){
mKey1SwapTask=4;
}
break;
case 4: /***键松开去抖延时***/
mKey1SwapTask=5; /***延时一个体系时刻***/
break;
case 5: /***键值判别***/
if(iKey1==1){
mKey1SwapTask=0; /*去按键检测开端*/
}
else mKey1SwapTask=3; /*颤动*/
break;
}
switch(mKey2SwapTask){
case 0:/***有按键按下吗?***/
if(iKey2==0){
mKey2SwapTask=1;
}
break;
case 1: /***键按下去抖延时***/
mKey2SwapTask=2; /***延时一个体系时刻***/
break;
case 2: /***键值判别***/
if(iKey2==0){
fKey2=1; /*按键有用*/
mKey2SwapTask=3; /*去按键去抖*/
}
else mKey2SwapTask=0; /*颤动*/
break;
case 3: /***有松开吗?***/
if(iKey2==1){
mKey2SwapTask=4;
}
break;
case 4: /***键松开去抖延时***/
mKey2SwapTask=5; /***延时一个体系时刻***/
break;
case 5: /***键值判别***/
if(iKey2==1){
mKey2SwapTask=0; /*去按键检测开端*/
}
else mKey2SwapTask=3; /*颤动*/
break;
}
}
/*—————————————————————————*/
/*使命一*/
/**********************************************
一个部分输出1HZ的方波,2S后中止。
**********************************************/
void Task1_MainLoop()
{
switch(mTask1Id){
case 0: if(fKey1){
fKey1=0; /*接纳该键值*/
mTask1_1HzReg=500/2; /*1hz时刻寄存器,500ms,以2MS为单位*/
mTask1_2SReg=2000/2; /*2S时刻寄存器,500ms,以2MS为单位*/
oTask1=0;
mTask1Id=1;
}
break;
case 1: if(fSYS_2ms){
mTask1_1HzReg–;
if(mTask1_1HzReg==0){
oTask1=~oTask1;
mTask1_1HzReg=500/2; /*1hz时刻寄存器,500ms,以2MS为单位*/
}
mTask1_2SReg–;
if(mTask1_2SReg==0){
oTask1=1; /*2S时刻到*/
mTask1Id=0;
}
}
break;
}
}
/*—————————————————————————*/
/*使命二*/
/**********************************************
一个一向输出1.2hz的方波,直到按键再次按
**********************************************/
void Task2_MainLoop()
{
switch(mTask2Id){
case 0: if(fKey2){
fKey2=0; /*接纳该键值*/
mTask2_1p2HzReg=416/2; /*1hz时刻寄存器,832/2ms,以2MS为单位*/
oTask2=0;
mTask2Id=1;
}
break;
case 1: if(fKey2){
fKey2=0;
oTask2=1;
mTask2Id=0;
}
else {
if(fSYS_2ms){
mTask2_1p2HzReg–;
if(mTask2_1p2HzReg==0){
oTask2=~oTask1;
mTask2_1p2HzReg=416/2; /*1hz时刻寄存器,832/2ms,以2MS为单位*/
}
}
}
break;
}
}
/*—————————————————————————*/
/*主程序*/
void main(){
Timer0_Init();
EA=1;
while(1){
Timer0_MainLoop();
Key_MainLoop();
Task1_MainLoop();
Task2_MainLoop();
}
}