📄 xmodem._c
字号:
#include "xmodem.h"
#include "pic_crc_data.h"
#include "atc.h"
uchar sending;
extern uchar receive_data[STRING_LENGTH];
extern int receive_sp=0;
uchar const *pic;
uchar temp_char0=0;
uchar xmodedata; // TH
uint picLenth; // TH
struct Message
{
uchar Data_Len; /* 消息内容长度,即Message中的内容字节数 */
uchar Message[PACKET_DATA_BUFFER_LENGTH]; /* 消息内容, 由发送进程填写 */
uint User_Data;
};
struct String
{
uint string_len;
uchar string[STRING_LENGTH];
void *string_data;
};
void intDelay(uint i);
uint update_CRC(uchar inData, uint checksum);
uchar tx_EOT(void);
void Delay(unsigned int Delay_MS);
void send_m_byte(uchar *string, uint length);
void send_a_byte(uchar temp);
void do_serial_data(int lenth);
uchar send_packet_data(uchar const *User_Data , uint LEN);
uchar tx_packet(uchar packet_number,uchar * packet_data_buffer, uchar temp_char );
void sendcmd(unsigned char *by_Array);
uchar xModemSend(uchar *temp_data, uint length)
{
*temp_data = 0;
length = 0;
return 0;
}
// 信息包序号 包里面的数据 收接收方反回来的信息
uchar tx_packet(uchar packet_number,uchar * packet_data_buffer, uchar temp_char )
{
uchar attempt;
uint checksum;
uchar buffer_index;
for(attempt = 1; attempt <= MAX_TX_TRY; attempt++)
{
checksum= 0; //校验和为0
send_a_byte(SOH); // send start of packet(sending标志中断发送)
send_a_byte(packet_number); //发送信息包序号
send_a_byte(255 - packet_number); //发送信息包序号的补码
//以下为发送数据
for(buffer_index = 0; buffer_index < PACKET_DATA_BUFFER_LENGTH; buffer_index++)
{
send_a_byte(packet_data_buffer[buffer_index]); //发送128个字节
if (temp_char == NAK) //接收方返回NAK则发送方要得传
checksum += packet_data_buffer[buffer_index]; //计算校验和
else
checksum = update_CRC(packet_data_buffer[buffer_index], checksum); //CRC校验和
}
if (temp_char == ASCII_C) //如果收到C
{ send_a_byte((uchar)((checksum>>8) & 0x00ff));
send_a_byte((uchar)(checksum & 0x00ff));
} // send end of packet CRC
temp_char0=0;
while(temp_char0 == 0);
temp_char =temp_char0; // get receiver response
if (temp_char == CAN)
return 0; // reception cancelled
if (temp_char == ACK)
return 1; // packet received okay
}
return 0; // attempts exhausted
}
/*
function: 以XMODEM 发送数据
in: user_data 是数据指针
out: 1 sucess
o faile
使用全局变量? 无
*/
uchar send_packet_data(uchar const *User_Data , uint LEN)
{
struct Message Xmodem_Pack22;
struct Message *xModem;
uint i,j=0;
unsigned char packet_number = 1;
unsigned char no_more = 0;
unsigned char temp_char = 0;
xModem=&Xmodem_Pack22;
xModem->User_Data=0;
// xModem->User_Data=User_Data;
//只要没有收到ACK(crc校验) 和NAK(校验和)信号就一直在这里等
while((temp_char != ASCII_C) && (temp_char != NAK))
{
temp_char = temp_char0;// wait till receiver ready(从这里知道temp_char存的是接收方返回来的信息)
if(temp_char == CAN)
return 0;
}
if (LEN < PACKET_DATA_BUFFER_LENGTH) // 数据区段的长度固定为 128 字节
{
for(i=0;i<LEN;i++)
xModem->Message[i]=(User_Data[j++]);
for(i=LEN;i<128;i++)
xModem->Message[i]=CTRL_Z;
if(tx_packet(packet_number, xModem->Message, temp_char)==0)
return 0;
}
else
{
do
{
for(i=0;i<128;i++)
xModem->Message[i]=(User_Data[j++]);
if(tx_packet(packet_number, xModem->Message, temp_char)==0)
return 0;
packet_number++;
LEN=LEN-128;
Delay(10);
}while(LEN>=128);
if (LEN)
{
for(i=0;i<LEN;i++)
xModem->Message[i]=(User_Data[j++]);
for(i=LEN;i<128;i++)
xModem->Message[i]=CTRL_Z;
if( tx_packet(packet_number, xModem->Message, temp_char)==0)
return 0;
}
}
if (!tx_EOT()) //发送方正常结束要发EOT信号,
return 0; // end tx data failed
return 1; //正常结束
}
uchar tx_EOT(void)
{
uchar attempt;
unsigned char temp;
for(attempt = 1; attempt <= MAX_TX_TRY; attempt++)
{
send_a_byte(EOT);
// send file end
Delay(1);
temp=temp_char0;
if(temp == ACK)
return 1; // file end acknowledged 接收方返因ACK信号
}
return 0; // file tx failed
}
uint update_CRC(uchar inData, uint checksum)
{
return ((checksum << 8) ^ crc16_table[ (checksum >> 8) ^ inData ]);
}
char memcmp_self(char const *string1, char const *string2 ,unsigned int lenth)
{
uchar i;
for(i = 0; i<lenth; i++)
{
if(*string1 != *string2)
return 0;
string1++;
string2++;
}
return 1;
}
void do_serial_data(int lenth)
{
switch (lenth)
{
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
if(memcmp_self(receive_data, DATA_OK,2)==0 ) //检测是否收到 OK
receive_OK = 1;
break;
case 4:
break;
case 5:
if(memcmp_self(receive_data, DATA_ERROR, 5)) //检测是否收到 ERROR
receive_ERROR = 1;
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 12:
if(memcmp_self(receive_data,DATA_DOWNFINEOK,12)) //检测是否收到 Ok_Info_FileUploadStarted
receive_DOWNFINEOK = 1;
break;
case 19:
if(memcmp_self(receive_data,DATA_DOWNFINE,19)) //检测是否收到 Ok_Info_FileUploadStarted
receive_DOWNFINE = 1;
break;
default:
break;
}
}
void Delay(unsigned int Delay_MS)
{
unsigned char i;
while(Delay_MS--)
{
for(i=0;i<111;i++);
}
}
void Xmodem(void)
{ int i;
uchar temp;
pic = test_pic1;
for (i = 1; i < 65530; i++)
{
if((*(pic-1) == 0xff) &&((*pic) == 0xd9))
{
break;
}
pic++;
}
picLenth = i;
temp = 1;
while(1)
{
if(temp == 1)
{
temp = 0;
receive_OK = 0;
receive_ERROR = 0; //删除旧图片
send_m_byte("at$fdel=\"*\"\r\n",13);
while((receive_OK == 0) && (receive_ERROR == 0)) ;
Delay(10);
receive_ERROR = 0;
receive_DOWNFINE = 0;
send_m_byte("at$fupl=\"test.jpg\"\r\n",21); //下载图片
while (1)
{
if(receive_DOWNFINE == 1) //测试是否收到 Ok_Info_FileUploadStarted
{
;
break;
}
if(receive_ERROR == 1) //测试是否收到 ERROR
{
;
break;
}
}
receive_C = 0;
//测试是否收到 C
while (receive_C == 0);
xmodedata = send_packet_data(test_pic1,picLenth);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -