?? 一個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 + -