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

📄 ping.txt

📁 基于PIC单片机的PPOE协议栈源代码。
💻 TXT
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////////////
//
//    PING.C    version 1.10    July 29/99     (C)opyright by Microchip Technology Inc
//
///////////////////////////////////////////////////////////////////////////////////////
//
// For more documentation read the Microchip Application Note 724
// This code is ready to compile with the HiTech C compiler demo for the PIC16C63A.
//
// You will need these additional things to make this code work:
//
//    - the simple hardware described in application note
//
//    - an Internet account with PPP dialup access (not compatible with all ISPs)
//
//    - replace 5551234 with your ISP's phone number in the line like this
//         if (sendwait("5551234\r","NNECT",3000)) {
//
//    - replace userid with your account userid in the line like this:
//         if (sendwait("userid\r","word:",200))
//
//    - replace password with your account password in the line like this:
//         if (sendwait("password\r","tion:",1000))
//
//    - replace the entire string in the line like this:
//         MakePacket(PAP,REQ,number,"\x14\x06userid\x08password");
//
//         C converts the \x## in the string to a character with that ASCII value
//         ## is a hexadecimal value, so the following character cannot be
//         if the next character is 0-9 or A-F or a-f then it will confuse the compiler
//         the solution is to convert the next characters to \x## until a non hex char
//         if in doubt look at the assembly output from the compiler
//         or try MakePacket(PAP,REQ,number,"\x14\x06" "userid\x08" "password");
//         replace the userid with yours and the \x06 with your userid length
//         replace the password with yours and the \x08 with your password length
//         replace the first value in the string, it must be the string length plus 4
//
// Once login is working you should also change the IP address of the Internet host to ping
// if you can not ping 207.161.117.67 with your PC this code will not work either
//    It is CF.A1.75.43, the characters 2 to 5, in the string in the line like this:
//       MakePacket(IP,0,1,"\x10\xCF\xA1\x75\x43\x8\x0\xF7\xFE\x0\x1\x0\x0");
//    Convert the address you want to hexadecimal and replace the four values.
//
// Make sure the power-on reset and brownout detect config bits are enabled
//
///////////////////////////////////////////////////////////////////////////////////////

// Defines for Internet constants
#define	REQ	1 	// Request options list for PPP negotiations
#define	ACK	2	// Acknowledge options list for PPP negotiations
#define	NAK	3	// Not acknowledged options list for PPP negotiations
#define	REJ	4	// Reject options list for PPP negotiations
#define	TERM	5	// Termination packet for LCP to close connection
#define	IP	0x0021	// Internet Protocol packet
#define	IPCP	0x8021	// Internet Protocol Configure Protocol packet
#define	CCP	0x80FD	// Compression Configure Protocol packet
#define	LCP	0xC021	// Link Configure Protocol packet
#define	PAP	0xC023	// Password Authenication Protocol packet

#define	MaxRx	46	// Maximum size of receive buffer
#define	MaxTx	46	// Maximum size of transmit buffer

unsigned char addr1, addr2, addr3, addr4;	// Assigned IP address
unsigned int rx_ptr, tx_ptr, tx_end;		// pointers into buffers
unsigned int checksum1, checksum2;		// Rx and Tx checksums
unsigned char number;				// Unique packet id

#include <pic1663.h>	// Defines specific to this processor

#define serial_init()	RCSTA=0x90;TXSTA=0x24;SPBRG=103	// Set up serial port
#define serial_tx_ready()	TXIF				// Transmitter empty
#define serial_send(a)	TXREG=a			// Transmit char a
#define serial_rx_ready()	RCIF				// Receiver full
#define serial_get()	RCREG				// Receive char
#define serial_error()	OERR				// USART error
#define serial_fix()	{CREN=0;CREN=1;}		// Clear error

unsigned int TIME;				// 10 millseconds counter
#define TIME_SET(a) TIME=a			// Set 10 millisecond counter to value 'a'
bank1 unsigned char tx_str[MaxRx+1];	// Transmitter buffer
bank1 unsigned char rx_str[MaxTx+1];	// Receiver buffer

// Process all the interupts in the PIC here
static void interrupt isr(void) {
   if (T0IF) {			// Timer overflow interrupt?
      TMR0 = 100;			// Set to overflow again in 10ms @ 4MHz
      T0IF = 0;			// Clear overflow interrupt flag
      TIME++;				// Increment 10 ms counter
   }
}

// Add next character to the CRC checksum for PPP packets
unsigned int calc(unsigned int c) {
   char i;				// Just a loop index
   c &= 0xFF;				// Only calculate CRC on low byte
   for (i=0;i<8;i++) {		// Loop eight times, once for each bit
      if (c&1) {			// Is bit high?
         c /= 2;			// Position for next bit      
         c ^= 0x8408;		// Toggle the feedback bits
      } else c /= 2;		// Just position for next bit
   }					// This routine would be best optimized in assembly
   return c;				// Return the 16 bit checksum
}

// Add character to the new packet
void add(unsigned char c) {
   checksum2 = calc(c^checksum2) ^ (checksum2/256); // Add CRC from this char to running total
   tx_str[tx_ptr] = c;		// Store character in the transmit buffer
   tx_ptr++;				// Point to next empty spot in buffer
}

// Create packet of type, code, length, and data string specified
//   packet is the type, like LCP or IP
//   code is the LCP type of packet like REQ, not used for IP packets
//   num is the packet ID for LCP, or the IP data type for IP packets
//   *str is the packet data to be added after the header
//   returns the packet as a string in tx_str
void MakePacket(unsigned int packet, unsigned char code, unsigned char num, const unsigned char *str) {
   unsigned int length;		// Just a dual use temp variable
   tx_ptr = 1;			// Point to second character in transmit buffer
   tx_str[0] = ' ';			// Set first character to a space for now
   checksum2 = 0xFFFF;		// Initialize checksum
   add(0xFF);				// Insert PPP header OxFF
   add(3);				// Insert PPP header 0x03
   add(packet/256);			// Insert high byte of protocol field
   add(packet&255);			// Insert low byte of protocol field
   if (packet==IP) {		// If Internet Protocol
      add(0x45);			// Insert header version and length
      add(0);				// Insert type of service
      add(0);				// Insert total packet length high byte
      add((*str)+12);		// Insert total packet length low byte
      add(0x88);			// Insert identification high byte
      add(0x10);			// Insert identification low byte
      add(0x40);			// Insert flags and fragement offset
      add(0);				// Insert rest of fragment offset
      add(127);			// Insert time to live countdown
      add(num);			// insert the protocol field
      length = 0x45+0x88+0x40+127+addr1+addr3+str[1]+str[3];  // high byte checksum
      packet = *str + 12 + 0x10 + num + addr2 + addr4 + str[2] + str[4];  
							// low byte checksum
      packet += length/256;			// make 1's complement
      length = (length&255) + packet/256;	// by adding low carry to high byte
      packet = (packet&255) + length/256;	// and adding high carry to low byte
      length += packet/256;			// fix new adding carries
      add(~length);			// Insert 1's complement checksum high byte
      add(~packet);			// Insert 1's complement checksum low byte
      add(addr1);			// Insert the 4 bytes of this login's IP address
      add(addr2);
      add(addr3);
      add(addr4);
      length = *str - 4;		// save the number of following data bytes
      str++;				// point to the first data byte
   } else {
      add(code);			// Insert packet type, like REQ or NAK
      add(num);			// Insert packet ID number
      add(0);				// Insert most significant byte of length
      length = *str - 3;		// point to the first data byte
   }
   while (length) {			// copy the whole string into packet
      length--;			// decrement packet length
      add(*str);			// add current character to packet
      str++;				// point to next character
   }
   length = ~checksum2;		// invert the checksum
   add(length&255);			// Insert checksum msb
   add(length/256);			// Insert checksum lsb
   tx_end=tx_ptr;			// Set end of buffer marker to end of packet
   tx_ptr = 0;			// Point to the beginning of the packet
}

// Test the option list in packet for valid passwords
//   option is the 16 bit field, where a high accepts the option one greater than the
//   bit #
//   returns 2 for LCP NAK, 1 is only correct fields found, and zero means bad options
//   return also modifies RX_STR to list unacceptable options if NAK or REJ required
unsigned char TestOptions(unsigned int option){
   unsigned int size;		// size is length of option string
   unsigned ptr1 = 8,		// ptr1 points data insert location
            ptr2 = 8;		// ptr2 points to data origin
   char pass = 3;			// pass is the return value
   size = rx_str[7]+4;		// size if length of packet
   if (size>MaxRx) size=MaxRx;	// truncate packet if larger than buffer
   while (ptr1<size) {		// scan options in receiver buffer
      if (rx_str[ptr1]==3 && rx_str[ptr1+2]!=0x80  && rx_str[2]==0xc2)
         pass&=0xfd;		// found a CHAP request, mark for NAK
      if (!((1<<(rx_str[ptr1]-1))&option))
         pass=0;			// found illegal options, mark for REJ
      ptr1 += rx_str[ptr1+1];	// point to start of next option
   }
   if (!(pass&2)) {			// If marked for NAK or REJ
      if (pass&1) {			// save state for NAK
         option=0xfffb;
      }
      for (ptr1=8; ptr1<size;) {
         if (!((1<<(rx_str[ptr1]-1))&option)) {	// if illegal option
            for (pass=rx_str[ptr1+1]; ptr1<size && pass; ptr1++) {  // move option
               rx_str[ptr2]=rx_str[ptr1];		// move current byte to new storage
               ptr2++;					// increment storage pointer
               pass--;					// decrement number of characters
            }
         } else {
            ptr1+=rx_str[ptr1+1];				// point to next option
         }
      }
      rx_str[7] = ptr2-4;			// save new option string length
      pass=0;					// restore state for REJ
      if (option==0xfffb) pass=1;		// restore state for NAK
   }
   return pass;
}

// Send a string and loop until wait string arrives or it times out
//  send is the string to transmit
//  wait is the string to wait for
//  timeout is in multiples of 10 milliseconds
//  addr1 is used to control the status LED, 0=off, 1=flash, 2=on
//  returns 0 if timeout, returns 1 if wait string is matched
char sendwait(const char *send, const char *wait, unsigned int timeout) {
   addr2=addr3=0;
   for (TIME_SET(0); TIME<timeout; ) {		// loop until time runs out
      if (!addr1) PORTB&=0xFB;			// if addr1=0 turn off status LED
      else if (addr1==1) {				// if addr1=1 flash status LED
         if (TIME&4) PORTB&=0xFB;			// flash period is 8 x 10ms 
         else PORTB|=4;
      } else PORTB|=4;				// if addr1>1 turn on status LED
      if (serial_rx_ready()) {			// is there an incoming character
         PORTB|=1;					// turn on the Rx LED
         addr4 = serial_get();			// get character
         if (serial_error()) serial_fix();	// clear serial errors
         if (wait[addr2]==addr4) addr2++;	// does char match wait string
         else addr2=0;				// otherwise reset match pointer
         PORTB&=0xFE;				// turn off the Rx LED
         if (!wait[addr2]) return 1;		// finished if string matches
      } else if (send[addr3] && (serial_tx_ready())) {  // if char to send and Tx ready
         if (send[addr3]=='|') {	// if pause character
            if (TIME>100) {			// has 1 second expired yet?
               TIME_SET(0);			// if yes clear timer
               addr3++;				// and point to next character
            }
         } else {
            PORTB|=2;			// turn on Tx LED
            TIME_SET(0);			// clear timer, timeout starts after last char
            serial_send(send[addr3]);	// send the character
            addr3++;			// point to next char in tx string
         }
         PORTB&=0xFD;			// turn off Tx LED
         if (!send[addr3] && !(*wait))
            return 1; 			// done if end of string and no wait string
      }
   }
   return 0;					// return with 0 to indicate timeout
}

void flash(void) {				// flash all LEDs if catastrophic failure
   for (TIME_SET(0);;) {
      if (TIME&8) PORTB|=0x07;		// flash period is 16 x 10ms
      else PORTB&=0xF8;
      if (TIME>3000) PORTB&=0xF7;	// after 30 seconds turn off the power
   }

⌨️ 快捷键说明

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