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

📄 93c46.txt

📁 c51经典子程序代码全集
💻 TXT
字号:
用【 小 | 中 | 大 】字体浏览 
C51编程:老古,其实你的那个编程思路还可以再调整一些 [zilingzhang] [64次] 01-11-22 下午 04:06:53
你可以把任务号及信号值作为函数指针数组的下标,在你的程序里不用那些SWITCH CASE,
直接将任务号及送来的信号值代入函数指针数组  FUNC[TASKID][NUM],这样你的所有处理
都可以用独立的小函数模块来处理,在程序的开始将这些函数地址赋给函数指针数组即可,
主程序只需要一些简单的处理调度其他的一句 FUNC[TASKID][NUM],修改添加时只改该对应
函数,或添加函数增加数组下标即可,仅供参考。 

对不起,敲错了,应该是小师、农民、大师才对,不好意思。 [zilingzhang] [8次] 01-11-22 下午 04:08:23 

不行啊,在函数内部任务已经被分割了,不能写为函数形式,想来想去还是SWITCH好,而且支持消息结构非常适合,C51可以优化的。 [《农民运动讲习所》现任所长] [4次] 01-11-22 下午 04:22:28 

消息结构对俺这种编程方法可以很好结合,给你个例子,93C46,完全不占延时,靠消息自我处理,参考一下: [《农民运动讲习所》现任所长] [79次] 01-11-22 下午 04:34:19 
/*93c46操作。*/
#include <reg52.h>
#include <intrins.h>

#include <Timer.h>
#include <Const.h>
#include <News.h>

sbit o93_cs=P3^4;
sbit o93_sk=P3^3;
sbit io93_data=P1^4;

unsigned char xdata m93c46_Task=0;
/*存储在93C46中的镜象*/
unsigned char xdata g93c46_Store[STORE93C46MAX];
/*存储在93C46中的镜象备份*/
unsigned char xdata g93c46_BakStore[STORE93C46MAX];
/*写全部缓冲时用的计数器*/
unsigned char xdata m93c46_Id;
bit fBusyDelay;                 /*写的延时标志*/
/*93C46存储数据缺省*/
unsigned char code c93c46_Default[]={
5,
5,
0,
0,
0,
0,
0,
0,
160,
100,
100,
60,
0,
160,
120,
0,
40,
1,
10,
120,
40,
90,
0};
bit fLinMode;                   /*单双线使用的标志,为提速而使用的*/
/***********************************************
内部函数。
软件延时4个时钟
***********************************************/
#define In93_SoftDlay() _nop_();_nop_();_nop_();_nop_()
/***********************************************
内部函数。
clk时钟
***********************************************/
void Clk93c46()
{
    In93_SoftDlay();
    o93_sk=1;
    In93_SoftDlay();
    o93_sk=0;
}
/***********************************************
内部函数
送起始位
***********************************************/
void startbit93c46(){
    o93_cs=0;
    In93_SoftDlay();
    io93_data=1;
    o93_cs=1;
    Clk93c46();             /*输出1*/
}
/***********************************************
内部函数
送地址或数据
***********************************************/
void ad93c46(unsigned char outdata){
    unsigned char i=8;
        do{
        ACC=outdata;
        io93_data=ACC7;
        Clk93c46();
        ACC<<=1;
        outdata=ACC;
    }while(--i);
}
/***********************************************
读入一char字返回
***********************************************/
unsigned char Read93c46(unsigned char mLocation)
{
    unsigned char i;

    startbit93c46();            /*开始*/

    Clk93c46();                 /*输出个1*/

    ad93c46(mLocation);         /*送地址*/

    io93_data=1;
    for(i=8;i>0;i--){
        In93_SoftDlay();
        o93_sk=1;
        ACC=mLocation;
        ACC+=ACC;
        ACC0=io93_data;
        mLocation=ACC;
        o93_sk=0;
    }
    In93_SoftDlay();
    o93_cs=0;

    return(mLocation);
}

/***********************************************
写一char字
***********************************************/
void Write93c46(unsigned char mLocation,unsigned char mData)
{
   if(fBusyDelay==0){
    startbit93c46();

    io93_data=0;
    Clk93c46();                 /*输出个0*/

    ad93c46(0x60);              /*写允许*/
    In93_SoftDlay();
    o93_cs=0;
    In93_SoftDlay();
    }
//---------------------------------------------
    startbit93c46();
    io93_data=0;
    Clk93c46();                 /*输出个0*/

    ad93c46(mLocation|0x80);            /*送地址写*/
    ad93c46(mData);
    o93_cs=0;

    fBusyDelay=1;               /*开始10MS写忙延时*/

    g93c46_Store[STORE93C46MAX-1]=g93c46_Store[STORE93C46MAX-1]-g93c46_BakStore
[mLocation]+mData;  /*更新效验和*/
}


之二: [《农民运动讲习所》现任所长] [54次] 01-11-22 下午 04:34:53 
/***********************************************
备份93C46镜象
***********************************************/
void AT93_Backup()
{
unsigned char i;
  for(i=0;i<STORE93C46MAX;i++)g93c46_BakStore[i]=g93c46_Store[i];
}

/***********************************************
93C46镜象与备份比较,如果不等则发出写命令
***********************************************/
void AT93_StoreChange()
{
unsigned char i;
    for(i=0;i<STORE93C46MAX;i++){
        if(g93c46_BakStore[i]!=g93c46_Store[i]){
                   News_PushInt(WRITE93C46,i,g93c46_Store[i]);
                }
    }
}

/***********************************************
写93C46的循环
***********************************************/
void AT93_MainLoop()
{
    switch(m93c46_Task){
        case 0: if(fSYS_Touch){                     /*20ms触发*/
                    if(fBusyDelay)m93c46_Task=1;    /*开始延时*/
                }
                break;
        case 1: /*写效验和*/
                if(fSYS_Touch){
                   startbit93c46();
                   io93_data=0;
                   Clk93c46();                 /*输出个0*/

                   ad93c46((STORE93C46MAX-1)|0x80);            /*送地址写*/
                   ad93c46(g93c46_Store[STORE93C46MAX-1]);
                   o93_cs=0;

                    m93c46_Task=2;
                }
                break;
        case 2: /*写禁止*/
                if(fSYS_Touch){
                    startbit93c46();
                    ad93c46(0);                 /*写禁止*/
                    In93_SoftDlay();
                    o93_cs=0;

                    fBusyDelay=0;               /*撤消忙信号*/
                    m93c46_Task=0;
                }
                break;
/*写全部缓冲的循环*/
        case 3: if(m93c46_Id<STORE93C46MAX-1){
                    Write93c46(m93c46_Id,g93c46_Store[m93c46_Id]);
                    m93c46_Task=4;
                }
                else m93c46_Task=0;                 /*写完,有忙信号,继续延时*/
                break;
        case 4: if(fSYS_Touch){                     /*20ms触发*/
                    m93c46_Task=5;                  /*开始延时*/
                }
                break;
        case 5: if(fSYS_Touch){
                   m93c46_Id++;
                    m93c46_Task=3;
                }
                break;
    }
}

/***********************************************
处理93C46消息的循环
***********************************************/
void AT93News_Loop()
{
unsigned char i;

  if(News_Read0Data()==nINIT){  /*初始化*/
    o93_cs=0;
    o93_sk=0;
    In93_SoftDlay();

    for(i=0,B=0;i<(STORE93C46MAX-1);i++){
        g93c46_Store[i]=Read93c46(i);   /*读到镜象*/
        B+=g93c46_Store[i];             /*效验和*/
    }
    g93c46_Store[i]=Read93c46(i);       /*效验字*/
    B+=0x36;

    if(B!=g93c46_Store[i]){             /*效验不对,写缺省值*/
        /*初始化数据*/
        News_Push(WRITE93DEFAULT);
    }
        else {
          if(g93c46_Store[LINEMODE]>0)fLinMode=1;       /*单双线使用的标志,为提
速而使用的*/
      else fLinMode=0;
        }
        return;
  }

    switch(News_Read0Data()){
        case WRITE93C46:    /*有93C46的写请求*/
                            News_Pop();         /*弹出消息位*/
                            if(fBusyDelay){
                                News_PushInt(WRITE93C46,News_Pop(),News_Pop
()); /*继续在消息队列中保存*/
                            }
                            else Write93c46(News_Pop(),News_Pop
());             /*写*/
                            break;
        case WRITE93DEFAULT:                    News_Pop();
                            /*初始化数据*/
                            for(i=0,B=0;i<(STORE93C46MAX-1);i++){
                                g93c46_Store[i]=c93c46_Default[i];
                                B+=g93c46_Store[i];             /*效验和*/
                            }
                            B+=0x36;
                            g93c46_Store[i]=B;

                            if((fBusyDelay==1)||(m93c46_Task!=0))
{              /*忙*/
                                News_Push
(WRITE93DEFAULT);                          /*继续在消息队列中保存*/
                            }
                            else {
                                
m93c46_Task=3;                                  /*进入写全部的循环*/
                                m93c46_Id=0;
                            }
                            break;
    }
} 

你仔细看看,有个主循环和一个消息循环,是放在主程序中的。每个循环进入后没做任何浪费的事,这就是改变结构后的好处。是基本思想。 [《农民运动讲习所》现任所长] [4次] 01-11-22 下午 05:02:26 

请进来看看 [zilingzhang] [25次] 01-11-22 下午 05:03:57 
我说的是你弹出的消息处理
/***********************************************
处理93C46消息的循环
***********************************************/
    switch(News_Read0Data()){
        case WRITE93C46:    /*有93C46的写请求*/
。。。。。。。。。。
就是这里,如果消息类型很多,消息的处理有点复杂,那这个弹出消息判断处理的SWITCH,
CASE会很难看,此时将 TASKID=News_Read0Data(); FuncPro(TASKID);即可代替;
定义(*FuncPro[])(); 并将对应的消息处理函数入口地址赋给FuncPro[TASKID]; 



加入每个程序模块都如此写法,不就实现多任务了吗?呵呵,我就用这种方法为公司做了两个新产品,每个程序容量都快31K,如果用普通的方法会更大,而且也麻烦。这种方式编程起来很容易的,不易错,但调试要一定技巧 [《农民运动讲习所》现任所长] [7次] 01-11-22 下午 05:06:52 

消息有很多,而且是唯一性的,就是所有的消息加起来只有255个,但已经够了。写为函数不能取,一是程序找不着边(变为函数找不着),二是程序大了。 [《农民运动讲习所》现任所长] [3次] 01-11-22 下午 05:10:33 

小的程序我还想的明白,大程序如何有效的分割任务传递参数我还是感到头疼,不过这种思路确实比顺序编程要好 [zilingzhang] [3次] 01-11-22 下午 05:40:26 
 

 
点击这里回复这篇贴子>>
_____________________________________________________________________________
Copyright?,C51BBS论坛 2000-2002 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -