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

📄 m16_xmodem._c

📁 AVR 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 + -