| PicManía by RedRaven |
Búsqueda personalizada
|
|
PROYECTOS : TRADUCTOR MORSE |
|
|
|
Traductor de ASCII a Código MORSE |
| Introducción: |
|
|
|
| Descripción: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| // Traductor Morse
RS232 -> Lights & Sound #include <18f4550.h> #fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN // Fuses #use delay(clock=20000000) // Clock a 20 Mhz #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Canal serie con el PC const int maxlendefinition=12; // Maxima longitud de la definicion Morse en las tablas const long lapsus=1000; // Tiempo en milisegundos para Leds al reset const long periodo=75; // Tiempo en milisegundos para unidad Morse = . (un punto) const int lenrecbuffer=64; // Tamaño en bytes del buffer de recepcion const int COMMAND_NULL=0; // COMANDO NULO -> No hay comando const int COMMAND_PROCESS=1; // COMANDO PROCESA TEXTO -> Convertir buffer a Morse char Version[]="1.5.0\0"; // Version del programa char CharRcv=0; // Caracter recibido por la USART char Command=0; // Caractar a enviar al main para su procesado char recbuffer[lenrecbuffer]; // Buffer de recepción int nextc=0; // Indice de siguiente caracter en recbuffer char Numeros[10][maxlendefinition]={ // Tabla de definicion de los Numeros "\x010\x02-----\0 ", "\x011\x02.----\0 ", "\x012\x02..---\0 ", "\x013\x02...--\0 ", "\x014\x02....-\0 ", "\x015\x02.....\0 ", "\x016\x02-....\0 ", "\x017\x02--...\0 ", "\x018\x02---..\0 ", "\x019\x02----.\0 "}; char Letras[27][maxlendefinition]={ // Tabla de definicion de las Letras "\x01A\x02.-\0 ", "\x01B\x02-...\0 ", "\x01C\x02-.-.\0 ", "\x01D\x02-..\0 ", "\x01E\x02.\0 ", "\x01F\x02..-.\0 ", "\x01G\x02--.\0 ", "\x01H\x02....\0 ", "\x01I\x02..\0 ", "\x01J\x02.---\0 ", "\x01K\x02-.-\0 ", "\x01L\x02.-..\0 ", "\x01M\x02--\0 ", "\x01N\x02-.\0 ", "\x01O\x02---\0 ", "\x01P\x02-..-\0 ", "\x01Q\x02--.-\0 ", "\x01R\x02-.-\0 ", "\x01S\x02...\0 ", "\x01T\x02-\0 ", "\x01U\x02..-\0 ", "\x01V\x02...-\0 ", "\x01W\x02.--\0 ", "\x01X\x02-..-\0 ", "\x01Y\x02-.--\0 ", "\x01Z\x02--..\0 ", "\x01Ñ\x02--.--\0 "}; char Signos[7][maxlendefinition]={ // Tabla de definicion de las Letras "\x01 \x02 \0 ", // Espacio "\x01,\x02.-.-.-\0 ", // Coma "\x01?\x02--..--\0 ", // Interrogación "\x01=\x02-...-\0 ", // Igual "\x01-\x02-....-\0 ", // Guión "\x01/\x02-..-.\0 ", // Barra "\x01@\x02.--.-.\0 "}; // Arroba #int_rda // Declaración de Interrupción ... void rda_handler() { // Manejador de la interrupción recepcion USART CharRcv=0; // Inicializo caracter a recibir Command=COMMAND_NULL; // Inicializo comando para main if(kbhit()){ // Si hay algo pendiente de recibir ... CharRcv=getc(); // lo recibo sobre RecRcv. if(CharRcv!=0){ // Si no es un \0 ... recbuffer[nextc]=CharRcv; // lo copio en el buffer, ... if(CharRcv==0x0D){ // Si he recibido un [Intro] 0x0D 13 ... recbuffer[nextc]='\0'; // Sustituyo el 0x0D en recbuffer por el terminador \0 Command=COMMAND_PROCESS; // lo copio sobre command para procesarlo en main } else { putc(CharRcv); // lo envío de vuelta como eco y continuo ... } if(++nextc==lenrecbuffer){ // Y si despues de incrementar nextc es igual a lenrecbuffer ... nextc=0; // lo vuelvo a poner a cero } } } } void limpia_recbuffer(void){ int i; // Declaro variable de índice for(i=0;i!=lenrecbuffer;i++){ // Bucle de 0 a lenrecbuffer recbuffer[i]='\0'; // Pongo a \0 } nextc=0; } void wait_nperiodos(int n){ // Rutina que espera n peridos int x; // Declaro variable de índice for(x=0;x<n;++x){ // Bucle de n periodos delay_ms(periodo); // Espero un periodo en milisegundos } } char morse_parse_char(char* mistring){ // Rutina que extrae el Caracter de la tabla de definiciones // Entrada : Puntero a la definicion Devuelve: Caracter pulsado return mistring[1]; // Devuelvo el segundo caracter de la tabla } char* morse_parse_code(char* mistring){ // Rutina que extrae el código Morse de la tabla // Entrada: Puntero a la definicion, Devuelte: Puntero al codigo int i,j=0; // Declaro variables de indices para copiar ... char c=' '; // Caracter a procesar uno a uno char result[maxlendefinition]; // Buffer para el resultado for(i=3;i<maxlendefinition,c!='\0';i++,j++){ // Bucle que comienza en el caracter 3º y termina al \0 ó en Mñáxima longitud c=mistring[i]; // Tomo los caracteres uno a uno ... result[j]=c; // y lo copio en el resultado } result[j]='\0'; // Finalizo el string del resultado con el estandar \0 return result; // Devuelvo el resultado } void morse_rs232(char* mistring){ // Rutina que monitoriza el código Morse extraído // Entrada : Puntero a la definicion char crtr; // Variable para el Carácter pulsado char* code; // Puntero a la Variable con el Código correspondiente crtr = morse_parse_char(mistring); // Extraigo el caracter pulsado de la definicion code = morse_parse_code(mistring); // Extraigo el codigo morse correspondiente a ese caracter printf("%c -> %s\r\n",crtr,code); // Lo envio a la RS232 } void morse_light_punto(void){ output_High(PIN_E1); // Enciendo Led1 -> Puntos y Led0 -> Completo output_High(PIN_E0); wait_nperiodos(1); // Espero 1 x "periodo" de puntos output_Low(PIN_E1); output_Low(PIN_E0); // Apago Led1 -> Puntos y Led0 -> Completo wait_nperiodos(1); // Espero 1 "periodo" de separacion entre puntos y rayas } void morse_light_raya(void){ output_High(PIN_E2); // Enciendo Led2 -> Rayas y Led0 -> Completo output_High(PIN_E0); wait_nperiodos(3); // Espero 3 x "periodo" de rayas output_Low(PIN_E2); output_Low(PIN_E0); // Apago Led2 -> Rayas y Led0 -> Completo wait_nperiodos(1); // Espero 1 "periodo" de separacion entre puntos y rayas } void morse_lights(char* mistring){ // Rutina que enciende los Led's de la RRBOARD2 char* code; // Puntero a la Variable con el Código correspondiente int i; // Declaro variable de indice para procesar ... char c=' '; // Caracter a procesar uno a uno e inicializo en blanco code = morse_parse_code(mistring); // Extraigo el codigo morse correspondiente a ese caracter for(i=0;i<maxlendefinition-3,c!='\0';i++){ // Bucle que recorre el contenido de code hasta \0 c=code[i]; // Tomo los caracteres a representar uno a uno ... switch(c){ case ' ': wait_nperiodos(5); // Espero 5 x "periodo" ( espacio entre palabras) break; case '.': morse_light_punto(); break; case '-': morse_light_raya(); break; } } } void morse_process(char* mitext){ int i,x,y,z; // Variables indice de ratreo de mitext, índice relativas // a las tablas y al caracter recibido char xdefinition[maxlendefinition]; // Buffer para seleccionar la definicion correspondiente char c=' '; // Caracter a procesar uno a uno e inicializo en blanco for(i=0;i<lenrecbuffer,c!='\0';i++){ // Cargo siguiente caracter a procesar c=mitext[i]; if(c!='\0'){ // Inicializo índices de tablas a un valor imposible x=0xff; y=0xff; z=0xff; // Letras Minúsculas, las convierto a mayúsculas if( (c>'a'- 1) && (c<'z'+ 1)){ c = c - 'a' + 'A'; } // Letras Mayúsculas, calculo el índice en la tabla según su código ASCII if( (c>'A'- 1) && (c<'Z'+ 1)){ x = c-'A'; } // Letras Especiales, puestas a güebo if( (c=='Ñ') || (c=='ñ')){ // Ñ x =26; } // Números, calculo el índice en la tabla según su código ASCII if( (c>'0'- 1) && (c<'9'+ 1)){ y = c-'0'; } //Signos y puntuación, puestos a güebo if(c==' ') z = 0; // Espacio if(c==',') z = 1; // Coma if(c=='?') z = 2; // Interrogación if(c=='=') z = 3; // Igual if(c=='-') z = 4; // Guión if(c=='/') z = 5; // Barra if(c=='@') z = 6; // Arroba // Guardo en el buffer de main la definicion correspondiente a lo pulsado if(x < 255){sprintf(xdefinition,"%s",Letras[x]);} if(y < 255){sprintf(xdefinition,"%s",Numeros[y]);} if(z < 255){sprintf(xdefinition,"%s",Signos[z]);} // Presenta y/o suena (Ahora solo presenta) morse_rs232(xdefinition); morse_lights(xdefinition); } } } void on_reset(){ disable_interrupts(global); // Deshabilito todas las interrupciones disable_interrupts(int_timer1); // Deshabilito ... disable_interrupts(int_rda); disable_interrupts(int_ext); disable_interrupts(int_ext1); disable_interrupts(int_ext2); setup_adc_ports(NO_ANALOGS); // Configuro todo lo que voy setup_adc(ADC_OFF); // a usar y lo que no ... setup_spi(FALSE); setup_psp(PSP_DISABLED); setup_counters(RTCC_INTERNAL,RTCC_DIV_2); setup_timer_0(RTCC_OFF); setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); setup_timer_2(T2_DISABLED,0,1); setup_timer_3(T3_DISABLED); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); port_b_pullups(FALSE); set_tris_e(0b00010000); set_tris_c(0b10000000); enable_interrupts(global); // Habilito todas las interrupciones (que esten habilitadas) enable_interrupts(int_rda); // Habilito la interrupcion por recepcion USART delay_ms(333); // Espero 333 milisegundos a que todo se estabilice printf("\r\n"); // Me presento como deben hacer todos los PIC's de printf("Morse with 18F4550 in RRBOARAD2"); // buena familia printf("\r\n"); printf(" v.%s by Redpic\r\n\n\n",Version); output_High(PIN_E0); // Enciendo los tres Led's de la RRBOARD2 output_High(PIN_E1); output_High(PIN_E2); wait_nperiodos(lapsus/periodo); // Espero lo que indica "lapsus" expresado en unidades de "periodo" output_Low(PIN_E0); output_Low(PIN_E1); output_Low(PIN_E2); // Apago los tres Led's de la RRBOARD2 wait_nperiodos(lapsus/periodo); limpia_recbuffer(); // Limpio el buffer de recepción } void main(){ On_reset(); do{ // Bucle Infinito if(Command!=COMMAND_NULL){ if(Command==COMMAND_PROCESS){ // COMMAND_PROCESS : Convierte a Morse el contenido de recbuffer printf("\r\n\n"); // Paso una linea en el monitor rs232 morse_process(recbuffer); // Mando procesar el contenido de recbuffer printf("\r\n"); // Paso otra linea en el monitor rs232 limpia_recbuffer(); // Limpio el buffer de recepción Command=COMMAND_NULL; // Limpio el ultimo comando procesado } } }while(TRUE); } |
||
Esta página se modificó el 27/12/2008
|