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

📄 messaging.c

📁 whereavr是一个用ATMEL M8实现的AX.25精简协议栈,搜了很多资料,这个是对学习自动位置报告系统最好的实例
💻 C
字号:
/*******************************************************************************File:			Messaging.c 				Messaging subsystem function library for the atmega8.Functions:	extern void MsgInit (void)				extern void MsgPrepare (void)				extern void MsgSendPos (void)				extern void MsgSendTelem (void)		extern void MsgSendAck (unsigned char *rxbytes, unsigned char msg_start)				extern void SerHandler (unsigned char newchar);Revisions:	1.00	11/02/04	GND	Gary Dion				1.01	11/28/04	GND	Added MsgSendAck routine				1.02	06/23/05	GND	Converted to C++ comment style and cleaned upCopyright:	(c)2005, Gary N. Dion (me@garydion.com). All rights reserved.				This software is available only for non-commercial amateur radio				or educational applications.  ALL other uses are prohibited.				This software may be modified only if the resulting code be				made available publicly and the original author(s) given credit.*******************************************************************************/// OS headers#include <avr/eeprom.h>#include <avr/interrupt.h>#include <avr/io.h>#include <avr/signal.h>// General purpose include files#include "StdDefines.h"// App required include files.#include "ADC.h"#include "ax25.h"#include "Messaging.h"#include "Serial.h"#define	GPRMC		(1)#define	GPGGA		(2)static unsigned char	Time[7];				// UTC time in HHMMSS formatstatic unsigned char	Latitude[10];		// Latitude in DDMM.MMMM formatstatic unsigned char	Longitude[11];		// Longitude in DDDMM.MMMM formatstatic unsigned char	Altitude[8];		// Altitude (meters) in MMM.MMM formatstatic unsigned char	Speed[6];			// Speed (knots) in kkk.kk formatstatic unsigned char	Course[6];			// Track angle (degrees) in ddd.dd formatstatic unsigned char	Satellites[3];		// Number of Satellites tracked// Temporary variables used for decoding. Note: Time_Temp[7] is in the .h file.static unsigned char	Latitude_Temp[10];static unsigned char	Longitude_Temp[11];static unsigned char	Altitude_Temp[8];static unsigned char	Speed_Temp[6];static unsigned char	Course_Temp[6];static unsigned char	Satellites_Temp[3];static unsigned char	Altifeet[7];		// Altitude (feet) in FFFFFF formatstatic unsigned char	sentence_type;		// GPRMC, GPGGA, or unrecognized/******************************************************************************/extern void MsgInit (void)/******************************************************************************** ABSTRACT:	Initialize some of the fields in case we transmit before the GPS*				has lock and sends us valid data.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	Speed_Temp[0] = Speed_Temp[1] = Speed_Temp[2] = '0';	Course_Temp[0] = Course_Temp[1] = Course_Temp[2] = '0';	Altitude_Temp[0] = Altitude_Temp[1] = '0';	Altitude_Temp[2] = '.';	return;}		// End MsgInit/******************************************************************************/extern void MsgPrepare(void)/******************************************************************************** ABSTRACT:	Call this function right before sending a position report for two*				reasons. This copies all the temp strings into transmit strings so*				they are not modified by the GPS receive handler.  Altitude is also*				converted into feet from meters.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	static unsigned long	LongAltitude;	// Used to convert meters to feet	static unsigned long	LongTemp;		// Just a long temp variable	static unsigned char	index;			// For indexing local arrays	static unsigned char	count;			// Keeps track of loops	in F-to-A	for (index = 0; index < 6 ; index++)			// Grab latest Time		Time[index] = Time_Temp[index];	Time[index] = 0; 										// Terminate string	for (index = 0; index < 9 ; index++)			// Grab latest Latitude		Latitude[index] = Latitude_Temp[index];	Latitude[index] = 0;									// Terminate string	for (index = 0; index < 10 ; index++)			// Grab latest Longitude		Longitude[index] = Longitude_Temp[index];	Longitude[index] = 0;								// Terminate string	for (index = 0; index < 7 ; index++)			// Grab latest Altitude		Altitude[index] = Altitude_Temp[index];	Altitude[index] = 0;									// Terminate string	for (index = 0; index < 5 ; index++)			// Grab latest Speed		Speed[index] = Speed_Temp[index];	Speed[index] = 0;										// Terminate string	for (index = 0; index < 5 ; index++)			// Grab latest Course		Course[index] = Course_Temp[index];	Course[index] = 0;									// Terminate string	for (index = 0; index < 2 ; index++)			// Grab latest Satellites		Satellites[index] = Satellites_Temp[index];	Satellites[index] = 0;								// Terminate string	index = 0;									// Reset index for this search	Altitude[6] = '.';						// Force last character to a '.'	while (Altitude[++index] != '.');	// Find the decimal in Alt string	LongAltitude = 0;							// Begin with a blank slate	while (index)			// This is Float-to-A, working from the decimal leftward	{		LongAltitude += (Altitude[--index] - 48) * LongTemp; // Right to left		LongTemp *= 10;						// Each digit is worth 10x previous	}	// The LongAltitude variable now contains the altitude in meters.	// The following is an approximation of 3.28 to convert Meters to Feet	LongAltitude *= 3;						// Start by multiplying by 3	LongAltitude += LongAltitude>>4;		// add to self/16  (3.1875)	LongAltitude += LongAltitude>>6;		// add to self/64  (3.2373)	LongAltitude += LongAltitude>>7;		// add to self/128 (3.2626)	LongAltitude += LongAltitude>>8;		// add to self/256 (3.2758)	LongAltitude += LongAltitude>>10;	// add to self/1024 (3.279)	// The LongAltitude variable now contains the altitude in feet.	// This converts a long to ASCII with six characters & leading zeros.	count = 0;									// Convert to character each cycle	index = 0;									// Start on left and work right	for (LongTemp = 100000 ; LongTemp > 1; LongTemp /= 10)	{		while (LongAltitude >= LongTemp)	// Convert each order of 10 to a #		{			LongAltitude -= LongTemp;		// By looping, sub'ing each time			count++;								// Keep track of iteration loops		}		Altifeet[index++] = count + 48;	// Save that count as a character		count = 0;								// Reset count and start over	}	Altifeet[index++] = LongAltitude + 48;	// Last digit resides in LongAlt...	Altifeet[index] = 0;						// Terminate string	return;}		// End MsgPrepare(void)/******************************************************************************/extern void MsgSendPos(void)/******************************************************************************** ABSTRACT:	Send an APRS formatted message containing timestamped position data,*				a symbol, the course, speed, altitude, and # of satellites received.*				I also added two channels of analog data for temperature & voltage.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	ax25sendByte('@');						// The "@" Symbol means time stamp first	ax25sendString(Time);					// Send the time	ax25sendByte('z');						// Tag it as zulu	Latitude[7] = 0;							// Truncate Latitude past 7th character	ax25sendString(Latitude);				// Send it	ax25sendByte('N');						// As degrees North	ax25sendByte('/');						// Symbol Table Identifier	Longitude[8] = 0;							// Truncate Longitude past 8th character	ax25sendString(Longitude);				// Send it	ax25sendByte('W');						// As degrees West	ax25sendByte('O');						// Symbol Code for a balloon icon	Course[3] = 0;								// Truncate course at 3 characters	ax25sendString(Course);					// Transmit Course	ax25sendByte('/');						// Just a separator with no meaning	Speed[3] = 0;								// Truncate speed at 3 characters	ax25sendString(Speed);					// Transmit Speed	// Begin Comment - up to 36 characters are permissable	ax25sendByte('/');						// A little more data...	ax25sendByte('A');						// ...to be interpreted as altitude...	ax25sendByte('=');						// ...starts right now	ax25sendString(Altifeet);				// Send Altitude in feet	ax25sendByte(' ');						// Space for formatting	// Send number of Satellites tracked in HEX	if (Satellites[0] == '1') Satellites[1] += 17; // '0' becomes 'A'...	ax25sendByte(Satellites[1]);	ax25sendByte(' ');						// Space for formatting	ax25sendASCIIebyte(ADCGet(0) + 7);	// Send analog channel 0	ax25sendByte(' ');						// Space for formatting	ax25sendASCIIebyte((ADCGet(1)<<1) + 33);	// Send analog channel 1	return;}		// End MsgSendPos(void)/******************************************************************************/extern void MsgSendTelem(void)/******************************************************************************** ABSTRACT:	Send an APRS formatted message containing telemetry.** INPUT:		None* OUTPUT:	None* RETURN:	None*/{	static unsigned char	sequence;		// Telemetry sequence number	static unsigned char	temp;				// To loop analog / digital channels	ax25sendByte('T');						// Data type identifier for telemetry	ax25sendByte('#');						// "#" for sequence number	ax25sendASCIIebyte(sequence++);		// Transmit the sequence number...	ax25sendByte(',');						// First comma preceding analog values	for (temp = 1 ; temp < 6 ; temp++)	// For analog channels 1 through 5...	{		ax25sendASCIIebyte(ADCGet(temp));// Send their values in ASCII		ax25sendByte(',');					// A comma following each analog value	}	// Send eight digital channels	ax25sendByte((PIND & 1<<1)? '1' : '0');	// Check pin & choose character	ax25sendByte((PIND & 1<<2)? '1' : '0');	// Check pin & choose character	ax25sendByte((PIND & 1<<3)? '1' : '0');	// Check pin & choose character	ax25sendByte((PIND & 1<<4)? '1' : '0');	// Check pin & choose character	ax25sendByte((PIND & 1<<5)? '1' : '0');	// Check pin & choose character	ax25sendByte((PIND & 1<<6)? '1' : '0');	// Check pin & choose character	ax25sendByte((0)? '1' : '0');					// TBD & choose character	ax25sendByte((0)? '1' : '0');					// TBD & choose character	// Begin Comment - up to TBD characters are permissable	ax25sendByte(',');						// Another comma so that I can...	ax25sendASCIIebyte(ADCGet(0));		// Send analog channel 0 in ASCII	ax25sendByte(',');						// Another comma so that I can...	ax25sendString(Time);					// Send the time	return;}		// End MsgSendTelem(void)/******************************************************************************/extern void MsgSendAck(unsigned char *rxbytes, unsigned char msg_start)/******************************************************************************** ABSTRACT:	Send an APRS formatted message to acknowledge receipt of a command.** INPUT:		*rxbytes		Pointer to the received character array*				msg_start	Character of the first byte in the message* OUTPUT:	None* RETURN:	None*/{	static unsigned char	pad;				// Number of spaces the address is padded	static unsigned char	ploop;			// Used in the loop which pads spaces	pad = 0;										// Initialize the pad variable	ax25sendByte(':');						// Send ack message	ax25sendByte(rxbytes[7]>>1);			// To originating	ax25sendByte(rxbytes[8]>>1);			//  callsign	ax25sendByte(rxbytes[9]>>1);	ax25sendByte(rxbytes[10]>>1);	if (rxbytes[11] != 0x40) ax25sendByte(rxbytes[11]>>1);	// 5th char?	else pad += 1;											// Or just pad with a space	if (rxbytes[12] != 0x40) ax25sendByte(rxbytes[12]>>1);	// 5th char?	else pad += 1;											// Or just pad with a space	rxbytes[13] = (rxbytes[13]>>1) - 64;			// Convert SSID to ASCII	if (rxbytes[13] == 48)					// No SSID for call	{		pad += 3;								// So pad three spaces to the callsign	}	else	{		if (rxbytes[13] < 58)				// SSID < 10		{			ax25sendByte('-');				// Hyphenate the callsign and SSID			ax25sendByte(rxbytes[13]);		// Send ones digit of station SSID			pad += 1;							// Need to pad with one more space		}		else 										// SSID > 9		{			ax25sendByte('-');				// Hyphenate the callsign and SSID			ax25sendByte('1');				// Send tens digit of station SSID			ax25sendByte(rxbytes[13] - 10);	// Send last digit of SSID		}	}	for (ploop = 0 ; ploop < pad ; ploop++)		ax25sendByte(' ');					// Send all those pad spaces for 9 chars	ax25sendByte(':');						// We are still acknowledging	ax25sendByte('a');	ax25sendByte('c');	ax25sendByte('k');	ax25sendString(&(rxbytes[msg_start + 13]));	// Send ack message number	return;}		// End MsgSendAck(unsigned char *rxbytes, unsigned char msg_start)/******************************************************************************/extern void MsgHandler(unsigned char newchar)/******************************************************************************** ABSTRACT:	Processes the characters coming in from USART.  In this case,*				this is the port connected to the gps receiver.** INPUT:		newchar	Next character from the serial port.* OUTPUT:	None* RETURN:	None*/{	static unsigned char	commas;			// Number of commas for far in sentence	static unsigned char	index;			// Individual array index	if (newchar == 0)							// A NULL character resets GPS decoding	{		commas = 25;							// Set to an outrageous value		sentence_type = FALSE;				// Clear local parse variable		return;	}	if (newchar == '$')						// Start of Sentence character, reset	{		commas = 0;								// No commas detected in sentence for far		sentence_type = FALSE;				// Clear local parse variable		return;	}	if (newchar == ',')						// If there is a comma	{		commas += 1;							// Increment the comma count		index = 0;								// And reset the field index		return;	}	if (commas == 0)	{		switch(newchar)		{			case ('C'):							// Only the GPRMC sentence contains a "C"				sentence_type = GPRMC;		// Set local parse variable				break;			case ('S'):							// Take note if sentence contains an "S"				sentence_type = 'S';			// ...because we don't want to parse it				break;			case ('A'):							// The GPGGA sentence ID contains "A"				if (sentence_type != 'S')	// As does GPGSA, which we will ignore					sentence_type = GPGGA;	// Set local parse variable				break;		}		return;	}	if (sentence_type == GPGGA)			// GPGGA sentence	decode initiated	{		switch (commas)		{			case (1):									// Time field, grab characters				Time_Temp[index++] = newchar;				return;			case (2):									// Latitude field, grab chars				Latitude_Temp[index++] = newchar;				return;			case (4):									// Longitude field, grab chars				Longitude_Temp[index++] = newchar;				return;			case (7):									// Satellite field, grab chars				Satellites_Temp[index++] = newchar;				return;			case (9):									// Altitude field, grab chars				Altitude_Temp[index++] = newchar;				return;		}		return;	}		// end if (sentence_type == GPGGA)	if (sentence_type == GPRMC)			// GPGGA sentence	decode initiated	{		switch (commas)		{			case (7):									// Speed field, grab characters				Speed_Temp[index++] = newchar;				return;			case (8):									// Course field, grab characters				Course_Temp[index++] = newchar;				return;		}		return;	}		// end if (sentence_type == GPRMC)	return;}		// End MsgHandler(unsigned char newchar)

⌨️ 快捷键说明

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