📄 一个c51的通讯子程序.txt
字号:
用【 小 | 中 | 大 】字体浏览
C51编程:一个C51的通讯子程序,大伙给批评一下.谢谢. [wander] [71次] 01-12-23 下午 03:53:33
#include <reg51.h>
#define TRUE 0xff
#define FALSE 0X00
#define uchar unsigned char
void fasong(char character);
uchar jieshou();
void ssub();
void rsub();
uchar xdata t_buff[]={'@','U','N','0','0','#'};
uchar xdata sys_info[183];
uchar xdata r_buff[20];
uchar i,Fa,Jie,Head,t0;
void fasong(char character) /*发送一个字符*/
{
SBUF=character;
while(TI==0);
TI=0;
}
uchar jieshou() /*接收一个字符*/
{
REN=1;
RI=0;
while(RI!=1);
Head=SBUF;
return(Head);
}
void ssub() /*发送一串字符*/
{
SM2=1; /*发送地址码*/
Fa=0x00;
while(1)
{
fasong(Fa);
Jie=jieshou();
if(Jie==Fa) break;
}
SM2=0; /*发送数据码*/
i=0;
t0=0;
re:
do
{
fasong(t_buff[i]);
t0=t0+t_buff[i]; /*计算累加和*/
}
while (t_buff[i]!='#'); /*#是字符串结束标志符号*/
fasong(t0); /*发送累加和*/
Jie=jieshou(); /*接收PC回送码*/
if(Jie==FALSE)
{
i=0;
t0=0;
goto re;
}
}
void rsub() /*接收一串字符*/
{
SM2=1; /*发送地址码*/
Fa=0x00; /*是呼叫本机吗?*/
while(1)
{
Jie=jieshou();
if (Jie==Fa) break;
}
fasong(Fa); /*发送本机码,与PC握手*/
SM2=0; /*发送数据*/
i=0;
t0=0;
rel:
do
{
r_buff[i]=jieshou();
t0=t0+r_buff[i]; /*求累加和*/
}
while(r_buff[i]!='#'); /*接收完成?*/
jieshou(); /*接收累加和*/
if(t0==jieshou()) /*累加和与计数相等,发送TRUE*/
fasong(TRUE);
else /*否则发送FALSE,要求重发*/
{
fasong(FALSE);
t0=0;
i=0;
goto rel;
}
}
main()
{
TMOD=0x20; /*定时器初始化*/
TH1=0xe6;
TL1=0Xe6;
TCON=0x40;
SCON=0xe0; /*串口初始化,1200bps*/
EA=0;
ES=0;
ET1=0; /*关中断*/
if (RI==1) rsub(); /*查询*/
if (TI==1) ssub();
/*work();*/
}
有点象流水帐, 累加和校验不太可靠, 最好用CRC. [夜半老妖] [6次] 01-12-23 下午 04:30:18
流水帐?什么意思?具体指正一下.谢谢.至于校验,好像是在单片机系统中很少用CRC,好像有人这么说过.不好意思. [wander] [2次] 01-12-23 下午 04:51:48
接收等待限时,不用while(RI!=1); [大头小语] [5次] 01-12-23 下午 07:11:30
Head不应该用全局变量,goto改为do{}while(...),为什么用SM2?要和PC做多机通讯吗?比较麻烦,好象通讯方案不太对... [DarkKeeper] [3次] 01-12-23 下午 07:17:40
在Head=SBUF;前改成while(RI==1)RI=0;不改可能收不着 [波] [4次] 01-12-23 下午 09:22:04
呵呵,谢谢.我这两天也在考虑这个问题,其实函数的参数传递,即可以使用全局变量进行传递,也可以使用参变量做传递,Head用做全局变量并不会导致错误,只是多占用RAM.goto语句可以改成do{} [wander] [7次] 01-12-24 上午 09:47:25
while()语句.使用SM2只是做一个预留,以便以后采用多机通讯.通讯方案不对?这个该如何解
释?无外乎,发地址,校验地址,发数据,接收数据,接收累加和,校验累加和,可否具体指点一
下?谢谢.
这是一个好办法,可以防止死机.谢谢. [wander] [2次] 01-12-24 上午 09:49:10
好像开始是RI=0;然后判断RI=1?RI=1,才可以接收的.不过有一点可能确实有问题,RI=1后,应该再一次清零.谢谢. [wander] [2次] 01-12-24 上午 09:57:35
老兄,你的程序可能跑不起来。 [寄存器] [7次] 01-12-24 上午 10:02:31
主程序中必须有个while(1){},或类似的语句,否则程序一定会跑飞的,就像汇编最后
有一死等一样。另外中断是单片机的宝贵资源,学着用用吧,搞不懂中断,基本上可以讲
就无法理解CPU。一片没有中断的PIIII其性能可能还不如80286之类的CPU。
内详 [DarkKeeper] [8次] 01-12-24 下午 05:08:02
#include <reg51.h>
#define TRUE 0xff
#define FALSE 0X00
#define uchar unsigned char
void fasong(char character);
uchar jieshou();
void ssub();
void rsub();
uchar xdata t_buff[]={'@','U','N','0','0','#'};
uchar xdata sys_info[183];
uchar xdata r_buff[20];
uchar i,Fa,Jie,Head,t0;
void fasong(char character) /*发送一个字符*/
{
SBUF=character;
while(TI==0);
TI=0;
}
uchar jieshou() /*接收一个字符*/
{
REN=1; /*不合适,REN为零,RI不会响应*/
RI=0; /*错,第一次响应丢失*/
while(RI!=1);
Head=SBUF;
return(Head);
}
void ssub() /*发送一串字符*/
{
SM2=1; /*发送地址码*/ /*错 置位用TB9,为什么查资料*/
Fa=0x00;
while(1)
{
fasong(Fa);
Jie=jieshou();
if(Jie==Fa) break;
}
SM2=0; /*发送数据码*/ /*错 置位用TB9,为什么查资料*/
i=0;
t0=0;
re:
do
{
fasong(t_buff[i]);
t0=t0+t_buff[i]; /*计算累加和*/
}
while (t_buff[i]!='#'); /*#是字符串结束标志符号*/ /*不好,C字符串有结束
符,自定义不好/
fasong(t0); /*发送累加和*/
Jie=jieshou(); /*接收PC回送码*/
if(Jie==FALSE)
{
i=0;
t0=0;
goto re;
}
}
void rsub() /*接收一串字符*/
{
SM2=1; /*发送地址码*/ /*不合适,之前SM2为零,TI响应所有数据接受*/
Fa=0x00; /*是呼叫本机吗?*/
while(1)
{
Jie=jieshou();
if (Jie==Fa) break;
}
fasong(Fa); /*发送本机码,与PC握手*/
SM2=0; /*发送数据*/
i=0;
t0=0;
rel:
do
{
r_buff[i]=jieshou();
t0=t0+r_buff[i]; /*求累加和*/
}
while(r_buff[i]!='#'); /*接收完成?*/ /*不好,C字符串有结束符,自定义不好/
jieshou(); /*接收累加和*/
if(t0==jieshou()) /*累加和与计数相等,发送TRUE*/
fasong(TRUE);
else /*否则发送FALSE,要求重发*/
{
fasong(FALSE);
t0=0;
i=0;
goto rel;
}
}
main()
{
TMOD=0x20; /*定时器初始化*/
TH1=0xe6;
TL1=0Xe6;
TCON=0x40;
SCON=0xe0; /*串口初始化,1200bps*/
EA=0;
ES=0;
ET1=0; /*关中断*/
/*问题1:如果这里REN为0,RI不会响应*/
/*问题2:如果这里SM2为0,RI响应所有数据和地址*/
if (RI==1) rsub(); /*查询*/
if (TI==1) ssub();
/*work();*/
}
没有做过多机通讯,以上是个人理解,以自己实践为准,我上次提出的是编程风格的问题,
占用空间倒不重要,还有,要用pc机做多机通讯的主机第9位处理有点麻烦,直接操作底层
可以实现查查单片机文选,你如果有兴趣可以试试用WINDOWS下用奇偶校验,置MASK(1),置
SPACE(0).
点击这里回复这篇贴子>>
_____________________________________________________________________________
Copyright?,C51BBS论坛 2000-2002
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -