幾年前,我寫了一個摩爾斯電碼發生器,用於一個朋友進入地理尋寶。這段代碼控制着一臺變送器雖然它在C中,但它可能會讓你對如何做到這一點有所瞭解。你真的只需要三個例程,一個用於'dit','dah'和'空間'。
play_space
真的只是關閉聲音和短暫的延遲。
play_mark
真的不過是打開持續時間的聲音,並且可以在Arduino中編碼爲tone(pin, frequency, duration_milliseconds)
。
init
中的所有東西只是設置控制器以設定的頻率播放音調。再一次,更容易與Arduino tone()
。主要是在MCode
結構和它們的數組中表示每個字符和數字。然後,對於要發送的字符串中的每個字符,只需搜索數組,直到找到匹配的字符,然後使用xmit_symbol()
從結構中播放code
。
#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>
// transmission lengths, in milliseconds
#define DIT_MS 60 // dit length of 120 should yield ~10 words per minute
#define DAH_MS (DIT_MS * 3) // dah length
#define AL_SPACE (DIT_MS * 3) // after-letter space
#define AW_SPACE (DIT_MS * 6) // after-word space = 6 + after-letter space = 7
// simple diagnostic LED
#define LED_1 PA0
// hardcoded callsign
const char* CALLSIGN = "HELLO WORLD";
static const struct
{
const char symbol;
const uint8_t length;
const uint8_t code;
} MCode[] =
{
{'A', 2, 0b01000000},
{'B', 4, 0b10010000},
{'C', 4, 0b10100000},
{'D', 3, 0b10000000},
{'E', 1, 0b00000000},
{'F', 4, 0b00100000},
{'G', 3, 0b11000000},
{'H', 4, 0b00000000},
{'I', 2, 0b00000000},
{'J', 4, 0b01110000},
{'K', 3, 0b10100000},
{'L', 4, 0b01000000},
{'M', 2, 0b11000000},
{'N', 2, 0b10000000},
{'O', 3, 0b11100000},
{'P', 4, 0b01100000},
{'Q', 4, 0b11010000},
{'R', 3, 0b01000000},
{'S', 3, 0b00000000},
{'T', 1, 0b10000000},
{'U', 3, 0b00100000},
{'V', 4, 0b00010000},
{'W', 3, 0b01100000},
{'X', 4, 0b10010000},
{'Y', 4, 0b10110000},
{'Z', 4, 0b11000000},
{'1', 5, 0b01111000},
{'2', 5, 0b00111000},
{'3', 5, 0b00011000},
{'4', 5, 0b00001000},
{'5', 5, 0b00000000},
{'6', 5, 0b10000000},
{'7', 5, 0b11000000},
{'8', 5, 0b11100000},
{'9', 5, 0b11110000},
{'0', 5, 0b11111000},
{'-', 6, 0b10000100}
};
void init(void)
{
// set up diagnostic led
DDRA |= (1<<LED_1);
// set up OC1A pin as output for PWM signal
DDRB |= (1<<PB1);
// set up fast PWM mode
TCCR1A |= (1<<PWM1A);
// timer1 prescaler
TCCR1B |= (1<<CS12); // 1/8 (yields ~490Hz at 1MHz FCPU) (p.117)
// set OCR value to achieve close enough to square wave
OCR1A = 128;
}
/////////////////////////////////////////////////////////////////////////////////
//// ROUTINES TO CREATE MARKS AND SPACES
/////////////////////////////////////////////////////////////////////////////////
void play_space(uint16_t length)
{
// play a space of the specified length
PORTA &= ~(1<<LED_1);
TCCR1A &= ~(1<<COM1A1);
_delay_ms(length);
}
void play_mark(uint16_t length)
{
// play a mark for specified length
PORTA |= (1<<LED_1);
TCCR1A |= (1<<COM1A1);
_delay_ms(length);
// always play a dit-length space afterwards
PORTA &= ~(1<<LED_1);
TCCR1A &= ~(1<<COM1A1);
_delay_ms(DIT_MS);
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//// TRANSMIT A CHARACTER AND INTER-CHARACTER SPACE
/////////////////////////////////////////////////////////////////////////////////
void xmit_symbol(uint8_t length, uint8_t code)
{
for (uint8_t p = 0; p < length; p++)
{
uint8_t shift = 7 - p;
uint8_t mask = 1<<shift;
uint8_t result = code & mask;
if (result == mask)
play_mark(DAH_MS);
else
play_mark(DIT_MS);
}
play_space(AL_SPACE);
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//// TRANSMIT A NULL-TERMINATED STRING
/////////////////////////////////////////////////////////////////////////////////
void xmit_callsign()
{
uint8_t iStringPos;
uint8_t iSearchPos;
// Process each character of the callsign string.
// NOTE: Trick here uses null terminator on string to make comparison false.
for (iStringPos = 0; CALLSIGN[iStringPos]; iStringPos++)
{
// Linear search through array of structs seeking matching symbol.
for (iSearchPos = 0; iSearchPos < (sizeof MCode/sizeof *MCode); iSearchPos++)
{
if (CALLSIGN[iStringPos] == MCode[iSearchPos].symbol)
{
// We found a match, so transmit this character/symbol.
xmit_symbol(MCode[iSearchPos].length, MCode[iSearchPos].code);
// Bail out and move on down the string until done...
break;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//// MAIN LOOP
/////////////////////////////////////////////////////////////////////////////////
int main(void)
{
// Initialize the controller.
init();
// Endless main loop.
while(1)
{
// 3-second delay in before starting, for ease in copying...
for (int n = 0; n < 3; n++) _delay_ms(1000);
// call central transmit routine
xmit_callsign();
// insert a hard delay in between transmissions, for now
for (int n = 0; n < 3; n++) _delay_ms(1000);
}
// required but unreachable
return 0;
}
你應該問[這裏](https://codereview.stackexchange.com/questions) –
請你只是谷歌 「的Arduino莫爾斯」 ......它不是那麼困難的https://gist.github .com/madc/4474559和其他命中將給予足夠的靈感 – Piglet
我投票結束這個問題作爲題外話,因爲要求改進工作代碼的問題屬於代碼審查,而不是Stack Overflow。 – TylerH