找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 8529|回復(fù): 4
收起左側(cè)

51單片機(jī)xmodem協(xié)議程序—接收部分的代碼及rs232.h頭文件

[復(fù)制鏈接]
ID:75263 發(fā)表于 2015-3-25 00:12 | 顯示全部樓層 |閱讀模式
本帖最后由 niuniu 于 2015-3-25 00:13 編輯

#include "..\include\AT89X52.H"
#include "..\include\rs232.h"

uchar RS232_Rec;
static bit RS232_Rec_flag=0;
static bit RS232_Trn_flag=1;
//----------------------------------------------------------
// 函數(shù)名稱 RS232_Init()
// 函數(shù)功能 串口初始化,設(shè)置默認(rèn)通信速率為9600bps
//          單片機(jī)主振頻率11.0592MHz,主頻為其它值時(shí)
//          通信速率按比例變化。
// 入口參數(shù):無(wú)
// 函數(shù)返回:無(wú)
// 函數(shù)引用:無(wú)
// 變量引用:無(wú)
// 變量修改:TMOD:設(shè)置T1為串口波特率發(fā)生器
//          TH1,TL1:設(shè)置波特率為9600bps(以11.0592MHz晶體為基準(zhǔn))
//          TR1,RI,TI:啟動(dòng)T2,清除TI、RI標(biāo)志
//          REN,SM0,SM1:使能串口接收,1位起始8位數(shù)據(jù)1位停止模式
//          ES,EA:使能串口中斷,使能總中斷
//          RS232_Trn_flag:設(shè)置發(fā)送完成標(biāo)志
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
//          10/29/2009:格式規(guī)范
//----------------------------------------------------------
void RS232_Init(void)
{
    uchar i;
    RS232_Trn_flag = 1;
    TMOD &= 0x0f;
    TMOD |= 0x20;
    TH1   = 0xfd;
    TL1   = 0xfd;
    TR1   = 1;
    REN   = 1;
    SM0   = 0;
    SM1   = 1;
    RI    = 0;
    TI    = 0;
    EA    = 1;
    ES    = 1;
}
//----------------------------------------------------------
// 函數(shù)名稱:RS232_ISR()
// 函數(shù)功能:串口中斷服務(wù)函數(shù)
// 入口參數(shù):無(wú)
// 函數(shù)返回:無(wú)
// 函數(shù)引用:無(wú)
// 變量引用:RI:串口接收標(biāo)志
//          SBUF:串口接收緩沖寄存器
// 變量修改:RI,TI:清除TI、RI標(biāo)志
//          RS232_Rec:接收串口收到的字節(jié)
//          RS232_Rec_flag:設(shè)置成功接收標(biāo)志
//          RS232_Trn_flag:設(shè)置發(fā)送完成標(biāo)志
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
//          10/29/2009:格式規(guī)范
//----------------------------------------------------------
void RS232_ISR(void) interrupt 4
{
    if(RI)
    {
        RS232_Rec  = SBUF;
        RS232_Rec_flag = 1;
    }
    else RS232_Trn_flag = 1;
    RI = 0;
    TI = 0;
}
//----------------------------------------------------------
// 函數(shù)名稱:RS232_Tran_Chr(...)
// 函數(shù)功能:串口單個(gè)字符發(fā)送函數(shù)
// 入口參數(shù):chr:待發(fā)送的字符
// 函數(shù)返回:無(wú)
// 函數(shù)引用:無(wú)
// 變量引用:RS232_Trn_flag,自定義串口發(fā)送成功標(biāo)志
// 變量修改:
//          SBUF:賦值串口發(fā)送緩沖寄存器
//          RS232_Trn_flag:清除自定義串口發(fā)送成功標(biāo)志
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
//          10/29/2009:格式規(guī)范,解決發(fā)送偶爾死循環(huán)不返回問(wèn)題
//----------------------------------------------------------
void RS232_Tran_Chr(uchar chr)
{
    uint tryit = 5000;
    while((!RS232_Trn_flag) && (tryit--)) ;
    RS232_Trn_flag = 0;
    SBUF = chr;
}
//----------------------------------------------------------
// 函數(shù)名稱:RS232_Rec_Xmodem()
// 函數(shù)功能:Xmodem協(xié)議接收部分,128字節(jié)緩沖區(qū)
// 入口參數(shù):無(wú)
// 函數(shù)返回:無(wú)
// 函數(shù)引用:RS232_Tran_Chr(...)
// 變量引用:RS232_Rec_flag:串口收到字符的標(biāo)志
//          RS232_Rec:串口收到的字符
//          Xmodem_Buffer[]:Xmodem接收緩沖區(qū)
//          Xmodem_Buffer_Ptr:Xmodem緩沖區(qū)指針
// 變量修改:RS232_Rec_flag:串口收到字符的標(biāo)志
//          Xmodem_Buffer_Ptr:Xmodem緩沖區(qū)指針
//          Xmodem_Buffer[]:環(huán)形緩沖區(qū)
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
//          10/29/2009:格式規(guī)范

//          11/09/2009:修改原因:在包頭部分發(fā)現(xiàn)錯(cuò)誤,不應(yīng)該立即發(fā)NAK,而是應(yīng)該等這個(gè)包收完了再發(fā)NAK
//                               即將修改:接收過(guò)程中應(yīng)做延時(shí)檢查,防止斷線進(jìn)入死循環(huán)。
//----------------------------------------------------------
// #define SOH             0x01
// #define STX             0x02
// #define EOT             0x04
// #define ACK             0x06
// #define NAK             0x15
// #define CAN             0x18
// #define CTRLZ           0x1A
//enum TXmoden_STate {IDLE, WSTART, START, SEQ, CSEQ, DATA, DEND};
enum TXmoden_STate Xmoden_STate = IDLE;
xdata uchar Xmodem_Buffer[128];
uchar Xmodem_Buffer_Ptr=0;
uchar ChkSum=0;
uchar PSer=1, PT=0;
uchar xerror;
void RS232_Rec_Xmodem(void)
{
    if(Xmoden_STate == IDLE) return;
    if(RS232_Rec_flag)
    {
        switch(Xmoden_STate)
        {
            case WSTART:      //當(dāng)前正等待接收主機(jī)發(fā)送起始符號(hào)SOH
                if(RS232_Rec == SOH)      //收到主機(jī)發(fā)送的SOH符號(hào)
                {
                    Xmoden_STate = START; //進(jìn)入"SOH已經(jīng)收到"狀態(tài)
                    xerror=0;
                }
                else
                if(RS232_Rec == EOT)      //收到主機(jī)發(fā)送的EOT符號(hào)
                {
                    RS232_Tran_Chr(ACK);
                    Xmoden_STate = IDLE;         //進(jìn)入"空閑"狀態(tài)
                }
                break;
            case START://SOH已經(jīng)收到,當(dāng)前正等待接收期望的包序列號(hào)
                Xmoden_STate = SEQ;    //進(jìn)入"序列號(hào)已經(jīng)收到"狀態(tài)
                if(RS232_Rec != PSer)        //不是期望的包序列號(hào)
                    xerror=1;                      //設(shè)置出錯(cuò)標(biāo)志
                break;
            case SEQ:       //包號(hào)已經(jīng)收到,當(dāng)前正等待接收包號(hào)補(bǔ)碼
                Xmoden_STate = CSEQ;     //進(jìn)入"包號(hào)補(bǔ)碼已收"狀態(tài)
                if(RS232_Rec != (0xff-PSer)) //不是期望的包號(hào)補(bǔ)碼
                    xerror=1;                      //設(shè)置出錯(cuò)標(biāo)志
                break;
            case CSEQ:      //包號(hào)補(bǔ)碼已經(jīng)收到,當(dāng)前正等待接收數(shù)據(jù)
                Xmodem_Buffer[0] = RS232_Rec;
                ChkSum = RS232_Rec;
                Xmodem_Buffer_Ptr = 1;
                Xmoden_STate = DATA;
                break;
            case DATA:                       //當(dāng)前正等待接收數(shù)據(jù)
                if(Xmodem_Buffer_Ptr<128)
                {
                    Xmodem_Buffer[Xmodem_Buffer_Ptr++] = RS232_Rec;
                    ChkSum += RS232_Rec;
                    if(Xmodem_Buffer_Ptr==128)
                    Xmoden_STate = DEND;
                }
                break;
            case DEND:      //數(shù)據(jù)包接收結(jié)束,當(dāng)前正等待接收校驗(yàn)和
                if((ChkSum == RS232_Rec)&&(xerror==0))
                {
                    KS108_Disp_uint_Dec(0,0,PSer,0);
                    Flash_Write(((ulong)(PSer-1+(PT<<8))<<7), Xmodem_Buffer, 128);
                    PSer++;
                    if(PSer==0) PT++;
                    RS232_Tran_Chr(ACK);         //給主機(jī)正確應(yīng)答
                    Xmoden_STate = WSTART;
                }
                else
                {
                    RS232_Tran_Chr(NAK);    //要求主機(jī)重發(fā)SOH符號(hào)
                    Xmoden_STate = WSTART;//回到"等待接收SOH"狀態(tài)
                }
                break;
            default:break;
        }
        RS232_Rec_flag = 0;
    }
}
//本函數(shù)的調(diào)用方式如下:
//  Xmoden_STate = WSTART;
//  RS232_Tran_Chr(NAK);
//  while(Xmoden_STate != IDLE) RS232_Rec_Xmodem();

//需要進(jìn)一步完善/優(yōu)化。已經(jīng)成功用于PC--->51單片機(jī)管理下的2M字節(jié)串行Flash芯片AT45DB161D下載16點(diǎn)陣漢字庫(kù)。
//每個(gè)包都人為設(shè)置多個(gè)錯(cuò)誤,測(cè)試通過(guò)

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:75263 發(fā)表于 2015-3-25 00:13 | 顯示全部樓層
下面是頭文件rs232.h的內(nèi)容:
  1. #ifndef __RS232_H__
  2. #define __RS232_H__

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define ulong unsigned long

  6. #define SOH             0x01
  7. #define STX             0x02
  8. #define EOT             0x04
  9. #define ACK             0x06
  10. #define NAK             0x15
  11. #define CAN             0x18
  12. #define CTRLZ           0x1A
  13. enum TXmoden_STate {IDLE, WSTART, START, SEQ, CSEQ, DATA, DEND};

  14. extern uchar RS232_Rec;
  15. extern idata uchar RS232_Rec_Buf[];
  16. extern uchar RS232_Rec_Buf_Index;
  17. extern enum TXmoden_STate Xmoden_STate;

  18. void RS232_Init(void);
  19. void RS232_ISR(void);
  20. void RS232_Tran_Chr(uchar chr);
  21. // void RS232_Tran_Str(const uchar* str);
  22. //uchar* RS232_Rec_Str(void);
  23. void RS232_Rec_Xmodem(void);
  24. #endif
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:128605 發(fā)表于 2016-6-29 20:34 | 顯示全部樓層
感謝 正好要用到
回復(fù)

使用道具 舉報(bào)

ID:17809 發(fā)表于 2020-8-15 08:07 | 顯示全部樓層
謝謝, 程序?qū)懙煤芎?br />
回復(fù)

使用道具 舉報(bào)

ID:137736 發(fā)表于 2020-11-9 19:49 | 顯示全部樓層
編譯通不過(guò),請(qǐng)上傳文件
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表