morse.c

来自「国外网站上的一些精典的C程序」· C语言 代码 · 共 240 行

C
240
字号
/***   <<< Morse Code Functions >>>** ** Written by Michael M. Dodd, N4CF, and placed in the public domain.** ** The morse() function transmits a string in Morse code on the IBM PC's** speaker.  The speed is set by a program constant (UNIT_TIME).** ** There are several other functions in this file, all used by morse(),** and defined ahead of morse() for convenience.** ** The main() function at the end of the file is a test program to send** the command-line argument string in morse code.  Enclose multiple** words in quotes.  Example:  morse "hello, world"** ** These functions have been compiled and tested in the Small and Large** memory models using Microsoft C 6.00a.**** Modified for ZTC++, TC++, & BC++ by Bob Stout*/#include <stdio.h>#include <dos.h>#include <conio.h>#include <ctype.h>/*** These functions turn on and off the CW tone on the PC's speaker.  The** frequency is specified by the freq argument.** IMPORTANT!  These functions are highly IBM PC-specific!*/#define CLK_FREQ (1193180L)#define PIO (0x61)#define CTC_CMD (0x43)#define CTC_DATA (0x42)#define SETUP (0xB6)#define TONE_ON (0x03)#define TONE_OFF (0xFC)void note_on (int freq)        /* Turn on the tone.  */{      int divisor ;      int pio_word ;      divisor = (int)(CLK_FREQ / (long)(freq)) ;      outp (CTC_CMD, SETUP) ;      outp (CTC_DATA, divisor & 0xFF) ;      outp (CTC_DATA, divisor >> 8) ;      pio_word = inp (PIO) ;      outp (PIO, pio_word | TONE_ON) ;}void note_off (void)           /* Turn off the tone.  */{      int pio_word ;      pio_word = inp (PIO) ;      outp (PIO, pio_word & TONE_OFF) ;}/*** These functions implement a timing-loop delay.  Because the PC's** internal clock is too coarse for accurate CW timing, the pause()** function uses a simple software loop to produce a delay.** ** To minimize the effects of CPU clock speed, the calib() function** returns a number which represents a rough index of the clock speed** with relation to the standard IBM PC (this is very approximate).** ** Calibration is performed only once, when the static fudge_factor is** zero.  Thereafter, the contents of fudge_factor are used to form a** delay value.** ** IMPORTANT!  These functions are highly IBM PC-specific!*/unsigned int calib (void){      unsigned int far *timerLow = (unsigned int far *)(0x046c) ;      unsigned int lastTime ;      unsigned int iter ;      for (lastTime = *timerLow; lastTime == *timerLow;)            ;      for (iter = 0, lastTime = *timerLow; lastTime == *timerLow; iter++)            ;#if   defined(__ZTC__)      return ((unsigned int)((125L * ((long)(iter)) + 50L) / 2300L)) ;#elif defined(__TURBOC__)      return ((unsigned int)((77L * ((long)(iter)) + 50L) / 2300L)) ;#else /* assume MSC */      return ((unsigned int)((100L * ((long)(iter)) + 50L) / 2300L)) ;#endif}void pause (unsigned int amount){      static unsigned int fudge_factor = 0 ;      unsigned long ul ;      if (fudge_factor == 0)       /* Calibrate the speed.  */            fudge_factor = calib () ;      ul = (unsigned long)(amount) * (long)(fudge_factor) ;      while (ul--)                 /* Delay.  */            ;}/*** These functions transmit a dot, a dash, a letter space, and a** word space.** ** Note that a single unit space is automatically transmitted after** each dot or dash, so the ltr_space() function produces only a** two-unit pause.** ** Also, the word_space() function produces only a four-unit pause** because the three-unit letter space has already occurred following** the previous letter.*/#define SPACE_MASK (1 << 15)#define BIT_MASK (0xfe)#define UNIT_TIME (18)#define FREQUENCY (1500)void send_dot (void)           /* Send a dot and a space.  */{      note_on (FREQUENCY) ;      pause (UNIT_TIME) ;      note_off () ;      pause (UNIT_TIME) ;}void send_dash (void)          /* Send a dash and a space.  */{      note_on (FREQUENCY) ;      pause (UNIT_TIME * 3) ;      note_off () ;      pause (UNIT_TIME) ;}void ltr_space (void)          /* Produce a letter space.  */{      pause (UNIT_TIME * 2) ;}void word_space (void)         /* Produce a word space.  */{      pause (UNIT_TIME * 4) ;}/*** MORSE () - Transmit a string in Morse code** ** This function transmits the string pointed to by the cp argument in** Morse code on the PC's speaker.  The speed is set by the UNIT_TIME** constant.** ** A static table translates from ASCII to Morse code.  Each entry is** an unsigned integer, where a zero represents a dot and a one** represents a dash.  No more than 14 bits may be used.  Setting bit** 15 produces a word space, regardless of any other pattern.** ** The Morse code pattern is taken from bit 0, and is shifted right** each time an element is sent.  A special "marker bit" follows the** complete Morse pattern.  This marker bit is tested before** transmitting each bit; if there are no 1's in bits 1..15, the** complete character has been sent.** ** For example, an "L" would be 0000000000010010, with bit zero** containing the first dot, bit one the dash, etc.  The marker** bit is in bit 4.*/void morse (char *cp){  /*--- MORSE CODE FUNCTION ---*/      unsigned int c ;      static unsigned int codes [64] = {            SPACE_MASK,                      /* Entry 0 = space (0x20)  */            0, 0, 0, 0, 0, 0, 0, 0,          /* ! " # $  % & " (  */            0, 0, 0, 115, 49, 106, 41,       /* ) * + , - . /     */            63, 62, 60, 56, 48, 32, 33, 35,  /* 0 1 2 3 4 5 6 7   */            39, 47, 0, 0, 0, 0, 0, 76,       /* 8 9 : ; < = > ?   */            0, 6, 17, 21, 9, 2, 20, 11,      /* @ A B C D E F G   */            16, 4, 30, 13, 18, 7, 5, 15,     /* H I J K L M N O   */            22, 27, 10, 8, 3, 12, 24, 14,    /* P Q R S T U V W   */            25, 29, 19                       /* X Y Z  */            } ;      pause (0) ;                  /* Calibrate pause() function.  */      while ((c = *cp++) != '\0')      {  /*--- TRANSMIT COMPLETE STRING ---*/            c = toupper (c) ;          /* No lower-case Morse characters.  */            c -= ' ' ;                 /* Adjust for zero-based table.  */            if (c > 58)                /* If out of range, ignore it.  */                  continue ;            c = codes[c] ;             /* Look up Morse pattern from table. */            if (c & SPACE_MASK)        /* If the space bit is set..  */            {                          /* ..send a word space and go on.  */                  word_space () ;                  continue ;            }            while (c & BIT_MASK)       /* Transmit one character.  */            {  /*--- TRANSMIT EACH BIT ---*/                  if (c & 1)                        send_dash () ;                  else  send_dot () ;                  c >>= 1 ;            }  /*--- TRANSMIT EACH BIT ---*/            ltr_space () ;             /* Send a space following character. */      }  /*--- TRANSMIT COMPLETE STRING ---*/}  /*--- MORSE CODE FUNCTION ---*//*** This is the test program, which transmits argv[1] in Morse code.*/main (int argc, char *argv[]){      while (--argc)            morse (*++argv) ;      return 0;}

⌨️ 快捷键说明

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