⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 多任务操作系统例程.txt

📁 一个任务显示LED
💻 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 + -