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
|