⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodem.c

📁 单片机与电脑通过xmodem协议通信源码。
💻 C
字号:
#include	"mylib.h"
#define	XMODEM_SOH	1
#define	XMODEM_ERR_RETRY_COUNT	0
#define	XMODEM_NAK	0x15
#define	XMODEM_ACK	6
#define	XMODEM_EOT 	4
#define	XMODEM_EOF	0


static unsigned char xmodem_buff[128+4];
static unsigned char xmodem_block_number;
static int xmodem_index = -1;

static int get_xmodem_frame(void)
{
 //TIMER timeout;
 uchar	timeout;
 int index;
 int c;

 xmodem_index = -1;

 set_timer(&timeout, ONE_SECOND*10 );

 do {
  c = getchar();
 } while(c < 0 && ! timer_expired(&timeout));

 if(c < 0) {
  return -1;
 }

 if(c != XMODEM_SOH && c != XMODEM_EOT && c != XMODEM_CAN) {
  set_timer(&timeout, ONE_SECOND);
  do {
   c = getchar();
   if(c >= 0) {
    set_timer(&timeout, ONE_SECOND);
   }
  } while( ! timer_expired(&timeout));
  return -1;
 }

 index = 0;
 xmodem_buff[index++] = c;

 if(c == XMODEM_EOT || c == XMODEM_CAN)
 {
  return 0;
 }

 while(index < sizeof(xmodem_buff)) {

  set_timer(&timeout, ONE_SECOND);

  do {
   c = getchar();
  } while(c < 0 && ! timer_expired(&timeout));

  if(c < 0) {
   return -1;
  }

  xmodem_buff[index++] = c;
 }

 xmodem_index = 0;
 return 0;
}


static int xmodem_verify_frame(void)
{
 int i;
 unsigned char checksum;

 if(xmodem_buff[0] != XMODEM_SOH) {
  return -1;
 }
 if(xmodem_buff[1] != xmodem_block_number) {
  return -1;
 }

 if(xmodem_buff[2] != ((~xmodem_block_number) & 0xff)) {
  return -1;
 }

 checksum = 0;

 for(i = 3; i < sizeof(xmodem_buff)-1; i++) {
  checksum += xmodem_buff[i];
 }

 if(checksum != xmodem_buff[sizeof(xmodem_buff)-1]) {
  return -1;
 }

 return 0;
}

static int xmodem_get_more(void)
{
 int err;
 int err_retry_count;

 xmodem_block_number++;
 err_retry_count = 0;

 while(err_retry_count < XMODEM_ERR_RETRY_COUNT)
 {
  if(xmodem_index < 0) {
   putchar(XMODEM_NAK);
  }

  err = get_xmodem_frame();

  if(err == 0) {
   if(xmodem_buff[0] == XMODEM_SOH) {
    if( xmodem_verify_frame() == 0) {
     putchar(XMODEM_ACK);//uart_sendchar
     xmodem_index = 3;
     return 0;
    } else if(xmodem_buff[1] == xmodem_block_number -1) {
     putchar(XMODEM_ACK);//uart_sendchar
    } else {
     xmodem_index = -1;
    }
    err_retry_count++;
    continue;
   } else if(xmodem_buff[0] == XMODEM_EOT) {
    putchar(XMODEM_ACK);
    xmodem_index = -1;
    return -1;
   }
  }

  xmodem_index = -1;
  err_retry_count++;
 }

 xmodem_index = -1;
 return -2;
}

static int xmodem_eof(void)
{
 int i;

 if(xmodem_index < 0) {
  return 1;
 }

 for( i = xmodem_index; i < sizeof(xmodem_buff) -1; i++) {
  if(xmodem_buff[i] != XMODEM_EOF) {
   return 0;
  }
 }

 if(peekchar() != XMODEM_EOT) {
  return 0;
 }

 return 1;
}

int xmodem_start(void)
{
 xmodem_index = sizeof(xmodem_buff)-1;
 xmodem_block_number = 0;

 return 0;
}

int xmodem_finish(void)
{
 int c;

 do {
  c = xmodem_getchar();
 } while(c >= 0);

 return 0;
}


int xmodem_abort(void)
{
 int i;

 for(i=0; i<8; i++) {
  putchar(XMODEM_CAN);
 }

 xmodem_finish();

 return 0;
}

/****************************************************************
 * This is the user api call for xmodem transfers.
 *
 *
 */

int xmodem_getchar(void)
{
 int err;
 int c;
 if(xmodem_index < 0) {
  return -1;
 }

 if(xmodem_index >= sizeof(xmodem_buff)-1) {
  err = xmodem_get_more();

  if(err < 0) {
   return err;
  }
 }

 c = xmodem_buff[xmodem_index];
 xmodem_index++;

 if(c == XMODEM_EOF) {
  if( xmodem_eof() ) {
   xmodem_finish();
   xmodem_index = -1;
   return -1;
  }
 }

 return c;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -