📄 main.c
字号:
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 + -