SDCC con delay en ensamblador embebido generado en PIKLoops para PIC16F628A y obtencion de la mediana con Quicksort

Ir abajo

SDCC con delay en ensamblador embebido generado en PIKLoops para PIC16F628A y obtencion de la mediana con Quicksort

Mensaje por maigke el Lun 4 Nov 2013 - 8:11

Buenos días a todos, ya hace rato que no escribo nada, pero no queria quedar con las ganas de compartir este código. Razz 

Bueno la cuestión es que se trata de muestrear el estado de un botón cada milisegundo (aun se debe verificar) 20 veces, lo que nos da un tiempo de toma de muestras de 20msegundos.
Usando la definición de mediana, y a través del algoritmo Quicksort que ha publicado Eduardo Urrea (http://blog.e-urrea.com/) se puede tomar la decisión si es abierto o cerrado el estado del push. (Hay formas muchisimo mas sencillas pero resultó interesante después de todo Wink). Ahora bien, la cuestión que es que para tomar la muestra cada determinado tiempo, sin recurrir a la librería delay.h, es posible generar el tiempo de retardo con la herramienta PikLoops, solo que el codigo que arroja está en ensamblador.

Bueno pues dado que SDCC permite agregar código ensamblador (Inline Assembly - http://www.maximintegrated.com/app-notes/index.mvp/id/3477) entonces podemos agregar el resultado que nos dé Pikloops a nuestro fuente en C y de esta forma hibridar el C con ensamblador para PIC14.

Dado que pikloops para generar los retardos nos arroja algo como esto
Código:

; Código de retardo generado por PikLoops (lun nov-2013-04 01:46:02)
; Tiempo de retardo = 0.00099900  con  Osc = 4.00000000MHz

retraso_0.001_seg
    movlw    D'2'
    movwf    ContadorB
    movlw    D'74'
    movwf    ContadorA
retraso_0.001_seg_bucle
    decfsz    ContadorA,1
    goto    retraso_0.001_seg_bucle
    decfsz    ContadorB,1
    goto    retraso_0.001_seg_bucle
    return

vemos que hay etiquetas, y registros (variables), pero que esto no nos limite!. En SDCC podemos acceder a variables declaradas en C, desde el ensamblador, solo que hay unas condiciones

1. La variable en C debe ser declarada como global, si se declara como variable local, entonces marcará un error de acceso
2. Para usar la variable de C en el ensamblador embebido, deberá colocarse antes del nombre de la variable un guión bajo
3. Las etiquetas marcadas en ensamblador, deberán finalizarse con dos puntos.

Bueno a continuación el código fuente completo, en realidad solo lo he compilado, no lo he probado, e incluso no hace absolutamente nada, eso solo una prueba de concepto, mas adelante, veremos si funciona correctamente la propuesta al implementarlo en fierros.

Código:

/* ----------------------------------------------------------------------- */
/* Plantilla generada por Piklab */
#include <pic16f628a.h>
#define MAX 20

/* ----------------------------------------------------------------------- */
/* Bits de configuración: adapte los parámetros a su necesidad */
typedef unsigned int word;
word __at 0x2007 CONFIG = _WDT_ON & _PWRTE_OFF & _RC_OSC_CLKOUT & _MCLRE_ON & _BODEN_ON & _LVP_ON  & _CP_OFF;




int pivot(int *unarray, int izq, int der);
void Quicksort(int *unarray, int izq, int der);
void delay();

void isr() __interrupt 0 {                                                                                                  /* rutina de servicio de interrupciones */
    /* << agregue el código de interrupción >> */
}


unsigned int dat[MAX];/*variable para guardar los datos muestreados*/
unsigned char ContadorA,ContadorB; /*Variables GLOBALES para el delay en ensamblador*/

void main() {
  unsigned char i=0;
  unsigned char acum;
    /* << agregue el código >> */
    if(RB7)
    {
      for(i=0;i<10;i++)
      {
    dat[i]=RB7;
    delay();
      }
     
      /*Se ordena el arreglo*/
      Quicksort(dat,0,MAX-1);
      
      /*Calculando la mediana de 20 muestras
      de los datos ya ordenados*/
    acum = (dat[MAX/2] + dat[MAX/2 +1])/2;
       /*Si la mediana de las lecturas tomadas cada segundo del estado
       del boton es 1 entonces se procede a realizar la función
       sino entonces sale de la rutina */
      if(acum==1)
      {
    /*Haz algo*/
      }
      /*se debe limpiar los valores que hay en el array */
      for(i=0;i<MAX;i++) dat[i]=0;
    }
}

int pivot(int *unarray, int izq, int der)
{
    int i;
    int pivote, valor_pivote;
    int aux;

    pivote = izq;
    valor_pivote = unarray[pivote];
    for (i=izq+1; i<=der; i++){
        if (unarray[i] < valor_pivote){
                pivote++;
                aux=unarray[i];
                unarray[i]=unarray[pivote];
                unarray[pivote]=aux;

        }
    }
    aux=unarray[izq];
    unarray[izq]=unarray[pivote];
    unarray[pivote]=aux;
    return pivote;
}

void Quicksort(int *unarray, int izq, int der)
{
     int pivote;
     if(izq < der){
        pivote=pivot(unarray, izq, der);
        Quicksort(unarray, izq, pivote-1);
        Quicksort(unarray, pivote+1, der);
     }
}

void delay(void)
{
 
 
      __asm
      ; Código de retardo generado por PikLoops (lun nov-2013-04 01:46:02)
      ; Tiempo de retardo = 0.00099900  con  Osc = 4.00000000MHz

retraso_0.001_seg:    ;se colocan los dos puntos en las etiquetas
    movlw    D'2'
    movwf    _ContadorB  ;se le coloca el guion bajo antes del nombre de la variable
    movlw    D'74'
    movwf    _ContadorA
retraso_0.001_seg_bucle:
    decfsz    _ContadorA,1
    goto    retraso_0.001_seg_bucle
    decfsz    _ContadorB,1
    goto    retraso_0.001_seg_bucle
    return
      __endasm;
  
}
Estas son las características de mi Linux box
Fedora 19 x64
6GB RAM
640GB HDD SATA
Intel Core i5
Desktop KDE 4.10
SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08 3.3.0 #8604 (May 11 2013) (Linux)
gpasm-1.2.0 #980 (Jun  5 2013)
p, li { white-space: pre-wra
Piklab
Versión 0.16.1
Pikloops 0.2.5


Saludos y comentarios

Pd. incluso creo que la temporizacion está mal !!! tongue  pero es una prueba de concepto aún.
Pd2. Esta es la salida del Piklab
p, li { white-space: pre-wrap; }
sdcc --use-non-free -mpic14 -p16f628a -V --debug -I/home/miguel/Documentos/ITST2013A/Proyectos2013/ -c testOrdenamientoQuickSort.c 
testOrdenamientoQuickSort.asm:203: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:368: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:372: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:517: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:521: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:649: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:653: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:693: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:697: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1512: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1516: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1589: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1593: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1718: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1722: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1863: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:1867: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2048: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2052: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2106: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2110: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2156: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2160: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2250: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2254: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2305: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2309: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2373: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2377: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2431: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2435: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2481: mensaje: Page or Bank selection not needed for this device. No code generated. 
testOrdenamientoQuickSort.asm:2485: mensaje: Page or Bank selection not needed for this device. No code generated. 
+ /usr/local/bin/sdcpp -nostdinc -Wall -I/home/miguel/Documentos/ITST2013A/Proyectos2013/ -D__SDCC_PROCESSOR="16f628a" -DSDCC_PROCESSOR="16f628a" -D__SDCC_PIC16F628A -obj-ext=.o -D__SDCC_USE_NON_FREE -DSDCC_USE_NON_FREE -D__SDCC=3_3_0 -DSDCC=330 -D__SDCC_REVISION=8604 -DSDCC_REVISION=8604 -D__SDCC_pic14 -DSDCC_pic14 -D__pic14 -D__STDC_NO_COMPLEX__ -D__STDC_NO_THREADS__ -D__STDC_NO_ATOMICS__ -D__STDC_NO_VLA__ -isystem /usr/local/bin/../share/sdcc/include/pic14 -isystem /usr/local/share/sdcc/include/pic14 -isystem /usr/local/bin/../share/sdcc/include -isystem /usr/local/share/sdcc/include -isystem /usr/local/bin/../share/sdcc/non-free/include/pic14 -isystem /usr/local/share/sdcc/non-free/include/pic14 -isystem /usr/local/bin/../share/sdcc/non-free/include -isystem /usr/local/share/sdcc/non-free/include testOrdenamientoQuickSort.c  
+ gpasm -g -o testOrdenamientoQuickSort.o -c testOrdenamientoQuickSort.asm 
sdcc --use-non-free -mpic14 -p16f628a -V --debug -Wl-c -Wl-m -I/home/miguel/Documentos/ITST2013A/Proyectos2013/ -otestOrdenamientoQuickSort.hex testOrdenamientoQuickSort.o 
using default linker script "/usr/share/gputils/lkr/16f628a_g.lkr" 
+ gplink -I/usr/local/bin/../share/sdcc/lib/pic14 -I/usr/local/share/sdcc/lib/pic14 -I/usr/local/bin/../share/sdcc/non-free/lib/pic14 -I/usr/local/share/sdcc/non-free/lib/pic14 -I/usr/local/bin/../share/sdcc/lib/pic14 -I/usr/local/share/sdcc/lib/pic14 -I/usr/local/bin/../share/sdcc/non-free/lib/pic14 -I/usr/local/share/sdcc/non-free/lib/pic14 -c -m -w -r -o testOrdenamientoQuickSort.hex testOrdenamientoQuickSort.o libsdcc.lib pic16f628a.lib  
*** Éxito *** 
Parsing COFF file: /home/miguel/Documentos/ITST2013A/Proyectos2013/testOrdenamientoQuickSort.cof
avatar
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 41
Localización : Mexico

Volver arriba Ir abajo

Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.