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

📄 main.c

📁 whereavr是一个用ATMEL M8实现的AX.25精简协议栈,搜了很多资料,这个是对学习自动位置报告系统最好的实例
💻 C
📖 第 1 页 / 共 2 页
字号:
	return;}		// End mainReceive(void)/******************************************************************************/extern void ax25rxByte(unsigned char rxbyte)/******************************************************************************** ABSTRACT:	This function calculates the crc of the incomming message.** INPUT:		txbyte	The byte to transmit* OUTPUT:	None* RETURN:	None*/{	static unsigned char		loop;			// Generic loop variable	static unsigned short	lsb_int;		// LSBit of incoming byte	static unsigned short	xor_int;		// Used for the IF statement	for (loop = 0 ; loop < 8 ; loop++)	// Loop through all eight bits	{		lsb_int = rxbyte & 0x01;			// Set aside the least significant bit		xor_int = crc ^ lsb_int;			// XOR lsb of CRC with the latest bit		crc >>= 1;								// Shift 16-bit CRC one bit to the right		if (xor_int & 0x0001)				// If XOR result from above has lsb set		{			crc ^= 0x8408;						// XOR the crc with magic number		}		rxbyte >>= 1;							// Shift the reference byte one bit right	}	return;}		// End ax25rxByte(unsigned char rxbyte)/******************************************************************************/extern void mainDelay(unsigned char timeout)/******************************************************************************** ABSTRACT:	This function sets "maindelay", programs the desired delay,*				and takes care of incoming serial characters until it's cleared.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	maindelay = TRUE;							// Set the condition variable	WatchdogReset();							// Kick the dog before we start	TCNT0 = 255 - timeout;					// Set desired delay	while(maindelay)	{		Serial_Processes();					// Do this until cleared by interrupt	}	return;}		// End mainDelay(unsigned int timeout)/******************************************************************************/extern void Delay(unsigned char timeout)/******************************************************************************** ABSTRACT:	This function sets "delay", programs the desired delay,*				and takes care of incoming serial characters until it's cleared.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	delay = TRUE;							// Set the condition variable	WatchdogReset();						// Kick the dog before we start	TCNT2 = 255 - timeout;				// Set desired delay	while(delay)	{		Serial_Processes();				// Do this until cleared by interrupt	}	return;}		// End Delay(unsigned char timeout)/******************************************************************************/SIGNAL(SIG_OVERFLOW0)/******************************************************************************** ABSTRACT:	This routine now decodes packets by sampling the state of*				rxtoggled, and assembling a packet if toggles occur.  A checksum is*				performed for validation, then msg_end is set to message size.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	static unsigned char sample_clock;	// Sample count since last sync	static unsigned char next_sample;	// Sample on which to grab next bit	static unsigned char last8bits;		// Last 8 bits received	static unsigned char bit_count;		// Bits of the next incoming byte	static unsigned char ones_count;		// Sequential ones (detect a stuff)	static unsigned char start_temp;		// Msg starts at end of header	static unsigned char	bytes_recd;		// Incoming byte index	static unsigned char crcstate;		// State of message checksum check	static unsigned char crchi;			// High byte of expected crc	if (transmit)	{		maindelay = FALSE;					// Clear condition holding up mainDelay		TCNT0 = 0;								// Make long as possible delay	}	else	{		TCNT0 = 69;								// Set sample rate to 9600 Hz. 		if (dcd)									// If we are actively monitoring a signal		{			dcd--;								// Decrement the dcd timer			busy = TRUE;			if (rxtoggled)						// See if a tone toggle was recognized			{				if(ones_count != 5)			// Only process if NOT a bit stuff toggle				{					bit_count++;				// Increment bit counter					last8bits >>= 1;			// Shift in a zero from the left				}				rxtoggled = FALSE;			// Clear toggle flag				ones_count = 0;				// Clear number of sequential ones				sample_clock = 0;				// Sync clock for bit sampling				next_sample = 12;				// Grab next bit after 12 clicks			}			else			{				if (++sample_clock == next_sample)	// Time to grab next bit?				{					ones_count++;				// Increment ones counter since no toggle					bit_count++;				// Increment bit counter					last8bits >>= 1;			// Shift the bits to the right					last8bits |= 0x80;		//  shift in a one from the left					sample_clock = 0;			// Clear the clock for bit sampling					next_sample = 8;			// Grab next bit 8 clicks from now				}			}	// end else for 'if (rxtoggled)'			if (last8bits == 0x7E)			// If the last 8 bits match the ax25 flag			{				crc = 0xFFFF;					// Initialize the crc register				bit_count = 0;					// Sync bit_count for an 8-bit boundary				bytes_recd = 0;				// Point to start of message buffer				start_temp = 0;				// Init message pointer as well				crcstate = 0;					// Start out expecting crc after header			}			else			{				if (bit_count == 8)			// Just grabbed 8'th bit for a full byte				{					if ((start_temp) && (crcstate == 0)) // Ready for LSB of crc?					{						if (last8bits == ((crc ^ 0xFF) & 0xFF)) // And see it?						{							PORTB |= 1;						// Turn on the DCD LED							crchi = (crc >> 8)^0xFF;	// Preserve MSB of crc							crcstate = 1;					// Expect the MSB of crc next						}					}					else if (crcstate)		 // Or looking for MSB of crc?					{						if (last8bits == crchi) 		// And it so happens to match						{							msg_start = start_temp; 	// Save message start							msg_end = bytes_recd - 2;	// Save message end							rxbytes[msg_end + 1] = 0;	// Null terminate string							ACSR &= ~(1<<ACIE);			// Disable the comparator						}						crcstate = 0;			// Revert to looking for LSB					}					bit_count = 0;				// Reset bit counter					ax25rxByte(last8bits);	// Update checksum					if (!(msg_end))						rxbytes[bytes_recd++] = last8bits;	// And stuff the byte					if ((rxbytes[bytes_recd-1] == 0xF0) &&	// End of header bytes						 (rxbytes[bytes_recd-2] == 0x03))	//  means end of header							start_temp = bytes_recd;			// Remember location				}		// end 'if (bit_count == 8)'			}		// end else for 'if (last8bits == 0x7E)'		}		// end 'if (dcd)'		else		{			busy = FALSE;			PORTB &= 0x3E;						// Turn off the DCD LED		}		// end else for 'if (dcd)'	}		// end else for 'if (!(transmit))'}		// End SIGNAL(SIG_OVERFLOW0)/******************************************************************************///SIGNAL(SIG_OVERFLOW1)/******************************************************************************** ABSTRACT:	This function would handle the counter1 overflow interrupt.	Since*				TCNT1 is used for for another process, we can't use this function.*///{//}		// End SIGNAL(SIG_OVERFLOW1)/******************************************************************************/SIGNAL(SIG_OVERFLOW2)/******************************************************************************** ABSTRACT:	This function handles the counter2 overflow interrupt.*				Counter2 is used to generate a sine wave using resistors on*				Pins B5-B1. Following are the sixteen 4-bit sinewave values:*							7, 10, 13, 14, 15, 14, 13, 10, 8, 5, 2, 1, 0, 1, 2, 5.*				If in receive mode, the counter is pre-loaded with a long delay*				and the delay variable is cleared.**		 !!!Important!!! This code is -optimized- for the least # of clock cycles.*				If you modify it, PLEASE be sure you know what you're doing!** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	// This line is for if you followed the schematic:	static char	sine[16] = {58,22,46,30,62,30,46,22,6,42,18,34,2,34,18,42};	// This line is for if you installed the resistors in backwards order :-) ://	static char	sine[16] = {30,42,54,58,62,58,54,42,34,22,10,6,2,6,10,22};	static unsigned char sine_index;		// Index for the D-to-A sequence	if (transmit)	{		++sine_index;							// Increment index		sine_index &= 15;						// And wrap to a max of 15		PORTB = sine[sine_index];			// Load next D-to-A sinewave value		TCNT2 = txtone;						// Preload counter based on freq.	}	else	{		delay = FALSE;							// Clear condition holding up Delay		TCNT2 = 0;								// Make long as possible delay	}}		// End SIGNAL(SIG_OVERFLOW2)/******************************************************************************/SIGNAL(SIG_COMPARATOR)/******************************************************************************** ABSTRACT:	This function handles the comparator interrupt.  Interrupts are*				disabled during TCNT1 access to prevent 16-bit corruption.*				A 1200 tone is 768 counts and 2200 tone is 419 at 14.7456 MHz.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	static unsigned short	count;	static unsigned char 	last;	// Ideally, interrupts should be disabled when TCNT1 is read and written to.	// This is because it's a 2-byte "atomic" operation. In this case, the extra	// step was omitted to save cycles.  This -may- cause occasional packet loss.	if (!(msg_end))							// If not waiting to progress a message	{		count = TCNT1;							// Read counts since last interrupt		if (count > 542)						// Below 1700 Hz?	(542 @ 14.7456 MHZ)		{			TCNT1 = 0;							// Clear the counter			if (last == SPACE)				// If the last tone detected was a SPACE			{				rxtoggled = TRUE;				// Toggle detected				dcd = count;					// Set "random" timeout			}			last = MARK;						// MARK is detected		}		else if (count > 100)				// Ignore a frequency above 4.6 kHz		{			TCNT1 = 0;							// Clear the counter			if (last == MARK)					// If the last tone detected was a SPACE			{				rxtoggled = TRUE;				// Toggle detected				dcd = count;					// Set "random" timeout			}			last = SPACE;						// SPACE is detected		}	}}		// End SIGNAL(SIG_COMPARATOR)

⌨️ 快捷键说明

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