PicManía by RedRaven
 

Búsqueda personalizada

 

PROYECTOS : RROS v 2.0

 

 

Continuando en mi línea de manejar el PIC desde el PC, vía RS232, he desarrollado todo un sistema monitor, al estilo del anterior RROS v 1.0 y utilizando lo estudiado en Strings Demo o como se pueden manejar las cadenas en nuestro PIC

Igual que en los citados ejemplos anteriores hago uso del receptor RS232 sobre un buffer y su tratamiento posterior pero en este caso vamos a implementar los comandos:

eedump, eeread, eewrite y eefill

que nos van a permitir volcar todo el contenido de la EEPROM en el hiperterminal, leer una posición determinada, escribir sobre ella o rellenar con un valor dado toda la EEPROM disponible.

En el fondo, con respecto a la EEPROM, solo vamos a utilizar realmente dos funciones CCS específicas: read_eeprom(dir) y write_eeprom(dir, byte). Todo lo demás lo compone nuestro programa receptor de comandos y ejecutor de los mismos.

El programa entonces habla con nosotros así:
 

 

  RROS v2.0  
  /////////////////////////////////////////////////////////////////////////////////////////
//
// RROS para RRBOARD1 v.2.0
//
// © 26.02.2006 By RedRaven
//
// Hardware: PIC16F628
//
// RA0..RA3 Leds
// RB1 USART RX
// RB2 USART TX
// RB5 Buzzer Driver
// RB6,RB7 ICSP
//
// Xtal Ext. 4.00 Mhz
//
// Idioma: CCS PICC v.3.242
//
//
/////////////////////////////////////////////////////////////////////////////////////////

#include <16f628.h>
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=19200, xmit=PIN_B2, rcv=PIN_B1)

#include <stdlib.h>

// Constantes y definiciones ////////////////////////////////////////////////////////////

int const MAXLENBUFF=24; // Maxima longitud de los bufferes
int const MAXLENCOMMAND=12; // Maxima longitud de un comando (sin argumentos)
int const NUMPAGSEEPROM=7; // Numero de paginas (de 16 bytes) de la EEPROM interna

// Variables Globales ///////////////////////////////////////////////////////////////////

char buffrec[MAXLENBUFF]; // Buffer de Recepcion
int xbuffrec=0x00; // índice del Buffer de Recepcion
int1 new_command=0; // Flag para indicar comando disponible
int1 pdte_send_prompt=0; // Flags para enviar echo fuera de la int_rda
int1 pdte_send_tmp_prompt=0;
char xcommand[MAXLENCOMMAND]; // Comprobador de comando recibido

// Declaracion de Funciones /////////////////////////////////////////////////////////////

void On_reset(void); // Tras RESET del Micro
void Send_listen(void); // Monitoriza RS232 : Comienzo
void Send_opts(void); // Monitoriza RS232 : Presenta opciones
void Send_prompt(void); // Monitoriza RS232 : Presenta el Cursor
void Send_tmp_prompt(void); // Monitoriza RS232 : Presenta el Cursor y el comando actual
void Ini_buffrec(void); // Borra el buffer de recepción
void Add_buffrec(char c); // Añade un caracter al buffer de recepción
int Extrae_arg_hex(char tipo, int lenarg); // Extrae del comando el valor hex tras -tipo
int aschex2int(char d); // Convierte un caracter ascii a hex
void Procesa_comando(void); // Procesado de comandos
void Vuelca_EEPROM(void); // Vuelca el contenido de la EEPROM
void Rellena_EEPROM(int x); // Rellena toda la EEPROM con x
void Write_port(int port, int valor); // Pone a valor el estado del puerto port


// INTERRUPCIONES ///////////////////////////////////////////////////////////////////////

// INTERRUPCION RDA - Recepción USART -

#int_rda
void serial_isr() {
  if(kbhit()){ // Si hay algo pendiente de recibir ...
    Add_buffrec(getc()); // lo recibo y lo añado al Buffer de Recepcion
  }
}

// Control del Buffer de recepcion ---------------------------------------

void Ini_buff_rec(void){ // Inicia a "\0" el Buffer de Recepcion

  int i;
  for(i=0;i<MAXLENBUFF;i++){ // Bucle que pone a 0 todos los
    buffrec[i]=0x00; // caracteres en el Buffer de Recepcion
  }
  xbuffrec=0x00; // Inicializo el indice de siguiente caracter recibido
}

void Add_buffrec(char c){ // Añade caracter al Buffer de Recepcion

  switch(c){
    case 0x0D: // [Enter] -> Habilita Flag para procesar comando en Main
      new_command=1;
      break;
    case 0x08: // [Del] -> Borra último caracter del Buffer
      if(xbuffrec>0){ // Si hay algo en el buffer
        buffrec[--xbuffrec]=0x00; // decremento el índice, escribo un cero y ...
        pdte_send_tmp_prompt=1; // habilito flag para refrescar el prompt
      }
      break;
    case 0x01B: // [Esc] -> Borra el Buffer completamente y ...
      Ini_buff_rec(); // habilito flag para refrescar el prompt
      pdte_send_prompt=1;
      break;
    case 0x009: // [Tab] -> Refresca el prompt y el comando tal como esté
      pdte_send_tmp_prompt=1;
      break;
    default:
      buffrec[xbuffrec++]=c; // Añade caracter recibido al Buffer
      putc(c); // y lo monitorizo
    }
}

// Rutinas y Funciones de RROS ///////////////////////////////////////////

void On_reset(void){ // Inicializacion del Micro tras RESET

  disable_interrupts(GLOBAL); // todas las interrupciones desactivadas

  delay_ms(100);

  // Hardware específico /////////////////////////
  output_low(PIN_A0); // RA0..RB3 a 0
  output_low(PIN_A1);
  output_low(PIN_A2);
  output_low(PIN_A3);
  output_low(PIN_B5); // RB5 a 0
  ////////////////////////////////////////////////

  Ini_buff_rec(); // Inicializo Buffer de recepcion
  new_command=0; // Desactivo flag de comando pendiente.
  pdte_send_prompt=0; // Desactivo Flags para enviar echo fuera de la int_rda
  pdte_send_tmp_prompt=0;

  enable_interrupts(int_rda); // interrupcion RDA habilitada
  enable_interrupts(global); // todas las interrupciones activadas

  Send_listen(); // Presenta Comienzo
  Send_prompt(); // Presenta el Cursor

}

void Send_listen(void){ // Presenta Comienzo

  printf("RR.PIC.OS v2.0\r\n\n");
  printf("? for valid commands\r\n");
}

void Send_opts(void){ // Relación de comandos válidos

  printf("\r\n\n");
  Send_listen();
  printf("\n");
  printf("[?] comandos válidos\r\n");
  printf("[eedump] contenido de eeprom\r\n");
  printf("[eeread -dDD] lee byte en dir DDh\r\n");
  printf("[eewrite -dDD -bBB] escribe byte BBh en dir DDh\r\n");
  printf("[eefill -bBB] eeprom a BBh\r\n");
  printf("[setport -pX -bBB] escribe byte BBh en puerto X\r\n");
}

void Send_prompt(void){ // Presenta el cursor

  printf("\r\n>");
}

void Send_tmp_prompt(void){ // Presenta el cursor con el comando actual

  printf("\r>%s",buffrec);
}

int Extrae_arg_hex(char tipo, int lenarg){ // Extrae del comando el valor hex tras -tipo

  char cc[3], *ptr, Hex[3]="\0"; // Variables necesarias para extraer direccion de buffrec
  int r=0;


  strcpy(cc,"-X"); // Compongo identificador de argumento para extraerlo
  cc[1]=tipo;

  ptr=strstr(buffrec,cc); // Obtengo puntero de donde comienza "-X" dentro de buffrec
  if(!ptr==0){ // Si realmente existe "-X" dentro de buffrec ...
    ptr+=2; // avanzo el puntero 2 posiciones para saltarme "-X" y ...
    strncpy(Hex,ptr,lenarg); // copio el trozo siguiente a Hex ...
    Hex[lenarg]='\0'; // y lo finalizo con '\0' para obterner Hex="DD\0".
    if(lenarg>1){
      r =(16*aschex2int(Hex[0])); // Convierto de Hex Ascii 1 ó 2 digitos
      r+=(aschex2int(Hex[1]));
    }
    else{
      r=(aschex2int(Hex[0]));
    }
  }
  return(r);
}

int aschex2int(char d){ // Convierte un caracter ascii a hex

  int r=0;

  if(isxdigit(d)){ // Si es un digito hexadecimal ...
    if(isdigit(d)){ // si es un digito decimal ...
      r=d-'0'; // devuelvo su diferencia con el valor ascii del caracter '0'
    }
    if(isalpha(d)){ // si es alfanumerico ...
      d=toupper(d); // lo paso a mayusculas y ...
      r=10+(d-'A'); // devuelvo 10 mas su diferencia con el valor ascii de la letra 'A'
    }
  }
  return(r);
}

// MAIN Programa Principal ///////////////////////////////////////////////

void main(void)
{
  On_reset();

  do {

    // Deteccion de la necesidad de procesar comandos pendientes ///////
    if(new_command==1){ // Si hay un nuevo comando ...
      new_command=0; // deshabilito el aviso y ...
      Procesa_comando(); // Procesado de comandos
      Ini_buff_rec(); // inicializo todo para nuevo comando y ...
      pdte_send_prompt=1; // mando prompt.
    }

    // Deteccion de la necesidad de enviar echos ///////////////////////
    if(pdte_send_prompt==1){
      pdte_send_prompt=0;
      Send_prompt();
    }
    if(pdte_send_tmp_prompt==1){
      pdte_send_tmp_prompt=0;
      Send_tmp_prompt();
    }

  } while(TRUE);
}

// Funciones de Comando //////////////////////////////////////////////////

void Vuelca_EEPROM(void){ // Vuelca el contenido de la EEPROM

  int i,j;

  printf("\r\n\n** "); // Pongo cabecera de direcciones
  for(i=0;i<16;i++) printf("%X ",i);
  printf("\r\n");
  for(i=0; i<=NUMPAGSEEPROM; ++i) { // Vuelco contenido paginado
    printf("%2x ",i*16);
    for(j=0; j<=15; ++j) {
      printf( "%2x ", read_eeprom( i*16+j ) );
    }
    printf("\n\r");
  }
}

void Rellena_EEPROM(int x){ // Rellena toda la EEPROM con x

  int i,j;

  for(i=0; i<=NUMPAGSEEPROM; ++i) { // Escribo toda la eeprom
    for(j=0; j<=15; ++j) {
      write_eeprom(i*16+j,x);
    }
  }
}

void Write_port(int port, int valor){ // Pone a valor el estado del puerto port

  switch(port){
    case(10): output_a(valor); // Puerto A
              break;
    case(11): output_b(valor); // Puerto B
              break;
    default:
              printf("\r\nPort %1X?",port);
  }
}

// Procesa_comando: Hace cosas o manda hacerlas ... //////////////////////

void Procesa_comando(void){

  int1 procesado_ok=0;
  int waddress, wbyte;

  // COMANDO = "" intro en blanco ---------------------------------------
  strcpy(xcommand,"");
  if(!strcmp(buffrec,xcommand)){
    procesado_ok=1;
    goto fin_procesa;
  }
  // COMANDO = "?" ------------------------------------------------------
  strcpy(xcommand,"?");
  if(!strncmp(buffrec,xcommand,strlen(xcommand))){
    Send_opts();
    procesado_ok=1;
    goto fin_procesa;
  }

  // COMANDO = "setport" - saca un byte por un puerto -------------------
  strcpy(xcommand,"setport");
  if(!strncmp(buffrec,xcommand,strlen(xcommand))){
    waddress=Extrae_arg_hex('p',1);
    wbyte=Extrae_arg_hex('b',2);
    Write_port(waddress,wbyte);
    printf("\r\n%2x->%1X Ok",wbyte,waddress);
    procesado_ok=1;
    goto fin_procesa;
  }

  // COMANDOS EEPROM ////////////////////////////////////////////////////

  // COMANDO = "eedump" - vuelca contenido de eeprom -----------------------
  strcpy(xcommand,"eedump");
  if(!strncmp(buffrec,xcommand,strlen(xcommand))){
    Vuelca_EEPROM();
    procesado_ok=1;
    goto fin_procesa;
  }
  // COMANDO = "eeread" - lee una posicion de la eeprom --------------------
  strcpy(xcommand,"eeread");
  if(!strncmp(buffrec,xcommand,strlen(xcommand))){
    waddress=Extrae_arg_hex('d',2);
    wbyte=read_eeprom(waddress);
    printf("\r\nd%2x==b%2x",waddress,wbyte);
    procesado_ok=1;
    goto fin_procesa;
  }
  // COMANDO = "eewrite" - escribe una posicion de la eeprom ----------------
  strcpy(xcommand,"eewrite");
  if(!strncmp(buffrec,xcommand,strlen(xcommand))){
    waddress=Extrae_arg_hex('d',2);
    wbyte=Extrae_arg_hex('b',2);
    write_eeprom(waddress,wbyte);
    printf("\r\n%2x->%2x Ok",wbyte,waddress);
    procesado_ok=1;
    goto fin_procesa;
   }
   // COMANDO = "eefill" - rellena la eeprom a un valor ---------------------
   strcpy(xcommand,"eefill");
   if(!strncmp(buffrec,xcommand,strlen(xcommand))){
     wbyte=Extrae_arg_hex('b',2);
     Rellena_EEPROM(wbyte);
     procesado_ok=1;
     goto fin_procesa;
   }

fin_procesa:

  // COMANDO ERRÓNEO - ¿ezo qué é lo que é ?-----------------------------
  if(procesado_ok==0){
    printf("\r\n?%s",buffrec);
  }
}
 
 
 

Fuentes de RROS v2.0    El Rincón del C

 

 

Esta página se modificó el 27/12/2008


Esta página usa la letra Ñ

Nota pública importante sobre las consultas al Webmaster de PicManía.


Sugerencias a Picmanía... (que serán leídas pero seguramente no podrán ser contestadas)

Esta página pertenece al grupo de páginas de Diego RedRaven

 

 



Nota: Esta página Web esta repleta de imágenes, textos, logotipos y demás material extraídos de los mas variados medios de los que no soy ni autor ni depositario de los correspondientes derechos de autor, uso y/o reproducción. Si Ud. es depositario de dichos derechos y desea que el material correspondiente sea eliminado de esta Web no dude en ponerse en contacto conmigo mediante e-mail y será inmediatamente retirado. Gracias.
 
Visitas
Totales : 13356 Hoy: 1 Activas: 1 Vistas: 13356

Esta página fue modificada el 07-08-2010 22:42:20

           
 DmSoft WAMP Escribir Unreal