X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/blobdiff_plain/f5186e12ed5aedf98d0fa0d8299a73c830046c75..HEAD:/pruebas/sdcc/leds_asm/leds.asm diff --git a/pruebas/sdcc/leds_asm/leds.asm b/pruebas/sdcc/leds_asm/leds.asm index 5fd5314..bc729f1 100644 --- a/pruebas/sdcc/leds_asm/leds.asm +++ b/pruebas/sdcc/leds_asm/leds.asm @@ -4,25 +4,30 @@ .module leds .optsdcc -mmcs51 --model-small -; Variables globales -.globl _leds_matrix -.globl _leds_matrix_len -.globl _leds_delay - -; Funciones globales -.globl _leds_init -.globl _leds_write -.globl _leds_write0 -.globl _leds_write1 -.globl _leds_delay_update +; Constantes "públicas" +LEDS_MAX_COLS = 32 ; Cantidad máxima de columnas + +; Variables públicas +.globl _leds_matrix_len ; unsigned char +.globl _leds_matrix ; unsigned int[LEDS_MAX_COLS] +.globl _leds_delay ; unsigned char + +; Funciones públicas +.globl _leds_init ; void leds_init(); +.globl _leds_test ; void leds_test(); +.globl _leds_write ; void leds_write(unsigned int); +.globl _leds_write_low ; void leds_write_low(unsigned char); +.globl _leds_write_high ; void leds_write_high(unsigned char); +.globl _leds_delay_update ; void leds_delay_update(); +.globl _leds_timer2_isr ; void leds_timer2_isr() interrupt 5; + ; Constantes ; UN CICLO DE MAQUINA SON 1.6666 useg (clock 8MHz) -INTERVAL = 66 ; 0.1ms (por el clock de 8MHz) -LEDS0 = 0x0080 -LEDS1 = 0x00c0 -MAX_COLS = 64 -DELAY_BASE = 28 +INTERVAL = 33 ; 0.05ms (por el clock de 8MHz) +LEDS_HIGH = 0x0080 +LEDS_LOW = 0x00c0 +DELAY_BASE = 28 ; 16 columnas anda bien con 28 - (len / 2) == 20 ; Área de bancos de registros .area REG_BANK_0 (REL,OVR,DATA) @@ -46,23 +51,18 @@ _leds_delay:: delay: .ds 1 curr_col: -__stack: ; XXX - .ds 1 ; Variables en memoria RAM extendida indirecta (8052) .area ISEG (DATA) _leds_matrix:: - .ds MAX_COLS * 2 ; 2 bytes por columna + .ds LEDS_MAX_COLS * 2 ; 2 bytes por columna ; Configuramos el vector de interrupciones para atender el timer2 -.area INTV (ABS, CODE) - .org 0x0000 ; XXX - ljmp _leds_init ; XXX - - .org 0x002b - clr tf2 ; limpio bit de interrupción porque para el timer2 no es autom. - ljmp timer2_isr +;.area INTV (ABS, CODE) +; .org 0x002b +; clr tf2 ; limpio bit de interrupción porque para el timer2 no es autom. +; ljmp timer2_isr ; Área de código del programa @@ -74,14 +74,13 @@ _leds_matrix:: ; ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita. _leds_init:: - mov sp, #__stack ; XXX ; guardo registros que uso push ar0 push ar1 push ar2 ; leo de la ROM el tamaño por default - mov dptr, #MAT_D_LEN + mov dptr, #DEFAULT_MATRIX_LEN clr a movc a, @a+dptr mov _leds_matrix_len, a @@ -94,66 +93,94 @@ _leds_init:: mov delay, _leds_delay ; copio imagen por default de la ROM a la RAM - mov dptr, #MAT_D + mov dptr, #DEFAULT_MATRIX mov r0, #0 ; indice del "array" en la ROM mov r1, #_leds_matrix ; dirección de memoria de la RAM mov a, r0 -seguir$: +proximo$: movc a, @a+dptr ; leo de la ROM con el índice mov @r1, a ; escribo en el puntero a la RAM inc r1 ; incremento puntero inc r0 ; incremento índice mov a, r0 ; para comparar - cjne a, ar2, seguir$ ; veo si quedan más bytes por leer + cjne a, ar2, proximo$ ; veo si quedan más bytes por leer ; cargo los capture registers mov rcap2l, #<(-INTERVAL) ; low byte del intervalo mov rcap2h, #>(-INTERVAL) ; high byte del intervalo - mov ie, #0b10100000 ; habilito interrupcion timer 2 - ; bits de IE (interrupt enable) en 1: - ; IE.7 (Global enable/disable) - ; IE.5 (Enable timer 2 interrupt) - mov t2con, #0b00000100 ; setup timer 2 (auto-reload y start) + mov t2con, #0x00; setup del timer2 (auto-reload), no lo arrancamos + setb et2 ; habilito interrupcion timer2 (IE.5) mov curr_col, #0 ; inicializo el contador de columna en 0 ; Limpiamos stack - push ar2 - push ar1 - push ar0 + pop ar2 + pop ar1 + pop ar0 ret +; Hace una prueba simple de los leds +; Primitiva de C: +; void leds_test(); +; +; C se encarga de hacer push y pop del dptr, a y psw si lo necesita. +_leds_test:: + ; escribo patrones en los leds + mov dptr, #0xffff + acall _leds_write + acall sleep + + mov dptr, #0xaaaa + acall _leds_write + acall sleep + + mov dptr, #0x5555 + acall _leds_write + acall sleep + + mov dptr, #0x0000 + acall _leds_write + acall sleep + + ret + + ; Escribe en los leds. ; Primitiva de C: ; void leds_write(unsigned int); ; ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita. _leds_write:: + ; guardamos en r0 la parte alta que imprimimos despues + push ar0 + mov r0, dph ; parte baja mov a, dpl ; de C me viene la parte baja del argumento en el dpl - mov dptr, #LEDS0 + mov dptr, #LEDS_LOW cpl a ; complemento para ver encendidos los "1" movx @dptr, a ; parte alta - mov a, dph ; de C me viene la parte alta del argumento en el dph - mov dptr, #LEDS1 + mov a, r0 ; de C me viene la parte alta del argumento en el dph + mov dptr, #LEDS_HIGH cpl a ; complemento para ver encendidos los "1" movx @dptr, a + ; devolvemos r0 + pop ar0 ret ; Escribe en los leds del primer latch. ; Primitiva de C: -; void leds_write0(unsigned char); +; void leds_write_low(unsigned char); ; ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita. -_leds_write0:: +_leds_write_low:: ; parte baja mov a, dpl ; de C me viene el argumento en el dpl - mov dptr, #LEDS0 + mov dptr, #LEDS_LOW cpl a ; complemento para ver encendidos los "1" movx @dptr, a ret @@ -161,13 +188,13 @@ _leds_write0:: ; Escribe en los leds del segundo latch. ; Primitiva de C: -; void leds_write1(unsigned char); +; void leds_write_high(unsigned char); ; ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita. -_leds_write1:: +_leds_write_high:: ; parte baja mov a, dpl ; de C me viene el argumento en el dpl - mov dptr, #LEDS1 + mov dptr, #LEDS_HIGH cpl a ; complemento para ver encendidos los "1" movx @dptr, a ret @@ -190,10 +217,13 @@ _leds_delay_update:: ret -; Manejador de la interrupción del timer2 -timer2_isr: +; Manejador de la interrupción del timer2 para el uso de los leds. +; Primitiva de C: +; void leds_timer2_isr() interrupt 5; +; +_leds_timer2_isr:: ; vemos si todavía hay que seguir esperando o si ya tenemos que leer - djnz delay, fin$ + djnz delay, 255$ ; comenzamos realmente a leer la próxima columna mov delay, _leds_delay @@ -207,13 +237,13 @@ timer2_isr: ; vemos si hay que empezar a leer por la 1ra columna de nuevo mov a, curr_col - cjne a, _leds_matrix_len, continua$ + cjne a, _leds_matrix_len, 1$ ; hay que empezar de nuevo mov curr_col, #0 mov a, curr_col ; dejamos en a la columna actual -continua$: +1$: ; multiplicamos por 2 porque hay 2 bytes por columna clr c rlc a @@ -223,16 +253,16 @@ continua$: add a, r0 ; le sumo al puntero el offset actual segun la columna mov r0, a - ; imprimo en LEDS1 + ; imprimo en LEDS_LOW mov a, @r0 ; leo el contenido de la matriz - mov dptr, #LEDS1 + mov dptr, #LEDS_LOW cpl a ; complemento para ver encendidos los "1" movx @dptr, a - ; imprimo en LEDS0 + ; imprimo en LEDS_HIGH inc r0 ; busco proximo byte de la columna mov a, @r0 ; leo el contenido de la matriz - mov dptr, #LEDS0 + mov dptr, #LEDS_HIGH cpl a ; complemento para ver encendidos los "1" movx @dptr, a @@ -248,16 +278,30 @@ continua$: pop psw pop acc -fin$: +255$: reti ; listo! seguimos viaje... +; Provoca un retardo corto. +; Usamos dpl y dph porque son "C-safe". +sleep: + mov a, #0xff +2$: + mov dph, #0xff +1$: + mov dpl, #0xff + djnz dpl, . + djnz dph, 1$ + djnz acc, 2$ + ret + + ; Matriz por default -MAT_D_LEN: +DEFAULT_MATRIX_LEN: .db 16 ;.db 32 -MAT_D: +DEFAULT_MATRIX: .dw 0b0000111111110000 ; columna 0 .dw 0b0011111111111100 ; columna 1 .dw 0b0111000000001110 ; columna 2 @@ -275,24 +319,23 @@ MAT_D: .dw 0b0011111111111100 ; columna 14 .dw 0b0000111111110000 ; columna 15 -; .dw 0b0000111111110000 ; columna 0 -; .dw 0b0011111111111100 ; columna 1 -; .dw 0b0111000000001110 ; columna 2 -; .dw 0b0110000000000110 ; columna 3 -; .dw 0b1100110000000011 ; columna 4 -; .dw 0b1100011000110011 ; columna 5 -; .dw 0b1100001100110011 ; columna 6 -; .dw 0b1100001100000011 ; columna 7 -; .dw 0b1100001100000011 ; columna 8 -; .dw 0b1100001100110011 ; columna 9 -; .dw 0b1100011000110011 ; columna 10 -; .dw 0b1100110000000011 ; columna 11 -; .dw 0b0110000000000110 ; columna 12 -; .dw 0b0111000000001110 ; columna 13 -; .dw 0b0011111111111100 ; columna 14 -; .dw 0b0000111111110000 ; columna 15 - -;MAT_D: + .dw 0b1111000000001111 ; columna 0 + .dw 0b1100000000000011 ; columna 1 + .dw 0b1000111111110001 ; columna 2 + .dw 0b1001111111111001 ; columna 3 + .dw 0b0011001111111100 ; columna 4 + .dw 0b0011100111001100 ; columna 5 + .dw 0b0011110011001100 ; columna 6 + .dw 0b0011110011111100 ; columna 7 + .dw 0b0011110011111100 ; columna 8 + .dw 0b0011110011001100 ; columna 9 + .dw 0b0011100111001100 ; columna 01 + .dw 0b0011001111111100 ; columna 00 + .dw 0b1001111111111001 ; columna 01 + .dw 0b1000111111110001 ; columna 03 + .dw 0b1100000000000011 ; columna 04 + .dw 0b1111000000001111 ; columna 05 + ; .dw 0b0000001111100000 ; columna 0 ; .dw 0b0000111110000000 ; columna 1 ; .dw 0b0111111000000000 ; columna 2