📄 m16_xmodem._c
字号:
//ICC-AVR application builder : 2008-7-29 下午 04:04:26
// Target : M16
// Crystal: 3.6864Mhz
#include <iom16v.h>
#include <macros.h>
#include "pic_crc_data.h"
#define true 1
#define false 0
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define SOH 0x01
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define CTRL_Z 0x1a
#define SPACE 0x20
#define ASCII_C 0x43
#define ENTER 0x0d
#define CHARGE_LINE 0x0a
#define PACKET_DATA_BUFFER_LENGTH 128
#define MAX_TX_TRY 3
#define ctrl_z 0x1a
uchar const *DATA_AT = "at$";
uchar const *DATA_OK = "OK";
uchar const *DATA_DOWNFINE = "Ok_Info_FileUploadStarted";
uchar const *DATA_ERROR = "ERROR";
uchar const *DATA_DOWNFINEOK = "Ok_Info_FileClose";
uchar const *DATA_MMSTRACE = "$MMSTRACE: 1";
uchar const *DATA_RING = "RING";
uchar const *DATA_CLIP = "+CLIP";
uchar dial_number[12]={'1','3','7','6','7','1','3','1','6','4','1'};
uchar subject[]="mmstest";
uchar deletmms[]="AT$FDEL=\"*\"\r\n" ;
uchar receive_OK;
uchar receive_other;
uchar receive_C;
uchar receive_DAYUHAO;
uchar receive_DOWNFINE;
uchar receive_DOWNFINEOK;
uchar receive_ERROR;
uchar receive_MMSTRACE;
uchar receive_RING;
uchar receive_CLIP;
uchar flag_mobile;
uchar flag_telephone;
uchar telephone_long;
uchar xmodedata; // TH
uint picLenth; // TH
uchar test[100];
#define PRINT_BUFFER_LENGTH 80
#define COUNT_STEP 1
#define MAX_COUNT 100
#define MAX_MESSAGE_LEN 132
struct Message
{
uchar Data_Len; /* 消息内容长度,即Message中的内容字节数 */
uchar Message[PACKET_DATA_BUFFER_LENGTH]; /* 消息内容, 由发送进程填写 */
uint User_Data;
};
#define STRING_LENGTH 40
struct String
{
uint string_len;
uchar string[STRING_LENGTH];
void *string_data;
};
uchar sending;
uchar receive_data[STRING_LENGTH];
int receive_sp=0;
uchar const *pic;
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(void);
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);
void mms_atsent(void);
void Xmodem(void);
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9600 (0.0%)
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x01; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
uart0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
uchar temp_char0=0;
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
//uart has received a character in UDR
//uchar temp_char0;
unsigned char temp;
temp=UDR;
temp_char0 = temp;
if(temp_char0 == 'C')
{ //检测是否收到 C
receive_C = 1;
}
if(temp_char0 == '>')
{ //检测是否收到 >
receive_DAYUHAO = 1;
}
if(temp_char0 == 'K')
{ //检测是否收到 OK
receive_OK = 1;
}
if(temp_char0 == '1')
{ //检测是否收到 $MMSTRACE: 1
receive_MMSTRACE = 1;
}
if(temp_char0 == 'U')
{ //检测是否收到 DOWNFINE
receive_DOWNFINE = 1;
}
if(temp_char0 == 'R')
{ //检测是否收到 RING
receive_RING = 1;
}
if(temp_char0 == '+')
{ //检测是否收到 CLIP
receive_CLIP = 1;
}
if ((temp_char0 == CHARGE_LINE)|| (temp_char0 == ENTER))
{
do_serial_data(); //收到回车,接收指针归零 ,并处理接收数据
receive_sp = 0;
}
else
{
receive_data[receive_sp++] =temp;
}
if (receive_sp > 40) //接收超长,接收指针规零
receive_sp = 0;
}
/*********************************************************************
*********************************************************************/
void main(void)
{
int i;
init_devices();
for(i = 0; i< STRING_LENGTH ; i++) //清接收缓存//40
{
receive_data[i] = 0;
}
receive_OK = 0;
send_a_byte(ENTER); //发送回车,测试模块
Delay(500);
receive_OK = 0;
send_m_byte("at\r\n",4); //发送AT,测试模块
send_a_byte(ENTER);
while(receive_OK== 0)
{
send_a_byte(ENTER);
Delay(1000);
}
receive_RING=0;
receive_CLIP=0;
while(1)
{
Delay(10);
while((receive_RING==1)&&(receive_CLIP==1))
{ Delay(10);
receive_OK = 0;
send_m_byte("ath\r\n",5);
while(receive_OK == 0) ;
Xmodem();
Delay(10);
mms_atsent();
receive_RING=0;
receive_CLIP=0;
}
}
}
void send_a_byte( unsigned char data )
{
/* 等待发送缓冲器为空 */
while ( !( UCSRA & (1<<UDRE)) )
;
/* 将数据放入缓冲器,发送数据 */
UDR = data;
}
/*unsigned char USART_Receive( void )
{
//等待接收数据
while ( !(UCSRA & (1<<RXC)) )
;
// 从缓冲器中获取并返回数据
return UDR;
}*/
void send_m_byte(uchar *string, uint length)
{
uint i; //发送多字节
for(i = 0; i< length; i++)
{
send_a_byte(string[i]);
}
}
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 ]);
}
/*
*************************************
*延时子程序,延时约10×i机器周期 *
*************************************/
void intDelay(uint i)
{
while(i--);
}
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;
}
//char do_serial_data(uchar lenth)
void do_serial_data(void)
{
uchar i;
if(receive_data[0]=='+')
{ receive_CLIP = 1;
if('1' == receive_data[8] && ((receive_data[18] >= '0') && (receive_data[18] <= '9')))
{
for(i=8;i<19;i++)
dial_number[i-8]=receive_data[i];
flag_mobile = 1;
}
else if('0'==receive_data[8])
{
i = 8;
while((receive_data[i] >= '0') && (receive_data[i] <= '9'))
{
dial_number[i-8]=receive_data[i];
i++;
telephone_long = i-8;
}
flag_telephone = 1;
}
}
/*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:
if(memcmp_self(receive_data, DATA_RING,4)==0 ) //检测是否收到 OK
receive_RING = 1;
break;
case 5:
if(memcmp_self(receive_data, DATA_ERROR, 5)==0) //检测是否收到 ERROR
receive_ERROR = 1;
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 17:
if(memcmp_self(receive_data,DATA_DOWNFINEOK,17)) //检测是否收到 Ok_Info_FileClose
receive_DOWNFINEOK = 1;
break;
case 25:
if(memcmp_self(receive_data,DATA_DOWNFINE,25)) //检测是否收到 Ok_Info_FileUploadStarted
receive_DOWNFINE = 1;
break;
case 29:
if(memcmp_self(receive_data,DATA_CLIP,5)) //检测是否收到 Ok_Info_FileClose
{ receive_CLIP = 1;
for(i=8;i<19;i++)
dial_number[i-8]=receive_data[i];
}
default:
break;
}*/
}
//1MS的延时
void Delay(unsigned int Delay_MS)
{
unsigned char i;
while(Delay_MS--)
{
for(i=0;i<111;i++);
}
}
void sendcmd(unsigned char *by_Array)
{
while(*by_Array)
{
while (!( UCSRA & (1<<UDRE)));
UDR=*by_Array;
by_Array++;
}
}
void mms_atsent(void)
{
receive_OK=0;
sendcmd("AT$MMSW=0\r\n") ;
while(receive_OK==0) ;
Delay(10);
receive_DAYUHAO=0;
sendcmd("AT$MMSW=1,1\r\n") ;
while(receive_DAYUHAO==0) ;
receive_OK=0;
send_m_byte(dial_number,11);
send_a_byte(ctrl_z);
while(receive_OK==0) ;
Delay(10);
receive_DAYUHAO=0;
sendcmd("AT$MMSW=4,1\r\n");
while(receive_DAYUHAO==0) ;
receive_OK=0;
sendcmd(subject);
send_a_byte(ctrl_z);
while(receive_OK==0) ;
Delay(10);
receive_DAYUHAO=0;
sendcmd("AT$MMSW=5,1,1\r\n");
while(receive_DAYUHAO==0) ;
receive_OK=0;
sendcmd("mypicture");
send_a_byte(ctrl_z);
while(receive_OK==0) ;
Delay(10);
receive_OK=0;
sendcmd("AT$MMSW=6,1,\"test.jpg\"\r\n");
while(receive_OK==0) ;
Delay(10);
receive_OK=0;
sendcmd("AT$MMSSEND\r\n");
while(receive_OK==0) ;
Delay(10);
receive_MMSTRACE=0;
while(receive_MMSTRACE==0) ;
receive_OK=0;
sendcmd(deletmms);
while(receive_OK==0) ;
}
void Xmodem(void)
{ int i;
pic = test_pic1;
receive_sp = 0;
for (i = 1; i < 65530; i++)
{
if((*(pic-1) == 0xff) &&((*pic) == 0xd9))
{
break;
}
pic++;
}
picLenth = i;
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 + -