📄 多任务操作系统例程.txt
字号:
//多任务操作系统例程 RealTime.C V2.00
//参照巨人老师的思路改编昨天的例程,硬件调试通过,这仅是一个很小的演示程序不够严
//谨供大家讨论
//这个思路确实有独到的地方,个人感觉应该继续完善下去;
//参考 C51BBS <<关于多任务操作系统的讨论>> 作者 巨人老师及JIFENG网友
//一个任务显示LED,一个扫描键盘,一个任务将键值转化为显示格式(无时间要求)
//键盘模块完全参照巨人老师例程;
//显示很简单:1、判是否到2ms 2、送显示
//键值处理:1、有无有效信息 2、弹出有效信息处理队列 3、将信息处理;键值处理不随
//1ms动作
//该例子对队列的处理很简单,仅用了一个长度标志,采用循环前移,只能做演示,
//具体的队列处理应专门设计数据结构及其相关算法;还需要高手多指点!!!
//请巨人老师和各位大虾多指点
#include <reg52.h>
#include <absacc.h>
typedef unsigned char uchar ;
typedef unsigned int uint ;
typedef unsigned long ulong ;
sbit WATCHDOG=P3^4; /*清看门狗信号线*/
sfr AUXR=0XBF; //W78E516
sbit A19=P1^6; /*138使能 FLASH高位地址*/
sbit A18=P1^5;
sbit A17=P1^4;
sbit A16=P1^3;
bit SYSTime,SYS1ms;
#define TimeEnable() SYSTime=0; if(SYS1ms){ SYSTime=1; SYS1ms=0; }
uchar NewsStr[9]; //分配按键队列,第1字节为有效按键数目,
uchar d_enable=0; //led的片选
uchar xdata dispbuff[12]; //led显示缓冲
uchar code disprule[17]={0x81,0xF3,0x49,0x61,0x33,0x25,0x05,0xF1,0x01,0x21,
0x11,0x01,0x8d,0x81,0x0d,0x1d,0x7f};
/***************************程序有关定义部分*******************************/
/**********************************************************************
I/O口地址分配
**********************************************************************/
#define BPADDR XBYTE[0XE000] /*蜂鸣器口地址*/
#define KBADDR XBYTE[0XF000] /*键盘扫描口地址*/
#define LEDADDR0 XBYTE[0XC000] /*LED扫描头六位*/
#define LEDADDR1 XBYTE[0XB000] /*LED扫描后六位*/
#define LEDEA XBYTE[0XA000] /*LED位选通地址口*/
#define PRNADDR XBYTE[0XD000] //打印口地址
#define SDPADD1 XBYTE[0X5555] /*FLASH写命令高位地址口*/
#define SDPADD2 XBYTE[0X2AAA] /*FLASH写命令低位地址口*/
#define STBADDR XBYTE[0XE000] //打印STB信号选通
void ScanKey(void); //扫描按键模块
void ShowLed(void); //LED送显示模块
void PushNews(void); //压入按键信息
uchar PopNews(void); //弹出按键信息
void DealNews(void); //处理按键信息
void DealKey(uchar ch); //处理键值
void SysInit(void); //初始化
void Led_Disp(void); //底层显示
uchar kb_hit(void); //有无按下键盘
uchar get_kbch(void); //取键值
void ls_enable(void);
void clrramdate(uchar xdata *ram,uint len);
/**************************************************
*原型:void time0(void) interrupt 1 using 1
*功能:定时器0中断子程序
*说明:产生1ms定时中断
*参数:无
*返回:无
**************************************************/
void time0(void) interrupt 1 using 1 {
TH0=0XFC;
TL0=0X00;
SYS1ms=1;
}
/**************************************************
*原型:void main(void)
*功能:初始化、各个任务进行循环处理
*说明:无
*参数:无
*返回:无
**************************************************/
void main(void) {
SysInit();
while(1) {
TimeEnable();
if(SYSTime) ScanKey();
if(SYSTime) ShowLed();
DealNews();
WATCHDOG=~WATCHDOG;
}
}
/**************************************************
*原型:void ScanKey(void)
*功能:扫描键盘模块
*说明:采用任务模式进行扫描,不循环等待,有效按键压入键盘队列,
*参数:无
*返回:无
**************************************************/
uchar KeyTime,KeyTask; //任务时间参数,任务内模块号
void ScanKey(void) {
uchar ch;
switch(KeyTask) {
case 0: if(kb_hit()) {
KeyTime=30;
KeyTask++;
}
break;
case 1: KeyTime--;
if(KeyTime==0) KeyTask++;
break;
case 2: if(kb_hit()) {
PushNews();
KeyTask++;
}
else KeyTask=0;
break;
case 3: if(!kb_hit()) {
KeyTime=30;
KeyTask++;
}
break;
case 4: KeyTime--;
if(KeyTime==0) KeyTask++;
break;
case 5: if(!kb_hit()) {
NewsStr[0]++;
KeyTask=0;
}
else KeyTask=3;//继续任务号3;
break;
}
}
/**************************************************
*原型:void ShowLed(void)
*功能:将LED缓冲数据送显示
*说明:每2ms送一次
*参数:无
*返回:无
**************************************************/
uchar LedTask,LedTime; //任务时间参数,任务内模块号
void ShowLed(void) {
switch(LedTask) {
case 0: LedTime--;
if(LedTime==0) LedTask++; //任
务加1
break;//时间减1
case 1: Led_Disp();
LedTime=2;
LedTask=0;
break;
}
}
/**************************************************
*原型:void PushNews(void)
*功能:将消息压入堆栈
*说明:但是没有将其置为有效
*参数:无
*返回:无
**************************************************/
void PushNews(void) {
uchar ch;
ch=NewsStr[0];
ch++;
NewsStr[ch]=get_kbch();
}
/**************************************************
*原型:uchar PopNews(void)
*功能:弹出最老消息
*说明:采用依次前移,如果队列大应采用有效算法
*参数:无
*返回:无
**************************************************/
uchar PopNews(void) {
uchar ch,i;
ch=NewsStr[1];
for(i=1;i<6;i++) {
NewsStr[i]=NewsStr[i+1];
}
NewsStr[5]=0;
NewsStr[0]--;
return ch;
}
/**************************************************
*原型:void DealNews(void)
*功能:对按键的处理模块
*说明:无
*参数:无
*返回:无
**************************************************/
uchar DealTask,NewsBuff;
void DealNews(void) {
switch(DealTask) {
case 0: if(NewsStr[0])DealTask++;
break;
case 1: NewsBuff=PopNews();
DealTask++;
break;
case 2: DealKey(NewsBuff);
DealTask=0;
break;
}
}
/**************************************************
*原型:void DealKey(uchar ch)
*功能:对按键进行处理
*说明:无
*参数:要处理的按键键值
*返回:无
**************************************************/
void DealKey(uchar ch) {
uchar i,cl;
for(i=0;i<10;i++) {
dispbuff[i]=dispbuff[i+2];
}
cl=(ch&0x0f);
dispbuff[11]=disprule[cl];
cl=(ch&0xf0)>>4;
dispbuff[10]=disprule[cl];
}
/**************************************************
*原型:void SysInit(void)
*功能:系统初始化
*说明:无
*参数:无
*返回:无
**************************************************/
void SysInit(void) {
ls_enable();
clrramdate(&dispbuff[0],12);
AUXR=AUXR|0x10; //W78E516
BPADDR=0XFF;
TMOD=0x01; //工作方式1
TH0=0xFC;
TL0=0x00;
IP=0X00;
TCON=0X10;
IE=0X82; //开中断硬件优先级相同
}
/**************************************************
*原型:void Led_Disp(void)
*功能:led显示
*说明:将缓冲区数据送显示一次两位
*参数:无
*返回:无
**************************************************/
void Led_Disp(void)
{
uchar num=0x01;
uchar i;
LEDEA=0X00;
LEDADDR0=dispbuff[d_enable];
LEDADDR1=dispbuff[d_enable+6];
for(i=0;i<d_enable;i++) num=num<<1;
LEDEA=num;
d_enable++;
if(d_enable==6)d_enable=0;
}
/**************************************************
*原型:uchar kb_hit(void)
*功能:确定有键按下
*说明:无
*参数:无
*返回:有键按下返回1,否则返回0
**************************************************/
uchar kb_hit(void)
{
KBADDR=0x00;
if((KBADDR&0x7f)==0x7F) return(0);
return(1);
}
/**************************************************
*原型:unsigned char get_kbch(void)
*功能:从键盘取得一个字符
*说明:取得行列号
*参数:无
*返回:输入的字符
**************************************************/
uchar get_kbch(void)
{
uchar rownum,linnum;
uchar check;
uchar kbch;
rownum=1;linnum=1;
check=0xfe;kbch=0;
/*分析按键所在列号(0-4)列*/
KBADDR=check;
while(((KBADDR&0x7f)==0x7F)&&check>0x7f)
{
linnum++; /*原文++linnum ???*/
check=check<<1;
KBADDR=check;
}
/*分析按键所在的行号(0-6)行*/
kbch=KBADDR;
check=0x01;
while((kbch&check)&&(check<0x80))
{
rownum++;
check=check<<1;
}
KBADDR=0xFF;
kbch=rownum<<4;
kbch=kbch+linnum;
return(kbch);
}
/**************************************************
*原型:void ls_enable(void)
*功能:使能138
*说明:无
*参数:无
*返回:无
**************************************************/
void ls_enable(void)
{
A19=1;A18=0;A17=0;A16=0;
}
/**************************************************
*原型:void clrramdate(uchar xdata *ram,uchar len)
*功能:对以ram开始的内存单元len长度个全部清零
*说明:无
*参数:ram起始地址,清零长度
*返回:无
**************************************************/
void clrramdate(uchar xdata *ram,uint len)
{
uint i;
for(i=0;i<len;i++)
{*ram=0;ram++;}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -