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

📄 finalprojectcommented.c

📁 Schifra Reed-Solomon Error Correcting Code Library http://www.schifra.com Copyright (c) 2000-2007
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************* *                             	 *	ECE 476 - Final Project - 5/5/04	 * *	(31,16) BCH Triple Eroor Correcting Code. *			Version 9.0 - Final * *	Alexander Krol & Cezar Serban * */#include <Mega32.h>#include <stdio.h>#include <stdlib.h>#include <math.h>		// For use of power function/** Note: Must be compiled with "char is unsigned" **////** Variable Definitions **//UserStateMachine statesenum {start, original, EncodeDecode, adderror, DisplayToggle, DetailToggle, help};// Various vars for user input and command control with HyperTermunsigned char char_count, char_ready, cmd_str[8], cmd_ready;//User State Machine stateunsigned char UserState;// Message to be encoded/decoded (stored in flash due to its large size)// Note - could easily be a 'stored' file that is to be transmitted// Note the '\r' terminators at the end of the messageflash char Message[] = "This is the Message to be Encoded and Decoded with a (31,16) BCH Triple-Error Correcting Code.\r\r\r";//Global Varsunsigned long EncodedMessage=0;	// Encoded Message as a longchar EncMsgArray[32];			// Encoded Message in Array formatchar n=31, k=16, t=3;			// BCH Code definitionsunsigned long GeneratorPoly = 36783;	// Generator Polynomial: 107657 in octalchar seed=0;				// Random seed for Error module//Counters to keep track of errors for BER calculationsint trans_error_count=0,rec_error_count=0;int enc_message_bits;// Flags for Display and Error Modulebit detail_toggle=0, display_toggle=0, Add_Error=0;// Struct for use in Berlekamp Decoding, allows for arrays of Poly32's// Note that all GF32 arrays contain the POWERS of alpha as their data,// not the actual GF32 element - hence multiplication is actually additionstruct Poly32{	char p[32];};// Define GF32 - ZERO as negative one since a zero would// zero out various multiplications#define ZERO -1// Efficient lookup tables for GF32// Alpha exponents - computed as powers of 2// Where alpha is from the Galois Field(32)flash char lookup[] = {                1,  // a^0  = 0                2,  // a^1  = 1                4,  // a^2  = 2                8,  // a^3  = 3                16, // a^4  = 4                5,  // a^5  = 2 0                10, // a^6  = 3 1                20, // a^7  = 4 2                13, // a^8  = 3 2 0                26, // a^9  = 4 3 1                17, // a^10 = 4 0                7,  // a^11 = 2 1 0                14, // a^12 = 3 2 1                28, // a^13 = 4  3 2                29, // a^14 = 4 3 2 0                31, // a^15 = 4 3 2 1 0                27, // a^16 = 4 3 1 0                19, // a^17 = 4  1 0                3,  // a^18 = 1 0                6,  // a^19 = 2 1                12, // a^20 = 3 2                24, // a^21 = 4 3                21, // a^22 = 4 2 0                15, // a^23 = 3 2 1 0                30, // a^24 = 4 3 2 1                25, // a^25 = 4 3 0                23, // a^26 = 4 2 1 0                11, // a^27 = 3 1 0                22, // a^28 = 4 2 1                9,  // a^29 = 3 0                18, // a^30 = 4 1                1   // a^31 = 0            };flash char reverseLookup[] = {                ZERO, // a^0                0,  // a^1                1,  // a^2                18, // a^3                2,  // a^4                5,  // a^5                19, // a^6                11, // a^7                3,  // a^8                29, // a^9                6,  // a^10                27, // a^11                20, // a^12                8,  // a^13                12, // a^14                23, // a^15                4,  // a^16                10, // a^17                30, // a^18                17, // a^19                7,  // a^20                22, // a^21                28, // a^22                26, // a^23                21, // a^24                25, // a^25                9,  // a^26                16, // a^27                13, // a^28                14, // a^29                24, // a^30                15  // a^31            };/** Function Prototypes **/// Note: For GF2 unisgned longs can be used since only two elements// in the field.  For GF32, byte arrays needed to be used since there// are 32 elements.// State machine definition for the user menu optionsvoid UserStateMachine();// Initialization functionvoid Initialize();// Displays a helpmenu for command definitionsvoid HelpMenu();// Initializes the UART interrupt and flags for reading commandsvoid get_cmd_init();// Main Encoding/Decoding Systemvoid System();// All encoding for BCH ECC is done here - accepts 2 char messagevoid EncoderBCH(unsigned char a, unsigned char b);// All encoding for BCH ECC is done herevoid DecoderBCH();/** Helper Functions **/// Concatenates 2 chars into a longunsigned long Concate(unsigned char num1, unsigned char num2);// Finds the degree of a polynomial encoded as a long in GaloisField2unsigned char GF2FindDegree(unsigned long a);// Adds 2 polynomials encoded as a long - GF2unsigned long GF2Add(unsigned long a, unsigned long b);// Polynomial Multiplication for longs in GF2unsigned long GF2Multiply(unsigned long a, unsigned long b);// Polynomial Division for longs in GF2void GF2Divide(unsigned long a, unsigned long b, unsigned long *qr);// Polynomial Modulo for longs in GF2unsigned long GF2Mod(unsigned long a, unsigned long b);// Retrieves a specified bit from a longunsigned char getBit(unsigned long r, char i);// Converts a long into a 32 length byte arrayvoid Bits2Bytes(unsigned long num, char *p);// Initializes GF32 arrays to ZEROvoid GF32Init(char *p);// Prints an Array byte by bytevoid PrintArray(char *p);// Prints an array in GF32 polynomial formatvoid GF32PrintArray(char *p);// Adds two alpha coefficients in GF32char GF32add2alpha(char a, char b);// Finds the degree of a GF32 polynomialchar GF32FindDegree(char *p);// Evaluates the result of a GF32 Polynomial for some xchar GF32Evaluate(char a, char *p);// Adds all alpha coefficients pairwise in 2 Arrays in GF32void GF32Add(char *a, char *b, struct Poly32 *powers);// Polynomial Multiplication for longs in GF32void GF32Multiply(char *a, char *b, struct Poly32 *mul);// Multiplies a GF32 polynomial with some power of xvoid multiplyX(char x_power, char *p, struct Poly32 *ret);// Multiplies a GF32 polynomial by a constantvoid multiplyConstant(char c, char *p, struct Poly32 *ret);// Corrects the detected errors in an encoded messagevoid CorrectErrors(char *p);// Converts an array of bytes into a longunsigned long Bytes2Bits(char *p);// Parses the lower 16bits of a long into 2 charsvoid deConcate(unsigned long a, unsigned char *ret);// Prints a long as 4 charsvoid PrintLong(unsigned long a);// A random error module that corrupts an encoded messagevoid ErrorModule(char *p, char numerrors);// The Entry point to the ECC unit// Simply initializes and then runs the UserStateMachine forevervoid main(){	Initialize();	while (1)  	{		UserStateMachine();	}}// The user interface: allows the user to select what it// is he wants to do.void UserStateMachine(){	char i, input;	switch (UserState)  	{   		case start: 		// Inital State			if (cmd_ready == 1)	// Check if a command has been entered			{				input = cmd_str[0];	// if so, grab it								if ((input == 'O') || (input == 'o')) // Print out the original message					UserState = original;				else 					get_cmd_init();			// Else, re-init for more user input			    				if ((input == 'N') || (input == 'n')) // Toggle Noise Module On/Off				{					UserState = adderror;				 	get_cmd_init();			// Check for user-inputted random seed				 	if (!Add_Error)			// only if module is being turned on						printf("Enter Random Seed for Noise Module (1-9): ");				}				else 					get_cmd_init();				if ((input == 'R') || (input == 'r'))	// Start Encoding/Decoding					UserState = EncodeDecode;				else					get_cmd_init();				if ((input == 'G') || (input == 'g'))	// Main Display Toggle					UserState = DisplayToggle;		// Displays only partial info				else					get_cmd_init();				if ((input == 'D') || (input == 'd'))	// Detailed Display Toggle					UserState = DetailToggle;		// Can only be activated if Main				else							// Display is on					get_cmd_init();				if ((input == '?'))				// User Help Menu					UserState = help;				else					get_cmd_init();								}		break;		case original:	// Print original message			i=0;			printf("\r\n--Original Message: ");			while (Message[i] != '\r')	// Simply run trhough message until terminator			{					// is reached				printf("%c",Message[i]);				i++;						}			printf("\r\n");			get_cmd_init();			// Re-init command input			UserState = start;		// and go back to initial state		break;					case EncodeDecode:			// Run Encoder/Decoder System			printf("\r\n--Encoding/Decoding of Message: ");			System();				// Run the system	  		get_cmd_init();	  		UserState = help;  		// Display Help Menu before		break;					// going back to initial state					case adderror:		// Error Module Toggle			if (Add_Error)	// If it's on, turn it off			{				 Add_Error=0;				 printf("--Noise Module is OFF\r\n");				 get_cmd_init();				 UserState = start;			}						if (cmd_ready == 1)	// Otherwise, turn it on and grab			{				// the user-inputted seed				seed = cmd_str[0]-48;				Add_Error = 1;				printf("--Noise Module is ON: Seed %d\r\n", seed);				get_cmd_init(); 								UserState = start;			}		break;					// Note that display toggles are used, since so much is displayed		// to HyperTerm, that the speed of encoding/decoding is comprimised		// and it is difficult to interpret the whole message		case DisplayToggle:		// Main Display toggle			display_toggle ^= 1;	// Switch it on and off with XOR			if (display_toggle)				printf("--Display is ON\r\n");			else				printf("--Display is OFF\r\n");			get_cmd_init(); 							UserState = start;		break;					case DetailToggle:		// Detailed Display Toggle			if (display_toggle)	// Can only be activated if			{				// Main Display is ON				detail_toggle ^= 1;	// Switch it On/Off				if (detail_toggle)					printf("--Detailed Display is ON\r\n");				else					printf("--Detailed Display is OFF\r\n");			}			else				printf("--Display is NOT on\r\n");			get_cmd_init(); 							UserState = start;		break;					case help:	// Simply displays the help menu		    HelpMenu();		    get_cmd_init();   		    UserState = start;		break;  	}}//**Initialize**//Sets up vars, timers, and Mega32 registersvoid Initialize(){	//Initialize the USART registers	UCSRB = 0x18; // enable RX/TX interrupts	UBRRL = 103;  // baud rate = 9600	//Initialize the state variables	UserState = start;	n=31; k=16; t=3;	// Initialize BCH Code parameters to (31,16)	EncodedMessage=0;	GeneratorPoly = 36783; // Init the Generator polynomial		// Initialize the toggles and the random seed to No Errors	display_toggle=0;	detail_toggle=0;	Add_Error=0;	seed=0;	// Initialize the Error Counters for BER	trans_error_count=0;	rec_error_count=0;			enc_message_bits=0;		// The # of bits in the Full encoded msg		get_cmd_init(); //start the RXC interrupt for keypad input.	HelpMenu(); // Run the help menu for User cmds		// Fire up the ISR's	#asm		sei	#endasm}//**Encode/Decode System**// High level system for the encoding and decoding operations for// the entire message to be transmittedvoid System(){ 		unsigned char out[2], a, b;	unsigned int CurrIndex = 0;	// Keeps track of where we are in the Message	unsigned long decoded_bits;	// Final decoded message of 2 chars	a = Message[CurrIndex];	// Initialize the first 2 chars to be encoded	b = Message[CurrIndex+1];	while ((a != '\r') && (b != '\r'))	// Loop throught the message until terminator chars are reached	{		if (display_toggle)	// In general, only disply if display toggles are ON		{			printf("\r\n========================================================================");			printf("\r\nOriginal Message: %c %c\r\n", a, b);		}		EncoderBCH(a,b);	// Run the encoder on the first 2 chars of Message		DecoderBCH();	// and Decoded the resulting encoded message		decoded_bits = Bytes2Bits(EncMsgArray);		deConcate(decoded_bits, out);	// Parse out the 2 chars		if (display_toggle)		{			printf("\nCorrected Message Array:\r\n");			PrintArray(EncMsgArray);			printf("\r\nMessage: %c %c\r\n\n", out[0], out[1]);		}		else			printf("%c %c ", out[0], out[1]);	// if no display toggle, just print decoded									// message	 	CurrIndex += 2;		// Increment to grab the next 2 chars to be Encoded/Decoded		a = Message[CurrIndex];		b = Message[CurrIndex+1];		enc_message_bits += 31;		// Every iteration, 31 bits are encoded	}	printf("\r\n\nBER of Transmitted Message: %f", (float)trans_error_count/enc_message_bits);	printf("\r\nBER of Recieved Message: %f\r\n", (float)rec_error_count/enc_message_bits);}//**16 bit Message Encoder**// Grabs a 16 bit message, and encodes it according to the BCH algorithm// with a specified generator polynomialvoid EncoderBCH(unsigned char a, unsigned char b){	char numerrors;	// Random number of errors to introduce into the message				// from 0 - user selected seed	// Calculates the number of errors	numerrors = (char)(rand() * ((float)(seed+1)) / (RAND_MAX + 1.0));	trans_error_count += numerrors;	// Internal counter to keep track of errors	if (numerrors > 3)			// Errors in decoded message only for 4 or more		rec_error_count += numerrors;	// Systematic encoding as follows:	// (m(x) * x^(n-k)) mod g(x) + (m(x) * x^(n-k))		// Shift by x^(n-k) = x*15	EncodedMessage = Concate(a, b);	// Concatenates the two chars to a 16bit message	EncodedMessage = EncodedMessage << (n-k);	// Multiply by x^(n-k)		EncodedMessage = GF2Add(GF2Mod(EncodedMessage, GeneratorPoly), EncodedMessage);//	EncodedMessage ^= 0x20010008;	// Errors can be manually added to message for debugging		GF32Init(EncMsgArray); // Initialize to ZERO's	Bits2Bytes(EncodedMessage, EncMsgArray);	// Convert to a GF32 polynomial	if (display_toggle)	{		printf("\nEncoded Message Array:\r\n");		PrintArray(EncMsgArray);	}	//	printf(" NumErrors: %d\r\n",numerrors);	// Execute the Error Module only if it is activated		if (Add_Error)	{		if (display_toggle)			printf("\nRandom Index Errors:  ");		ErrorModule(EncMsgArray, numerrors);	// Execute it		if (display_toggle)		{			printf("\r\n\nEncoded Message Array with %d Errors:\r\n", numerrors);			PrintArray(EncMsgArray);		}	}}//** 32 bit BerleKamp Decoder for BCH Codes **// Decodes an encoded 32 bit message, and corrects for any detected errors// according to the Berlekamp algorithm. See the writeup for details.

⌨️ 快捷键说明

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