///////////////////////////////////////
// Constantes
///////////////////////////////////////
int const lenbuff=128; // Longitud máxima del buffer
char const delimiter = ','; // Delimitador de parametros
char const disabler = '"'; // Deshabilitador de parametros
int const lenparam = 32; // Máxima longitud por parámetro
///////////////////////////////////////
// RAM
///////////////////////////////////////
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer de recepción
int1 flagcommand=0; // Flag para comando disponible
///////////////////////////////////////
// Funciones de Buffer
///////////////////////////////////////
// Cuenta los parametros en el buffer --
int8 count_param_number(void){
int8 ret, i;
int1 active;
char c;
ret=0;
active=1;
// ¿Hay comando?
c = cbuff[0];
if(c != 0x00) ret=1;
// Cuenta parámetros
for(i=0;i<lenbuff,c!=0x00;i++){
c = cbuff[i];
if(c==disabler && active==1) active=0; else if(c==disabler && active==0) active=1;
if(active==1) if(c==delimiter) ++ret;
}
return ret;
}
// Extrae un Parámetro del buffer ------
int1 get_param_by_order(int8 pos, int8 maxlen, char* pP){
int1 ret=0;
char tmp[lenparam];
int8 i,j;
int8 nDelimiter;
int1 active=1;
for(i=0,j=0,nDelimiter=0;i<lenbuff;i++){
tmp[j]=0x00;
if(nDelimiter==pos){
if(!(j==0 && cbuff[i]==disabler)) tmp[j++]=cbuff[i];
}
if(cbuff[i]==disabler && active==1) active=0; else if(cbuff[i]==disabler && active==0) active=1;
if(active==1) if((cbuff[i]==Delimiter) || (cbuff[i]==0x00)) ++nDelimiter;
if(nDelimiter>pos){
j -= 1;
break;
}
}
if(tmp[j-1]==disabler) --j;
tmp[j]='\0';
if(j>maxlen){
ret=1;
}else{
strcpy(pP,tmp);
}
return ret;
}
// Echo selectivo ----------------------
void echo_sel(char c){
switch(c){
case 0x0D: // Si he pulsado la tecla [Intro]
printf("\r\n[Ent]\r\n");
break;
case 0x08: // Si he pulsado la tecla [Retroceso]
printf("\r\n[Del]\r\n>%s",cbuff);
break;
case 0x1B: // Si he pulsado la tecla [Escape]
printf("\r\n[Esc]\r\n>");
break;
default: // Echo de cualquier otro caracter
putc(c);
}
}
// Inicia a \0 cbuff -------------------
void init_cbuff(void){
int i;
for(i=0;i<lenbuff;i++){// Bucle que pone a 0 todos los
cbuff[i]=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el indice de siguiente caracter
}
// Añade a cbuff -----------------------
void add_2_cbuff(char c){
switch(c){
case 0x0D: // Enter -> Habilita Flag para procesar comando
flagcommand=1;
break;
case 0x08: // Del -> Borra último caracter del Buffer
if(xbuff>0) cbuff[--xbuff]=0x00;
break;
case 0x01B: // Esc -> Borra el Buffer completamente
init_cbuff();
break;
default: // Añade caracter recibido al Buffer
cbuff[xbuff++]=c;
}
}
///////////////////////////////////////
// Procesador de Comandos
///////////////////////////////////////
void commad_menu(void){
printf("\r\nTyP_Serie_TTL\r\n");
printf("Método : Extrayendo parámetros del Buffer\r\n");
printf(" delimitados por [%c]\r\n\n",delimiter);
printf("[Enter] Procesa el buffer recibido.\r\n");
printf("[Escape] Borra todo el buffer.\r\n");
printf("[Delete] Borra último carácter del buffer.\r\n");
printf("\r\n\r\n>");
}
void commad_process(void){
int n,i;
char command[lenparam]; // Comando
char param[5][lenparam]; // Parámetros
flagcommand=0; // Desactivo flag de comando pendiente.
printf("\nProcesando ...\r\n\n");
// Primera Parte: Cuantos
n = count_param_number(); // Cuento el número de parámetros
if(n==0){
printf("En el Buffer no hay ni comando ni parámetro alguno\r\n\n");
}
else{
if(n==1){
printf("En el Buffer hay un comando y ningún parámetro\r\n\n");
}
else{
printf("En el Buffer hay un comando y %u parámetro(s)\r\n\n",n-1);
}
}
// Segunda Parte: Cuales
if(n>0){
get_param_by_order(0,lenparam,command);
printf("Comando <%s>\r\n",command);
if(n>1){
for(i=1;i<n;i++){
get_param_by_order(i,lenparam,¶m[i-1][0]);
printf("Parámetro %u <%s>\r\n",i,param[i-1]);
}
}
}
init_cbuff(); // Borro buffer.
printf("\nProcesado.\r\n\n>"); // Monitorizo procesado.
}
///////////////////////////////////////
// INTERRUPCIONES : RDA Recepción USART
///////////////////////////////////////
#int_rda
void serial_isr() { // Interrupción recepción serie USART
char rcvchar=0x00; // último caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar=getc(); // lo descargo y ...
add_2_cbuff(rcvchar); // lo añado al buffer y ...
echo_sel(rcvchar); // hago eco selectivo (si procede).
}
}
///////////////////////////////////////
// MAIN
///////////////////////////////////////
void main() {
delay_ms(2000); // Espero a estabilizar antes de actuar
// HARD ///////////
output_low(PIN_E2);
output_low(PIN_C0);
output_low(PIN_D7);
output_low(PIN_E1);
output_low(PIN_E0);
output_high(PIN_D1);
output_high(PIN_D0);
delay_ms(110);
output_low(PIN_D0);
///////////////////
commad_menu();
init_cbuff(); // Borra buffer al inicio
enable_interrupts(int_rda); // Habilita Interrupción RDA
enable_interrupts(global); // Habilita interrupciones
do {
if(flagcommand) commad_process(); // Hay algo pendiente de procesar y lo procesa.
} while (TRUE);
}
///////////////////////////////////////
// Fin de programa
///////////////////////////////////////