📄 93c46.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 + -