modem协议作简要研究2

#ifndef _XMODEM_H_
#define _XMODEM_H_

#include <stdint.h>

int xmodemReceive(unsigned char *dest, int destsz)  ;
#endif
#include "main.h"
#include "gkbaseusart.h"
#include "xmodem.h"
#include <string.h>

#define SOH 0x01  
#define STX 0x02  
#define EOT 0x04  
#define ACK 0x06  
#define NAK 0x15  
#define CANX 0x18  
#define CTRLZ 0x1A  
#define DLY_1S 1000  
#define MAXRETRANS 25  
  
static int last_error = 0;  


//完成输出  
//类似printf搬运过来串口1的函数
//最一个准备工作 把接受区清空
void out_buff(unsigned char *buff, int size)  
{  
   GK_usart_clear(&GKU1);
	 HAL_UART_Transmit(&huart1 , buff, size , 0xffff);
}  
   
  
//发送出去以后 我们在收到的数据
//这个函数风格是 我TX以后 过一会儿 就去接受缓存区拿数据 有的话 就是成功
//拿到受到的数据buff 返回数据的长度
int in_buff(unsigned char *buff, int time_out)  
{
    int qSize = 0;  
    int readSize = 0;       
    last_error = 0;  

	
	  HAL_Delay(time_out);  
 
      
    if(GKU1.rx_len)  
    {  
        qSize = GKU1.rx_len;   
        if(qSize > 0)  
        {  
					readSize = GKU1.rx_len;  
					memcpy(buff,GKU1.rxBuf,GKU1.rx_len);
        }  
    }  
      
    if(readSize == 0)  
        last_error = 1;  
  
    return (readSize);  
}
//完成数据CRC计算
int calcrc(const unsigned char *ptr, int count)  
{  
    int crc;  
    char i;  
  
    crc = 0;  
    while (--count >= 0)  
    {  
        crc = crc ^ (int) *ptr++ << 8;  
        i = 8;  
        do  
        {  
            if (crc & 0x8000)  
                crc = crc << 1 ^ 0x1021;  
            else  
                crc = crc << 1;  
        } while (--i);  
    }  
  
    return (crc);  
}  
//完成数据和本地比较 1一样 0不同
int check(int crc, const unsigned char *buf, int sz)  
{    
    if(crc)  
    {  
        unsigned short crc = calcrc(buf, sz);  
        unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];  
  
        if (crc == tcrc)  
            return 1;  
    }  
    else  
    {  
        int i = 0;  
        unsigned char cks = 0;  
          
        for(i = 0; i < sz; i ++)  
        {  
            cks += buf[i];   
        }  
          
        if (cks == buf[sz])  
            return 1;  
    }  
  
    return 0;   
  
}  

//接受函数
int xmodemReceive(unsigned char *dest, int destsz)  
{    
    unsigned char xbuff[140];  
    int bufsz = 0;  
    int crc = 0;  
    unsigned char trychar = 'C';  
    unsigned char packetno = 1;  
    int c = 0;  
    int len = 0;  
    int retry = 0;  
    int retrans = MAXRETRANS;  
    int recvSize = 0;  
  
    for(;;)   
    {  
        for(retry = 0; retry < 16; retry ++)  
        {  
            if(trychar)  
            {  
                xbuff[0] = trychar;  
                out_buff(xbuff, 1);  //发送'C'出去 作为接受者 先发送C 去启动
            }  
              
            recvSize = in_buff(xbuff, (DLY_1S)<<1); //相当于TXRX 这里收到的数据 去分析 
            c = xbuff[0];  
              
            if (last_error == 0)   
            {  
                switch(c)  
                {  
                    case SOH:  
                        bufsz = 128;  
                        goto start_recv;  
                    case STX:  
													{  
															xbuff[0] = CANX;  
															out_buff(xbuff, 1);  
													}  
													return -1;  
                    case EOT:   
														{  
																xbuff[0] = ACK;  
																out_buff(xbuff, 1);  
														}  
														return len;  
                    case CANX:  
  
                        in_buff(xbuff, DLY_1S);  
                        c = xbuff[0];  
                        if(c == CANX)  
                        {  
                            {  
                                xbuff[0] = ACK;  
                                out_buff(xbuff, 1);  
                            }  
                            return -1;  
                        }  
                        break;  
                    default:  
                        break;  
                }  
            }  
        }  
  
        if (trychar == 'C')  
        {  
            trychar = NAK;  
            continue;  
        }  
  
        {  
            xbuff[0] = CANX;  
            out_buff(xbuff, 1);  
            out_buff(xbuff, 1);  
            out_buff(xbuff, 1);  
        }  
  
        return -2;  
  
start_recv:  
        if(trychar == 'C')  
            crc = 1;  
  
        trychar = 0;  
  
        if(recvSize != (bufsz + (crc ? 1 : 0) + 4))  
            goto reject;  
          
        if(xbuff[1] == (unsigned char)(~xbuff[2]) &&   
            (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno - 1) &&   
            check(crc, &xbuff[3], bufsz))  
        {  
            if(xbuff[1] == packetno)  
            {  
                int count = destsz - len;  
                  
                if (count > bufsz)  
                    count = bufsz;  
  
                if (count > 0)  
                {  
                    memcpy(&dest[len], &xbuff[3], count);  
                    len += count;  
                }  
  
                packetno ++;  
  
                retrans = MAXRETRANS+1;  
            }  
  
            if(-- retrans <= 0)  
            {  
                {  
                    xbuff[0] = CANX;  
                    out_buff(xbuff, 1);  
                    out_buff(xbuff, 1);  
                    out_buff(xbuff, 1);  
                }  
                return -3;  
            }  
  
            {  
                    xbuff[0] = ACK;  
                    out_buff(xbuff, 1);  
            }  
              
            continue;  
        }  
  
reject:    
        {  
                xbuff[0] = NAK;  
                out_buff(xbuff, 1);  
        }  
  
    }  
}  
  
//send_buff_size == 140  
int xmodemTransmit(unsigned char *src, int srcsz)  
{  
    unsigned char xbuff[140];  
    int bufsz = 0;  
    int crc = -1;  
    unsigned char packetno = 1;  
    int i = 0;  
    int c = 0;  
    int len = 0;  
    int retry = 0;  
  
    for(;;)  
    {  
        for( retry = 0; retry < 16; ++retry)  
        {  
            in_buff(xbuff, (DLY_1S)<<1);  
            c = xbuff[0];  
              
            if(last_error == 0)  
            {  
                switch(c)  
                {  
                    case 'C':  
                        crc = 1;  
                        goto start_trans;  
                    case NAK:  
                        crc = 0;  
                        goto start_trans;  
                    case CANX:  
                        in_buff(xbuff, DLY_1S);  
                        c = xbuff[0];  
                        if(c == CANX)   
                        {  
                            {  
                                    xbuff[0] = ACK;  
                                    out_buff(xbuff, 1);  
                            }  
                            return -1;  
                        }  
                        break;  
                    default:  
                        break;  
                }  
            }  
        }  
  
        {  
            xbuff[0] = CANX;  
            out_buff(xbuff, 1);  
            out_buff(xbuff, 1);  
            out_buff(xbuff, 1);  
        }  
  
        return -2;  
  
        for(;;)  
        {  
start_trans:    
            xbuff[0] = SOH;  
            bufsz = 128;  
            xbuff[1] = packetno;  
            xbuff[2] = ~packetno;  
              
            c = srcsz - len;  
            if(c > bufsz)  
                c = bufsz;  
  
            if(c >= 0)  
            {  
                memset(&xbuff[3], 0, bufsz);  
  
                if (c == 0)  
                {  
                    xbuff[3] = CTRLZ;  
                }  
                else  
                {  
                    memcpy(&xbuff[3], &src[len], c);  
                      
                    if (c < bufsz)  
                        xbuff[3 + c] = CTRLZ;  
                }  
                  
                if(crc)  
                {  
                    unsigned short ccrc = calcrc(&xbuff[3], bufsz);  
                      
                    xbuff[bufsz + 3] = (ccrc>>8) & 0xFF;  
                    xbuff[bufsz + 4] = ccrc & 0xFF;   
                }  
                else  
                {  
                    unsigned char ccks = 0;  
                      
                    for(i = 3; i < bufsz + 3; i ++)  
                    {  
                        ccks += xbuff[i];  
                    }  
                      
                    xbuff[bufsz + 3] = ccks;  
                }  
                  
                for(retry = 0; retry < MAXRETRANS; retry ++)  
                {  
                    out_buff(xbuff, bufsz + 4 + (crc ? 1 : 0));  
  
                    in_buff(xbuff, DLY_1S);  
                    c = xbuff[0];  
                      
                    if(last_error == 0)  
                    {  
                        switch(c)  
                        {  
                            case ACK:  
                                packetno ++;  
                                len += bufsz;  
                                goto start_trans;  
                            case CANX:  
                                in_buff(xbuff, DLY_1S);  
                                c = xbuff[0];  
                                if(c == CANX)  
                                {  
                                    {  
                                        xbuff[0] = ACK;  
                                        out_buff(xbuff, 1);  
                                    }  
                                      
                                    return -1;  
                                }  
                                break;  
                            case NAK:  
                                break;  
                            default:  
                                break;  
                        }  
                    }  
                }  
                {  
                    xbuff[0] = CANX;  
                    out_buff(xbuff, 1);  
                    out_buff(xbuff, 1);  
                    out_buff(xbuff, 1);  
                }  
  
                return -4;  
            }  
            else  
            {  
                for(retry = 0; retry < 10; retry ++)  
                {  
                    {  
                        xbuff[0] = EOT;  
                        out_buff(xbuff, 1);  
                    }  
                      
                    in_buff(xbuff, (DLY_1S)<<1);  
                    c = xbuff[0];  
  
                    if(c == ACK)  
                        break;  
                }  
              
                return ((c == ACK) ? len : -5);  
            }  
        }  
    }  
}

此时写一文件

启动发送

在运行代码即可

STM32收到了数据到buf而且不够的全部是0X1A

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值