TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Leon Pic en 16 de Noviembre de 2008, 14:39:49

Título: Rutinas para compartir
Publicado por: Leon Pic en 16 de Noviembre de 2008, 14:39:49
He empezado a organizar mis cosas y como lo prometido es deuda http://www.todopic.com.ar/foros/index.php?topic=22737.msg187480#msg187480 subo la librería para manejar un LCD de 16 x 2 coompatibles con los chips Hitachi.

Esta librería, es una mejora del que se encuentra en x-robotics (http://www.x-robotics.com).

Nota: No permite el envío de caracteres especiales, solo código ASCII. Cuando la modifique, lo subo aquí.
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 18 de Noviembre de 2008, 21:47:45
Subo una rutina para hacer una resta de dos números de 8 bits. No es nada del otro mundo pero puede ahorrarnos tiempo.

EDITO: Mejoré un poquito la rutina porque podía traer problemas.
Título: Re: Rutinas para compartir
Publicado por: sander en 02 de Diciembre de 2008, 18:52:30
Gran iniciativa Leon Pic , pero dime, probaste la libreria para manejar el LCD en la vida real , porque la probe en el proteus y no me funciono.

Saludos
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 03 de Diciembre de 2008, 09:33:37
Si, funciona en la vida real.

Lo que debe pasar, es que el PROTEUS no simula el bit 7 del LCD qe se pone a 0 cuando se desocupó y puede recibir datos.
Título: Re: Rutinas para compartir
Publicado por: sander en 03 de Diciembre de 2008, 13:55:09
Mmmm, interesante  acabo de probar la rutina usando el PIC Simulator IDE y ahi si funciona, en todo caso lo importante es que funcione en el mundo real. Aprovecho para compartir la rutina de retardo de 5 ms que use para hacer la prueba.
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 14 de Diciembre de 2008, 08:09:07
hola a todos¡¡ joe hace tanto que no tengo tiempo para el foro,(maldito trabajo) que casi me da verguenza escribir :D 
buena idea lo de tener un topic para compartir librerias, asi hay un lugar al que recurrir donde coger ejemplos. Ademas de hacer busquedas en el foro.
Voy a copiar/pegar y os dejo algunas de las que mas uso para 16f877a

CAD 16F877
Código: ASM
  1. CAD_converter        MACRO
  2.                         DEFINICIONES RAM
  3.                         CBLOCK  0X20
  4.                         N_POTE
  5.                         ENDC
  6.  
  7. #DEFINE         REG_POTEX       (N_POTE+.1)     ;+1 QUE EL ULTIMO REGISTRO USADO. guarda el resultado del CAD en el registro al que apunte FSR
  8.  
  9. ;LA RUTINA CANAL_AD_X SE MANEJA INDICANDOLE EL CANAL DONDE SE QUIERE HACER LA CONVERSION
  10. ;DECLARACIONES DE LOS CANALAES/CH_, ANALOGICOS/AN_, NUMERO DE CANAL/X(0-7)
  11. ;CH_AN_X
  12. #DEFINE         CH_AN_0         B'10000101'
  13. #DEFINE         CH_AN_1         B'10001101'    
  14. #DEFINE         CH_AN_2         B'10010101'
  15. #DEFINE         CH_AN_3         B'10011101'
  16. #DEFINE         CH_AN_4         B'10100101'    
  17. #DEFINE         CH_AN_5         B'10101101'
  18. #DEFINE         CH_AN_6         B'10110101'
  19. #DEFINE         CH_AN_7         B'10111101'
  20. EJEMPLO_DE_USO
  21.         ;-----------------------------CONFIGURAMOS EL CAD
  22. CONFIG_ADCON1                                   ;000000000 TODOS LOS CANALES ANALOGICOS
  23.                 BANKSEL ADCON1         
  24.                 MOVLW   B'00000000'
  25.                 MOVWF   ADCON1
  26.         ;-----------------------------
  27. BUCLE                                                                   ;ANTES DE NADA HAY QUE LIMPIAR LOS REGISTROS N_POTE Y FSR PARA QUE GUARDE
  28.                                                                                 ;EL RESULTADO DE LA CONVERSION EN EL ARRAY DE MEMORIA RESERVADO PARA ELLO, A PARTIR DE LA POSICION DE MEMORIA, REG_POTEX
  29.                         BANKSEL N_POTE
  30.                         CLRF    N_POTE                          ;POTES Nº 0
  31.                         MOVLW   REG_POTEX                       ;DIRECCION DE LA MEMORIA RAM EN LA QUE EMPIEZA A GUARDAR LAS CONVERSIONES
  32.                         MOVWF   FSR
  33. ;0
  34.                         MOVLW   CH_AN_0                         ;A W
  35.                         CALL    CANAL_AD_X                      ;CANALx DEL CAD
  36. ;1                                                                              ;Y GUARDA EL RESULTADO DE LA CONVERSION EN INDF ((REG_POTEX +.Nº DE VECES QUE SE LLAMA A LA RUTINA CANAL_ADX))
  37.                         MOVLW   CH_AN_1                         ;A W
  38.                         CALL    CANAL_AD_X                      ;CANALx DEL CAD
  39.                        
  40.                         GOTO    BUCLE                           ;VUELVE A EMPEZAR
  41.                        
  42. CANAL_AD_X                                                              ;SELECCIONA CANAL X DEL CAD NO INICIA LA CONVERSION
  43.         BANKSEL ADCON0
  44.         MOVWF   ADCON0
  45.         CALL    DEMORA_25uS                                     ;EL TIEMPO DE ADQUISICION CORRECTO PARA CARGAR EL CONDENSADOR ANTES DE INICIAR LA CONVERSION  
  46.  
  47.         BANKSEL N_POTE
  48.         INCF    N_POTE,F                                        ;SIGUIENTE POTE
  49.         INCF    FSR,F                                           ;CADA VEZ QUE SE LLAMA A LA RUTINA QUE LEE EL
  50.                                                                                 ;VALOR DEL POTE, SE INCREMENTA EL REGISTRO FSR, PARA QUE REALICE LAS OPERACIONES
  51.                                                                                 ;EN EL REGISTRO DEL SIGUIENTE POTENCIOMETRO
  52.         BANKSEL ADCON0
  53.         BSF             ADCON0,GO                                       ;INICIA LA CONVERSION
  54. ESPERA_CAD                                                              ;TESTEA HASTA QUE TERMINA LA CONVERSIÓN
  55.         BTFSC   ADCON0,GO                                       ;HASTA QUE SE PONE A CERO EL BIT GO/DONE
  56.         GOTO    ESPERA_CAD                                      ;VUELVE ATRAS HASTA QUE TERMINE
  57.         MOVF    ADRESH,W
  58.         BANKSEL REG_DIVISOR    
  59.         MOVWF   REG_DIVISOR    
  60. RESTA
  61.         BANKSEL REG_POTEX
  62.         BCF             STATUS,Z
  63.         SUBWF   INDF,W
  64.         BTFSC   STATUS,Z
  65.         RETURN
  66. ENVIA_DATOS    
  67.         BANKSEL REG_DIVISOR    
  68.         MOVWF   INDF
  69.         ;aqui hace algo si el resultado de la conversion no es cero
  70.         RETURN
  71.         ENDM


W/R EEPROM 16F877

Código: ASM
  1. ;ESTAS SON LAS RUTINAS PARA R/W LA EEPROM
  2. ;SOLO HAY QUE INDICARLES EL DATO A GUARDAR EN REG_MUESTRA
  3. ;Y LA DIRECCION DE LA EEPROM 0-256 POSICIONES ANTES DE USARLAS
  4. ;DEFINICIONES RAM
  5.                         CBLOCK  0X20
  6.                         REG_MUESTRA
  7.                         N_POTE
  8.                         ENDC
  9.  
  10. #DEFINE         N_REG_EEPROM_POTES      .0      ;POSICION DE LA EEPROM PARA LOS DATOS A GUARDAR
  11.  
  12. R_W_EEPROM              MACRO
  13. CONTINUA_ESCRITURA     
  14.                 BCF             STATUS,RP0
  15.                 BCF             STATUS,RP1
  16.                 MOVF    REG_MUESTRA,W  
  17.                 BSF             STATUS,RP1     
  18.                 MOVWF   EEDATA                 
  19.                 BSF     STATUS,RP0             
  20.                 BCF     EECON1,EEPGD    
  21.                                                                
  22.                 BSF     EECON1,WREN    
  23.                 MOVLW   0X55 ;
  24.                 MOVWF   EECON2                 
  25.                 MOVLW   0XAA ;
  26.                 MOVWF   EECON2                 
  27.                 BSF     EECON1,WR              
  28.                 BTFSC   EECON1,WR              
  29.                 GOTO    $-1                    
  30.                 BCF     EECON1,WREN    
  31.                 BCF             STATUS,RP0
  32.                 BCF             STATUS,RP1
  33.                 RETURN
  34.                 ;---------------------------
  35. CONTINUA_LECTURA
  36.                 BANKSEL EECON1
  37.                 BCF     EECON1,EEPGD           
  38.                 BSF     EECON1,RD                      
  39.                 BANKSEL EEDATA
  40.                 MOVF    EEDATA,W                        ;;Y DEPOSITAMOS EN W, EL VALOR RECOGIDO DE LA TABLA ESCRITA EN LA EEPROM ;)
  41.                 BCF             STATUS,RP0     
  42.                 BCF             STATUS,RP1     
  43.                 RETURN
  44.  
  45. ;YO POR EJEMPLO UTILIZO EL MARCADOR DE LAS RUTINAS ANTERIORES DEL CAD, N_POTE.
  46. ;SUMANDOSELO A LA DIRECCION DONDE COMIENZA SU ARRAY DE MEMORIA N_REG_EEPROM_POTES, EN ESTE CASO VALE CERO.
  47. LECTURA_EEPROM_POTES
  48.                 BANKSEL N_POTE
  49.                 MOVF    N_POTE,W               
  50.                 BANKSEL EEADR
  51.                 MOVWF   EEADR                  
  52.                 MOVLW   N_REG_EEPROM_POTES      ;MUEVE UNA CONSTANTE A W
  53.                 ADDWF   EEADR,F                         ;Y LO SUMA A LA POSICION DE N_POTE
  54.                 GOTO    CONTINUA_LECTURA
  55. ESCRITURA_EEPROM_POTES
  56.                 BCF     STATUS,RP0      
  57.                 BCF             STATUS,RP1
  58.                 MOVF    N_POTE,W        
  59.                 BSF             STATUS,RP1             
  60.                 MOVWF   EEADR                  
  61.                 MOVLW   N_REG_EEPROM_POTES
  62.                 ADDWF   EEADR,F                        
  63.                 GOTO    CONTINUA_ESCRITURA
  64.  
  65.                 ENDM

convertidor binario a 7 segmentos, esta ya la conocereis, es del foro

Código: ASM
  1. CONVERTIDORES   MACRO  
  2.          CBLOCK       0X20
  3.         REG_MEM_DISPLAYS                ;ATENCION QUE SON TRES DESPUES E ESTE PARA MSD LSD CENT
  4.         ENDC
  5. #DEFINE         LSD                     REG_MEM_DISPLAYS
  6. #DEFINE         MSD                     (REG_MEM_DISPLAYS+.1)
  7. #DEFINE         CENT            (REG_MEM_DISPLAYS+.2)
  8.  
  9. B2_BCD_7_SEGMENT
  10.                 CLRF CENT                       ;CENTENAS
  11.                 clrf MSD                        ;DECENAS
  12.                 movwf LSD                       ;UNIDADES
  13. gtenth
  14.                 movlw .10
  15.                 subwf LSD,W
  16.                 BTFSS STATUS,C
  17.                 goto OVERHAUL
  18.                 movwf LSD
  19.                 incf MSD, F
  20.                 goto gtenth
  21. OVERHAUL
  22.                 MOVLW .10
  23.                 SUBWF MSD,W
  24.                 BTFSS STATUS,C
  25.                 GOTO OVER
  26.                 MOVWF MSD
  27.                 INCF CENT,F
  28.                 GOTO OVERHAUL
  29. OVER
  30.                 MOVF    CENT,W
  31.                 CALL    S_SEGMENT
  32.                 MOVWF   CENT
  33.  
  34.                 MOVF    MSD,W
  35.                 CALL    S_SEGMENT
  36.                 MOVWF   MSD
  37.  
  38.                 MOVF    LSD,W
  39.                 CALL    S_SEGMENT
  40.                 MOVWF   LSD
  41.                 RETLW 0
  42.  
  43.        
  44. S_SEGMENT       ;PASA A CODE 7 SEGMENTOS
  45.                         ADDWF   PCL,F  
  46.                         RETLW   B'11000000'
  47.                         RETLW   B'11111001'                            
  48.                         RETLW   B'10100100'
  49.                         RETLW   B'10110000'
  50.                         RETLW   B'10011001'
  51.                         RETLW   B'10010010'
  52.                         RETLW   B'10000010'
  53.                         RETLW   B'11111000'
  54.                         RETLW   B'10000000'
  55.                         RETLW   B'10010000'
  56.                         ENDM
  57.         ;---------------------------------

y una rutina que utiliza registros 74595 para mostrar los datos por displays de 7 segmentos o simplemente ampliar con mas salidas al pic

Código: ASM
  1. ;---------------------------------
  2.  
  3.         OUT_SHIFT_REGISTER      MACRO
  4.         cblock  0X20
  5.         REG_ENV_SPI
  6.         N_DIGITOS
  7.         FSR_TEMP2
  8.         REG_MEM_DISPLAYS                ;ATENCION QUE SON TRES DESPUES E ESTE PARA MSD LSD CENT
  9.         ENDC
  10. #DEFINE         LSD                     REG_MEM_DISPLAYS
  11. #DEFINE         MSD                     (REG_MEM_DISPLAYS+.1)
  12. #DEFINE         CENT            (REG_MEM_DISPLAYS+.2)
  13.  
  14. #DEFINE         LATCHX  PORTD,0                                
  15. #DEFINE         CLOKX   PORTD,3
  16. #DEFINE         DATOX   PORTD,2
  17. #DEFINE         N_REG_OUT       .3
  18.  
  19.  
  20. ENVIO_POSICIONES
  21.                         CALL    B2_BCD_7_SEGMENT        ;PASA W DE BINARIO A BCD Y DESPUES A 7 SEGMENTOS, Y LO PONE EN EL ARRAY PARA SALIR             
  22. ENVIA_TEXTOS                                            ;ENVIA LO QUE HAYA EN EL ARRAY DE REGISTROS PARA LAS SALIDAS LSD,MSD,CENT
  23.                 BCF             STATUS,RP0                      ;PAGE 0
  24.                 MOVF    FSR,W
  25.                 MOVWF   FSR_TEMP2
  26.                 MOVLW   N_REG_OUT                       ;Nº DE REGISTROS A LA SALIDA
  27.                 MOVWF   N_DIGITOS
  28.                 MOVLW   REG_MEM_DISPLAYS        ;DONDE ESTA EL PRIMER BYTE A SACAR EN SERIE
  29.                 MOVWF   FSR            
  30. ENVIAR_SPI
  31.                 MOVF    INDF,W
  32. LETRA
  33.                 MOVWF   REG_ENV_SPI                     ;DE W A REG_ENV_SPI
  34.                 MOVLW   .9                                      ;Nº DE BITS DEL REGISTRO A W
  35.                 MOVWF   N_BITS                          ;DE W A N_BITS
  36. REMONT         
  37.                 DECFSZ  N_BITS,F                        ;DECREMENTA Nº DE BITS 8-0
  38.                 GOTO    ENVIA_BIT                       ;SALTA A ENVIA_BIT
  39.                 GOTO    COMPLETA                        ;RETORNA, NO QUEDAN MAS BITS A ENVIAR
  40.  
  41. ENVIA_BIT
  42.                 RLF             REG_ENV_SPI,F           ;ROTA A LA IZQUIERDA Y EL BIT DE MAS PESO VA AL CARRY, A LA SIGUIENTE
  43.                                                                         ;ESTE VUELVE A ENTRAR POR EL CARRY;Y CUANDO PASAN 8 BITS VUELVE A DEJAR EL QUE ESTABA
  44.                 BTFSC   STATUS,C                        ;TESTEA SI ES CERO O UNO
  45.                 GOTO    ENVIA_UNO                       ;SI FUE CERO NO SALTA Y VA A ENVIA _UNO
  46.                         ;--------------ENVIA CERO Y ESPERA NUEVO BIT------------------------------------
  47. ENVIA_CERO                                                      ;SI FUE CERO SALTA PARA ENVIAR CERO POR EL SPI
  48.                 BCF             DATOX                           ;PONE A CERO RA0
  49.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  50.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  51.                 BSF             CLOKX                           ;CLOCK EN ALTO RA1 PARA ENVIAR DATO
  52.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  53.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  54.                 BCF             DATOX                           ;PONE A CERO RA0
  55.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  56.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  57.                 BCF             CLOKX                           ;PONE A CERO CLOCK PARA ESPERAR NUEVO DATO
  58.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  59.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  60.                 GOTO    REMONT                          ;RETORNA PARA ENVIAR NUEVO BIT
  61.                         ;--------------ENVIA UNO Y ESPERA NUEVO BIT-----------------------------------
  62. ENVIA_UNO                                                       ;SI EL CARRY ESTABA A UNO, NO SALTÓ
  63.                 BSF             DATOX                           ;1 EN DATO
  64.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  65.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  66.                 BSF             CLOKX                           ;CLOCK A UNO PARA ENVIAR DATO
  67.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  68.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  69.                 BCF             DATOX                           ;PONE A CERO PARA ESPERAR NUEVO DATO
  70.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  71.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  72.                 BCF             CLOKX                           ;PONE A CERO PARA ESPERAR NUEVO DATO
  73.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  74.                 NOP                                                     ;ESPERA PARA ESTABILIZAR
  75.                 GOTO    REMONT                          ;RETORNA PARA ENVIAR NUEVO BIT
  76. COMPLETA
  77.                 DECFSZ  N_DIGITOS,F
  78.                 GOTO    OTRO_MAS
  79.                 RETURN
  80. LATCH          
  81.                 BSF             LATCHX                          ;SACA LOS DATOS DEL CARRIL SERIE DE LOS 74595 A LAS SALIDAS PARALELO
  82.                 NOP
  83.                 NOP
  84.                 BCF             LATCHX
  85.                 NOP
  86.                 NOP
  87.                 MOVF    FSR_TEMP2,W
  88.                 MOVWF   FSR
  89.                 RETURN
  90. OTRO_MAS
  91.                 INCF    FSR,F
  92.                 GOTO    ENVIAR_SPI
  93.                
  94.                 ENDM   
  95.  
  96. EJEMPLO1                                      ;SACANDO NUMEROS
  97.                 MOVLW   .37            
  98.                 CALL    ENVIO_POSICIONES
  99.                 CALL    LATCH
  100.  
  101. EJEMPLO2        ; oLE
  102.                 MOVLW   S_O
  103.                 MOVWF   CENT
  104.                 MOVLW   S_L
  105.                 MOVWF   MSD
  106.                 MOVLW   S_E
  107.                 MOVWF   LSD
  108.                 CALL    ENVIA_TEXTO
  109.                 CALL    LATCH
  110. ;LETRAS EN 7 SEGMENTOS
  111. #DEFINE         S_A                     B'10001000';a
  112. #DEFINE         S_H                     B'10001001';h
  113. #DEFINE         S_O                     B'10100011';o
  114. #DEFINE         S_L                     B'11000111';l
  115. #DEFINE         S_M                     B'10101011';m
  116. #DEFINE         S_U                     B'11000001';u
  117. #DEFINE         S_N                     B'10101011';n
  118. #DEFINE         S_D                     B'10100001';d
  119. #DEFINE         S_E                     B'10000110';e
  120. #DEFINE         S_G                     B'11000010';g
  121.  
  122. EJEMPLO3
  123.                 MOVLW   B'11011111'             ;COLUMNAS PARA TECLADO
  124.                 MOVWF   REG_ENV_SPI    
  125.                 CLRF    N_DIGITOS
  126.                 CALL    LETRA  
  127.                 CALL    LATCH

reedito por que tengo mais rutinillas por aqui  8) 8)
como esta que utiliza registros de desplazamiento para hacer un teclado de XxX columnas solo hay que definir el nº de entradas y salidas que tiene, y ale 8x4 , 16x32... vosotros soldais¡¡


Código: ASM
  1. CBLOCK  0X20
  2.                         COLUMNAS
  3.                         N_BUTTON
  4.                         N_BUTTON_CON
  5.                         N_VECES
  6.                         PDel0
  7.                         PDel1
  8.                         CARGADOR
  9.                         ENDC
  10.  
  11. ;CONEXIONES DE LOS REGISTROS DEL TECLADO_MATRICIAL XxX
  12. ;###########################################                           
  13. #DEFINE         SR_IN           PORTB,1
  14. #DEFINE         SR_OUT          PORTB,2
  15. #DEFINE         CLOCK_IN        PORTB,3
  16. #DEFINE         LATCH_OUT       PORTB,4
  17. #DEFINE         CLOCK_OUT       PORTB,5
  18. #DEFINE         LATCH_IN        PORTB,6
  19. ;###########################################
  20. #DEFINE         NUMERO_DE_ENTRADAS      .8                              ;Nº DE PULSADORES CONCTADOS A LAS IN PARALELO DE LOS 74165
  21. #DEFINE         NUM_COLUMNAS            B'11111101'             ;SECUENCIA A CARGAR EN LOS REGISTROS 74595 COLUMNAS DE TECLADO
  22. #DEFINE         NUM_VECES               .9                              ;Nº+1 DE VECES QUE TIENE QUE CAMBIAR DE COLUMNA
  23. ;DEFINIENDO ESTOS VALORES SE PUEDEN USAR TECLADOS MATRICIALES DE 3x2, 4x4 CADA UNO QUE PONGA EL QUE NECESITE

Código: ASM
  1. PULSADORES_MATRIZ_CON_REGISTROS MACRO
  2. TECLADO_MAT
  3.                 BANKSEL         COLUMNAS
  4.                 MOVLW           NUM_COLUMNAS            ;Nº DE COLUMNAS
  5.                 MOVWF           COLUMNAS
  6.                 MOVLW           NUM_VECES
  7.                 MOVWF           N_VECES
  8. TECLADO
  9.                 DECFSZ          N_VECES,F
  10.                 GOTO            STREEP
  11.                 RETURN                                                  ;VUELVE_CUANDO SE ACABA EL Nº DE SALIDAS
  12. STREEP
  13.                 BSF                     STATUS,C                       
  14.                 RRF                     COLUMNAS,F
  15.                 BTFSC           COLUMNAS,0
  16.                 GOTO            SACA_UNO
  17. SACA_CERO
  18.                 BANKSEL         PORTD
  19.                 BCF                     SR_OUT
  20.                 NOP
  21.                 NOP
  22.                 CALL            SIGUIENTE_CLOCK_OUT
  23.                 GOTO            COMPRUEBA
  24. SACA_UNO
  25.                 BANKSEL         PORTD
  26.                 BSF                     SR_OUT
  27.                 NOP
  28.                 NOP
  29.                 CALL            SIGUIENTE_CLOCK_OUT
  30.                 GOTO            COMPRUEBA              
  31.         ;---------------------------------     
  32. COMPRUEBA
  33.                 BANKSEL         N_BUTTON
  34.                 MOVLW           NUMERO_DE_ENTRADAS      ;segun el nº de registros de desplazamiento
  35.                 MOVWF           N_BUTTON
  36. DESCONTANDO_BUTTON
  37.                 DECFSZ          N_BUTTON,F                      ;VA DESCONTANDO Y TESTEANDO
  38.                 GOTO            MENOS_UNO                       ; HASTA QUE LLEGA A CERO,O
  39.                 GOTO            TECLADO                         ;QUE SALTE A LA SIGUIETE COLUMNA
  40. MENOS_UNO
  41.                 CALL            RECARGA                         ;PONE EL DATO EN LA ENTRADA SR_IN
  42.                 BTFSC           SR_IN                           ;SI CONTINUA A CERO LA ENTRADA ESTA PULSADO Y EL PROGAMA SALTA
  43.                 GOTO            DESCONTANDO_BUTTON      ;SI NO PASA AL SIGUIENTE BOTON 
  44. BOTON_PULSADO
  45.                 CALL            DEMORA_5MS                      ;SI FUE PULSADO HACE UNA PAUSA
  46.                 CALL            RECARGA                         ;PONE EL DATO EN LA SR_IN
  47.                 BTFSC           SR_IN                           ;Y VUELVE A COMPROBAR
  48.                 GOTO            DESCONTANDO_BUTTON      ;SI ESTA EN ALTO HUBO REBOTE Y VUELVE PARA SEGUIR PASANDO ENTRADAS DEL CARRIL
  49.                 CALL            SELECCION                       ;ESTABA A NIVEL BAJO, SE GUARDA EN W EL VALOR DE LAS TABLAS
  50. ESPERA_UP
  51.                 CALL            RECARGA
  52.                 BTFSS           SR_IN
  53.                 GOTO            ESPERA_UP                       ;espera a que se levante el pulsador
  54.                 GOTO            DESCONTANDO_BUTTON      ;Y VUELVE HASTA LLEGAR A CERO QUE PASA A BUSCAR LA SIGUIENTE COLUMNA
  55.         ;-----------------------------------
  56. ;SE PODRIA PONER UNA DE LAS TABLAS CON GOTOS A MENUS SUB-INTERNOS PARA HACER MODIFICACIONES
  57. SELECCION
  58.                 MOVF            N_VECES,W                       ;SI ESTABA A 0 HACE UNA SELECCION PARA CONOCER QUE BOTON HA SIDO PULSADO
  59.                 BANKSEL         PCL
  60.                 ADDWF           PCL,F                           ;CON EL Nº DE COLUMNA
  61.                 GOTO            TABLA1
  62.                 GOTO            TABLA2
  63.                 GOTO            TABLA3
  64.                 GOTO            TABLA4
  65.                 GOTO            TABLA5
  66.                 GOTO            TABLA6
  67.                 GOTO            TABLA7
  68.                 GOTO            TABLA8
  69.                 GOTO            TABLA9
  70.                 GOTO            TABLA10        
  71.  
  72. TABLA1
  73.                 CALL            SUMA_N_BUTTON           ;Y CON EL Nº DE BOTON VUELVE CON UN VALOR DIFERENTE
  74.                 ADDWF           PCL,F                           ;SEGUN EN QUE TABLA
  75.         DT      .1,.2,.3,.4,.5,.6,.7,.8,.9
  76. TABLA2
  77.                 CALL            SUMA_N_BUTTON
  78.                 ADDWF           PCL,F
  79.         DT      .10,.11,.12,.13,.14,.15,.16,.17
  80. TABLA3
  81.                 CALL            SUMA_N_BUTTON
  82.                 ADDWF           PCL,F
  83.         DT      .18,.19,.20,.21,.22,.23,.24,.25
  84. TABLA4
  85.                 CALL            SUMA_N_BUTTON
  86.                 ADDWF           PCL,F
  87.         DT      .26,.27,.28,.29,.30,.31,.32,.33
  88. TABLA5
  89.                 CALL            SUMA_N_BUTTON
  90.                 ADDWF           PCL,F
  91.         DT      .34,.35,.36,.37,.38,.39,.40,.41
  92. TABLA6
  93.                 CALL            SUMA_N_BUTTON           ;Y CON EL Nº DE BOTON VUELVE CON UN VALOR DIFERENTE
  94.                 ADDWF           PCL,F                           ;SEGUN EN QUE TABLA
  95.         DT      .1,.2,.3,.4,.5,.6,.7,.8,.9
  96. TABLA7
  97.                 CALL            SUMA_N_BUTTON
  98.                 ADDWF           PCL,F
  99.         DT      .10,.11,.12,.13,.14,.15,.16,.17
  100. TABLA8
  101.                 CALL            SUMA_N_BUTTON
  102.                 ADDWF           PCL,F
  103.         DT      .18,.19,.20,.21,.22,.23,.24,.25
  104. TABLA9
  105.                 CALL            SUMA_N_BUTTON
  106.                 ADDWF           PCL,F
  107.         DT      .26,.27,.28,.29,.30,.31,.32,.33
  108. TABLA10
  109.                 CALL            SUMA_N_BUTTON
  110.                 ADDWF           PCL,F
  111.         DT      .34,.35,.36,.37,.38,.39,.40,.41
  112. SUMA_N_BUTTON
  113.                 BANKSEL         N_BUTTON
  114.                 MOVF            N_BUTTON,W
  115.                 BANKSEL         PCL    
  116.                 RETURN 
  117.         ;----------------------------------
  118.  
  119.  
  120. RECARGA
  121.                 BANKSEL N_BUTTON
  122.                 MOVF    N_BUTTON,W                              ;INDICA EL Nº DE BOTON
  123.                 MOVWF   N_BUTTON_CON                    ;-AL QUE SE QUIERE ACCEDER
  124.                 CALL    LATCHIN                                 ;-PONE LOS DATOS EN EL CARRIL SERIE
  125. MENOS_1                                                                
  126.                 BCF             CLOCK_IN                               
  127.                 NOP
  128.                 NOP
  129.                 NOP
  130.                 NOP
  131.                 BSF             CLOCK_IN
  132.                 NOP
  133.                 NOP
  134. DESCUENTA_3
  135.                 DECFSZ  N_BUTTON_CON,F                  ;Y DECREMENTA
  136.                 GOTO    MENOS_1                                 ;-PONIENDO UN DATO TRAS OTRO DEL CARRIL DE LOS REGISTROS EN LA SR_IN
  137.                 RETURN                                                  ;HASTA QUE LLEGA A CERO
  138.  
  139.         ;----------------------------------    
  140. SIGUIENTE_CLOCK_OUT
  141.                 BCF                     CLOCK_OUT
  142.                 NOP
  143.                 NOP
  144.                 BSF                     CLOCK_OUT
  145.                 NOP
  146.                 NOP
  147.                 CALL            LATCHOUT
  148.                 RETURN
  149.         ;-----------------------------------           
  150. LATCHOUT
  151.                 BSF                     LATCH_OUT
  152.                 NOP
  153.                 NOP
  154.                 BCF                     LATCH_OUT
  155.                 NOP
  156.                 NOP
  157.                 RETURN 
  158.         ;-----------------------------------
  159. LATCHIN
  160.                 BSF                     LATCH_IN
  161.                 NOP
  162.                 NOP
  163.                 NOP
  164.                 NOP
  165.                 BCF                     LATCH_IN
  166.                 NOP
  167.                 NOP
  168.                 RETURN
  169. ;-------------------------------------------------------------
  170. ; Generado con PDEL ver SP  r 1.0  el 22/06/2008 Hs 13:26:24
  171. ; Descripcion: Delay 25000 ciclos
  172. ;-------------------------------------------------------------
  173. DEMORA_5MS  movlw     .44       ; 1 set numero de repeticion  (B)
  174.         movwf     PDel0     ; 1 |
  175. PLoop1  movlw     .141      ; 1 set numero de repeticion  (A)
  176.         movwf     PDel1     ; 1 |
  177. PLoop2  clrwdt              ; 1 clear watchdog
  178.         decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
  179.         goto      PLoop2    ; 2 no, loop
  180.         decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
  181.         goto      PLoop1    ; 2 no, loop
  182. PDelL1  goto PDelL2         ; 2 ciclos delay
  183. PDelL2  clrwdt              ; 1 ciclo delay
  184.         return              ; 2+2 Fin.
  185. ;-------------------------------------------------------------  
  186.  
  187.  :mrgreen:
  188.  
  189. un saludo y gracias
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 14 de Diciembre de 2008, 12:33:44
Muchas gracias por tu aporte alogic.  :-/ :-/ :-/
Título: Re: Rutinas para compartir
Publicado por: sander en 13 de Febrero de 2009, 12:59:59
Aqui dejo unas rutinas para realizar una comunicacion i2c en pics que no tienen puerto MSSP.

En el siguiente codigo estan las subrutinas para realizar la comunicacion, para generar el bit
de inicio, bit de parada, escribir y leer un caracter.
Código: ASM
  1. ;*******************************************************************   
  2. ;       Rutinas para manejo del bus I2C         v1.00
  3. ;*******************************************************************   
  4.  
  5. ;*******************************************************************   
  6. ;       Se debe definir i2cDato, i2cCont e i2cFlags, dentro de i2cFlags
  7. ;       se debe definir ACK_F y S_NACK_F,
  8. ;               ACK_F = 1 si se recibio un ACK
  9. ;                         = 0 si no se recibio ACK
  10. ;               S_NACK_F = 1 si se debe enviar un NACK (para terminar recepcion)
  11. ;                                = 0 Si se debe enviar un ACK
  12. ;*******************************************************************
  13.  
  14. ;***********************        i2cStart        ***************************
  15. ;       Genera el bit de inicio, recibe SCl en bajo y se asegura que
  16. ;       SDA vaya de alto a bajo mietras SCL esta en alto
  17. ;******************************************************************
  18. i2cStart
  19.         SclLow                                          ;Nos aseguramos que SCL este en bajo
  20.         SdaHighZ                                        ;Solo si Scl esta en bajo
  21.         SclHighZ                                        ;para poder dar el bit de inicio
  22.         call            i2cDel                  ;
  23.         call            i2cDel                  ;espera
  24.         SdaLow                                          ;Damos el bit de inicio
  25.         return
  26. ;******************************************************************
  27.  
  28. ;***********************        i2cStop         ***************************
  29. ;       Genera el bit de parada, recibe SCl en bajo y se asegura que
  30. ;       SDA vaya de bajo a alto mietras SCL esta en alto
  31. ;******************************************************************
  32. i2cStop
  33.         SdaLow                                          ;Solo si Scl esta en bajo
  34.         call            i2cDel
  35.         SclHighZ                                        ;para poder dar el bit de parada
  36.         call            i2cDel
  37. i2cStopP0
  38.         SdaHighZ                                        ;Damos el bit de parada
  39.         call            i2cDel
  40.         btfss           i2cPort,Sda             ;Sda == liberado?
  41.         goto            i2cStopP0               ;No => esperamos a que se libere       
  42.         return                                          ;Si => retornamos
  43. ;******************************************************************
  44.  
  45. ;***********************        i2cTx   *******************************
  46. ;       El dato a enviar esta en WREG
  47. ;       Debe recibir SDA en bajo y SCL en alto
  48. ;       SCL termina en bajo
  49. ;******************************************************************
  50. i2cTx
  51.         movwf           i2cDato                 ;Guardamos el dato
  52.         movlw           .8
  53.         movwf           i2cCont                 ;contador en 8
  54.         SclLow                                          ;Scl en bajo para poder cambiar SDA
  55. i2cTxP0
  56.         rlf                     i2cDato,F
  57.         btfsc           STATUS,C                ;el bit a transmitir es 1?
  58.         goto            i2cTx_1                 ;Si => vamos a poner SDA en 1
  59.         SdaLow                                          ;No => ponemos SDA en 0
  60.         goto            i2cTxP1                 ;vamos a enviar pulso de reloj
  61. i2cTx_1
  62.         SdaHighZ                                        ;ponemos SDA en 1
  63.         goto            i2cTxP1                 ;vamos a enviar pulso de reloj
  64. i2cTxP1
  65.         SclHighZ                                        ;SCL en alto para que se transmita el bit
  66.         call            i2cDel                  ;
  67.         SclLow                                          ;acabamos el pulso de reloj
  68.         decfsz          i2cCont,F               ;i2cCont == 0?
  69.         goto            i2cTxP0                 ;No => continuamos transmitiendo
  70.                                                                 ;Si => debemos recibir ACK
  71.         call            i2cDel                  ;
  72.         SdaHighZ                                        ;para poder leer el bit ACK
  73.         call            i2cDel
  74.         SclHighZ                                        ;para leer ACK
  75.         call            i2cDel
  76.         btfsc           i2cPort,Sda             ;revisamos el bit recibido, es cero?
  77.         goto            i2cTx_Er                ;No => no se envio ACK
  78.         bsf                     ACK_F                   ;Si => se recibio ACK  
  79.         goto            i2cTx_X
  80. i2cTx_Er
  81.         bcf                     ACK_F                   ;No se recibio ACK
  82. i2cTx_X
  83.         SclLow                                          ;para que el esclavo libere SDA
  84.         call            i2cDel
  85.         return
  86. ;******************************************************************
  87.  
  88. ;***********************        i2cRx   *******************************
  89. ;       El dato se guarda en i2cDato
  90. ;       se utiliza la bandera S_NACK_F para indicar si se debe enviar
  91. ;       un NACK o un ACK
  92. ;       Debe recibir SCL en bajo para colocar SDA en modo entrada
  93. ;       SCL termina en bajo.
  94. ;******************************************************************
  95. i2cRx
  96.         movlw           .8
  97.         movwf           i2cCont                 ;Para controlar 8 bits
  98.         SdaHighZ                                        ;Sda como entrada para recibir
  99. i2cRxP0
  100.         call            i2cDel                  ;
  101.         SclHighZ                                        ;Pulso de reloj para recibir
  102.         bcf                     STATUS,C                ;suponemos que se recibira un cero
  103.         btfsc           i2cPort,Sda             ;Sda == 0(el esclvo envia cero)?
  104.         bsf                     STATUS,C                ;No => se recibio un 1
  105.         rlf                     i2cDato,F               ;guardamos el bit recibido
  106.         SclLow                                          ;terminamos el pulso
  107.         decfsz          i2cCont,F               ;i2cCont == 0?
  108.         goto            i2cRxP0                 ;No => seguimos recibiendo
  109.         btfsc           S_NACK_F                ;Si =>, se debe enviar NACK?
  110.         goto            i2cRxP1                 ;SI => vamos a enviar NACK
  111.         SdaLow                                          ;No => enviamos ACK
  112.         goto            i2cRx_X                 ;Vamos a salir
  113. i2cRxP1
  114.         SdaHighZ                                        ;Enviamos NACK
  115. i2cRx_X
  116.         call            i2cDel                 
  117.         SclHighZ                                        ;Pulso para enviar el ACK o NACK
  118.         call            i2cDel
  119.         SclLow                                          ;fin del pulso.
  120.         return
  121. ;******************************************************************
  122.  
  123. ;***************************    i2cDel  ***************************
  124. ;       Sirve para poder fijar la frecuencia del reloj.
  125. ;******************************************************************
  126. i2cDel
  127.         return

Esta otra rutina tiene macros para controlar las lineas SCL y SDA, ademas de que permitiria seleccionar los pines a usar para SDA y SCL

Código: ASM
  1. ;******************************************************************
  2. ;       El archivo contiene macros usadas para la comunicacion i2c, las
  3. ;       macros controlan el estado de las lineas SDA y SCL, sirven para
  4. ;       poner estas lineas en cero o en alta impedancia .
  5. ;
  6. ;       Para poner la linea en cero, primero se escribe en el pin del
  7. ;       puerto respectivo cero y luego se define la direccion del pin
  8. ;       como salida.
  9. ;
  10. ;       Para poner la linea en 1 se define el pin como
  11. ;       entrada(alta impedancia) para dejar que la resistencia de
  12. ;       Pullup lleve la linea a 1
  13. ;******************************************************************
  14.         #include        <P16F690.inc>
  15.         #DEFINE         i2cPort         PORTB
  16.         #DEFINE         i2cTris         TRISB
  17.         Sda                     EQU             0x04            ;RB4
  18.         Scl                     EQU             0x06            ;RB6
  19.  
  20. ;***********************        SdaLow  ******************************
  21. ;       Lleva la linea SDA a cero
  22. ;******************************************************************
  23. SdaLow          MACRO
  24.         bcf                     i2cPort,Sda
  25.         banksel         i2cTris
  26.         bcf                     i2cTris,Sda
  27.         banksel         i2cPort
  28.                         ENDM
  29. ;******************************************************************
  30.  
  31. ;***********************        SdaHighZ        ******************************
  32. ;       Lleva la linea SDA a 1
  33. ;******************************************************************
  34. SdaHighZ        MACRO
  35.         banksel         i2cTris
  36.         bsf                     i2cTris,Sda
  37.         banksel         i2cPort
  38.                         ENDM
  39. ;******************************************************************
  40.  
  41. ;***********************        SclLow  ******************************
  42. ;       Lleva la linea SCL a cero
  43. ;******************************************************************
  44. SclLow          MACRO
  45.         bcf                     i2cPort,Scl
  46.         banksel         i2cTris
  47.         bcf                     i2cTris,Scl
  48.         banksel         i2cPort
  49.                         ENDM
  50. ;******************************************************************
  51.  
  52. ;***********************        SclHighZ        ******************************
  53. ;       Lleva la linea SCL a 1
  54. ;******************************************************************
  55. SclHighZ        MACRO
  56.         banksel         i2cTris
  57.         bsf                     i2cTris,Scl
  58.         banksel         i2cPort
  59.                         ENDM
  60. ;******************************************************************

En este topico (http://www.todopic.com.ar/foros/index.php?topic=24397.msg202304#msg202304) puse un ejemplo que utiliza estas rutinas

Saludos
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 13 de Febrero de 2009, 14:32:04
Gracias Sander, sin dudas nos ahorraste varios dolores de cabeza.  :-/ :-/
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 17 de Marzo de 2009, 05:33:50
hola, ayer estuve media tarde intentando exponeros unas dudas, y al final me las explique a mi mismo  :-) :-) os iba a preguntar a ver si me podiais ayudar a resolver el pequeño problemilla que se ve en este video, eiii con video y todo, mirad si me estuve comiendo la olla durante unos dias de como solucionarlo
no solo no encendia ese, si no muchos, pero güeno; al final he encontrado muchas formas de hacer efectos de luces y dejar colgado en loops sin retolno al pic :P
pero ya funciona y que mejor que dejaros unas rutinicas para usar, los displays y leds se refrescan con el tmr0 conectados con 74595 y los steps con el tmr2, regula la velocidad con un pote conectado a un canal del cad, las rutinas del cad, de los registros y de la eeprom estan en un post anterior
configuracion de los perif. e interrupciones tmr0 y tmr2
Código: ASM
  1. CBLOCK  0XA0
  2.                         LECTOR_STEP
  3.                         DEC_STEP
  4.                         PISTA2
  5.                         PISTA1
  6.                         CANALES
  7.                         N_STEPS                         ;PUNTERO DEL NUMERO DE STEPS QUE LLEVA EL SECUENCIADOR
  8.                         ENDC
  9.  
  10. #DEFINE         BPM_POTE        (REG_POTEX+.4)   ;para probar se puede poner la direccion de un registro
  11. #DEFINE         N_STEPS_REGISTER                                .16 ;por que es de 16 pasos
  12.  
  13. CONFIG_OPTION_REG
  14.                 BANKSEL OPTION_REG
  15.                 MOVLW   B'11000111'             ;BIT5 A 1; EL TMR0 ESTA SINCRONIZADO EXTERNO POR RA4 ASCENDENTE CON UN PREESCALER DE 1/256
  16.                 MOVWF   OPTION_REG
  17.  
  18. CONFIG_T2CON
  19.                 BANKSEL T2CON
  20.                 MOVLW   B'01001100'             ;7:             NO IMPLEMENTADO
  21.                 MOVWF   T2CON                   ;6-3:   POSTDIVISOR DEL TIMER2
  22.                                                                 ;2:             1=ON 0=OFF ENCIENDE O APAGA EL TEMPORIZADOR
  23.                                                                 ;1-0:   PREDIVISOR DEL TIMER2
  24. CONFIG_INTERRUPTS
  25.                 CLRF    PIE2
  26.                 BANKSEL PIE1
  27.                 MOVLW   B'00000010'
  28.                 movwf   PIE1
  29.                 movlw   b'10100000'             ;activation of the interrupts
  30.                 movwf   INTCON

rutina de interrupcion
Código: ASM
  1. RUTINA_DE_INTERRUPCION  MACRO
  2. ;----------------------------------RUTINA DE SERVICIO DE INTERRUPCION-RSI-------------
  3.                                 ;------------------GUARDA LA DIRECCION DONDE SALTÓ, STATUS, W....-----                
  4. INTERRUP
  5.                         MOVWF   W_TEMP                  ;guardamos W,..
  6.                         SWAPF   STATUS,W                ;le damos la vuelta a STATUS en w
  7.                         MOVWF   STATUS_TEMP             ;y lo guardamos en STATUS_TEMP
  8.                         MOVF    PCLATH,W                ;PCLATH a W
  9.                         MOVWF   PCLATH_TEMP             ;y de W a PCLATH_TEMP
  10.                         banksel FSR                             ;banco de FSR
  11.                         MOVF    FSR,W                   ;FSR a W
  12.                         MOVWF   FSR_TEMP                ;y de W a FSR_TEMP
  13.                                 ;------------------CLASIFICACION DE CUAL INTERRUPCION HA SALTADO-------
  14.                 ;       BTFSC   INTCON,INTF            
  15.                 ;       CALL    INT_RB0                
  16.                         BTFSC   LECTOR_POSICION
  17.                         CALL    SCR_DISPLAY
  18.                         BTFSC   INTCON,T0IF
  19.                         CALL    INT_TMR0
  20.                         BANKSEL PIR1
  21.                         BTFSC   PIR1,TMR2IF
  22.                         CALL    INT_TMR2
  23.                                 ;------------------------------------------------------------------------------
  24.                                 ;-----------------RECARGA LOS VALORES QUE HABIA ANTES DE LA INTERRUPCION-------
  25. FIN_INT                
  26.                         BANKSEL FSR
  27.                         MOVF    FSR_TEMP,W
  28.                         MOVWF   FSR                                                                    
  29.                         MOVF    PCLATH_TEMP,W
  30.                         MOVWF   PCLATH
  31.                         swapf   STATUS_TEMP,W
  32.                         movwf   STATUS 
  33.                 MOVF    W_TEMP,W                               
  34.                         RETFIE
  35.                 ;-------------------------------------------------------------------------------
  36. SCR_DISPLAY
  37.                         BANKSEL LECTOR
  38.                         BCF             LECTOR_POSICION         ;LO PONE A CERO PARA NO SACAR MAS LOS DATOS A LOS REG DE DESPLAZAMIENTO
  39.                         BANKSEL SEGUNDOS                        ;
  40.                         MOVF    SEGUNDOS,W                      ;PONE SEGUNDOS EN W
  41.                         CALL    B2_BCD_7_SEGMENT        ;Y LO PASA A 7 SEGMENTOS EN LOS REG DE LOS DISPLAY, EL TMR0 YA LOS SACARA PARA MOSTRARLOS
  42.                         RETURN
  43.                 ;//////////////////////////////////////////////////////////////////////////////////////////////
  44.                 ;--------------------SERVICIO DE INTERRUPCIONES---------------------------------
  45.                 ;//////////////////////////////////////////////////////////////////////////////////////////////
  46. INT_TMR0                                                        ;REFRESCA LOS DISPLAYS
  47.                         BCF             INTCON,T0IF             ;A CERO POR SOFT
  48.                         PAGESEL ENVIAR_PALABRA1
  49.                         GOTO    ENVIAR_PALABRA1 ;REFRESCA LOS DISPLAY
  50.                 ;-----------------------------------------------------------------------------------------------------
  51.                 ;-----------------------------------------------------------------------------------------------------
  52.                 ;-----------------------------------------------------------------------------------------------------
  53. INT_TMR2
  54.                         BCF             PIR1,TMR2IF             ;A CERO POR SOFT
  55.                         BANKSEL DEC_STEP
  56.                         INCFSZ  DEC_STEP                ;DECREMENTA HASTA CERO POR QUE EL TIMER VA MUY RAPIDO :o
  57.                         RETURN                                  ;SI NO ESTÁ A CERO VUELVE AL PROGRAMA
  58.                         BANKSEL REG_POTEX
  59.                         MOVF    BPM_POTE,W              ;RECOGE LA INFO DEL POTE BPM
  60.                         BANKSEL DEC_STEP
  61.                         MOVWF   DEC_STEP
  62.                         INCF    DEC_STEP                ;LE SUMA UNO PARA QUE NO SE QUEDE A CERO
  63.                         BCF             STATUS,C
  64.                         RLF             DEC_STEP
  65.                         INCF    N_STEPS                 ;INCREMENTA N_STEPS
  66.                         MOVLW   N_STEPS_REGISTER                        ;MUEVE EL NUMERO MAXIMO DE STEPS A W
  67.                         SUBWF   N_STEPS,W               ;Y LO COMPARA CON N_STEPS
  68.                         BTFSC   STATUS,C                ;SI ES MAYOR/igual N_STEPS QUE W; C = 1 ;SE PONE A UNO
  69.                         CLRF    N_STEPS                 ;POR LO QUE LIMPIA EL REGISTRO, PARA VOLVER A EMPEZAR DE 0
  70. VISUAL_STEP
  71.                         BANKSEL N_STEPS
  72.                         MOVF    N_STEPS,W
  73.                         CLRF    PISTA1
  74.                         CLRF    PISTA2                          ;LIMPIA LOS REGISTROS
  75.                         SUBLW   .7
  76.                         BTFSC   STATUS,C
  77.                         GOTO    STEP_MAS8
  78.                         BSF     STATUS,C                                ;PONE A UNO C
  79. STEP_MENOS8
  80.                         MOVF    N_STEPS,W
  81.                         CALL    STEP_TABLA
  82.                         MOVWF   PISTA1
  83.                         GOTO    STEP_EXIT
  84. STEP_MAS8
  85.                         MOVF    N_STEPS,W
  86.                         CALL    STEP_TABLA
  87.                         MOVWF   PISTA2                 
  88.                         GOTO    STEP_EXIT
  89. STEP_EXIT
  90.                         RETURN
  91. STEP_TABLA
  92.                         ADDWF   PCL,F
  93.                         DT          B'10000000',B'01000000',B'00100000',B'00010000',B'00001000',B'00000100',B'00000010',B'00000001'
  94.                         DT          B'10000000',B'01000000',B'00100000',B'00010000',B'00001000',B'00000100',B'00000010',B'00000001'
  95.  
  96. LECTURA_EEPROM_STEP                                             ;LEE EL NUMERO DE PULSADOR EN LA EEPROM SEGUN DONDE ESTE APUNTANDO EL SECUENCIADOR N_STEPS
  97.                         BANKSEL N_STEPS
  98.                         MOVF    N_STEPS,W                      
  99.                         BANKSEL EEADR
  100.                         MOVWF   EEADR                          
  101.                         MOVLW   N_REG_EEPROM_BUTONS    
  102.                         ADDWF   EEADR,F                        
  103.                         GOTO    CONTINUA_LECTURA
  104.                 ;-----------------------------------------------------------------------------------------------------
  105.                 ;-----------------------------------------------------------------------------------------------------
  106.                 ;-----------------------------------------------------------------------------------------------------                 
  107.  
  108.                         ENDM
este es el ejemplo de como uso yo las rutinas para sacar los datos a los led con los registros de desplazamiento, en la CALL SCR_DISPLAY vereis que si en vez de sacar a los displays el valor de los potes quiero sacar el del registro SEGUNDOS lo cargo en w, se llama a B2_BCD_7_SEGMENT que lo pasa a numeros y lo coloca en los registros reservados para los 74595 que el tmr0 ya llamara a la rutina para sacarlos
esto habria de añadirse a la macro OUT_SHIFT_REGISTER
Código: ASM
  1. ENVIAR_PALABRA1                                                         ;ENVIA LO QUE HAYA EN LSD,MSD,CENT
  2.                         CALL    ENVIA_TEXTOS
  3.                         CALL    DISPLAY_SEC    
  4.                         MOVF    CANALES,W
  5.                         CALL    LETRA
  6.                         CALL    DISPLAY_SEC                            
  7.                         MOVF    PISTA2,W                        ;LEDS SECUENCIADOR 1
  8.                         CALL    LETRA                           ;PONE EN EL SIGUIENTE DISPLAY LO QUE HAYA EN W
  9.                         CALL    DISPLAY_SEC
  10.                         MOVF    PISTA1,W                        ;LEDS SECUENCIADOR 2
  11.                         CALL    LETRA                           ;PONE EN EL SIGUIENTE DISPLAY LO QUE HAYA EN W
  12.                         CALL    LATCH                           ;LACHEA LOS DATOS DEL CARRIL SERIE DE LOS REGISTROS, A LAS SALIDAS PARALELO
  13.                         PAGESEL INT_TMR0
  14.                         RETURN
  15.        
  16. DISPLAY_SEC
  17.                         BANKSEL N_DIGITOS
  18.                         MOVLW   .1
  19.                         MOVWF   N_DIGITOS
  20.                         BANKSEL PISTA1 
  21.                         RETURN
un saludo

Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 18 de Marzo de 2009, 10:38:03
 :-/ :-/ :-/ :-/
Título: 12f675 ADC con salida onda cuadrada
Publicado por: pibe en 25 de Marzo de 2009, 11:09:27
A veces necesitamos tener una salida con onda cuadrada para dimear un led, dar un tren de pulsos, etc etc pero queremos algo que podamos graduarlo con un potenciómetro

Se me presentó este problema al tener un solo pulso de entrada y debia tener una salida fija , pero también necesitaba la misma sallida pulsante.
Pues al pulsar 1 vez tenemos la salida fija, y al soltar y si dentro de 500ms volvemos a pulsar tenemos la salida con onda cuadrada.
Es así como lo he solucionado:



Código: [Seleccionar]
list      p=12f675           ; list directive to define processor
#include <p12f675.inc>        ; processor specific variable definitions

__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.




;***** VARIABLE DEFINITIONS
Cblock 0x20
PDel0
PDel1
PDel2
PDel3
FLAG
w_temp             ; variable used for context saving
status_temp         ; variable used for context saving
timer1,timer2,timer3
endc

#define toggle   FLAG,0
#define PULS GPIO,5
#define RL1 GPIO,4






;**********************************************************************
ORG     0x000             ; processor reset vector
goto    Inicio              ; go to beginning of program





; these first 4 instructions are not required if the internal oscillator is not used
Inicio
call    0x3FF             ; retrieve factory calibration value
bsf     STATUS,RP0        ; set file register bank to 1
movwf   OSCCAL            ; update register with factory cal value
bcf     STATUS,RP0        ; set file register bank to 0

CLRF GPIO ;Init GPIO
MOVLW 07h ;Set GP<2:0> to
MOVWF CMCON ;digital IO

BSF STATUS,RP0 ;Bank 1
movlw 0
movwf OPTION_REG;habilitacion pullups
movwf IOC ;deshabilitar int por cambio puertos
movwf WPU
; bsf   WPU,5 ;todas pullups deshabilitadas excepto GP5 entrada pulsador
movlw b'00110001'; FRC, AD en GP0, left justif. Leemos el ADRESH para la conversión 8 bits
movwf ANSEL ;
MOVLW b'11101101';GP0= AD IN, GP4 Relay out, GP5 pulsador in
MOVWF TRISIO ;
BCF STATUS,RP0 ;Bank 0

call delay500

main
bcf toggle
bcf RL1



test_puls1
btfsc PULS
goto main
call delay20
bsf RL1




test_puls2
btfsc PULS
goto test500 ;ha dejado de pulsar por 500ms?
goto test_puls2

test500
bcf RL1
call delay500
btfsc PULS
goto main
son2
call delay20



bsf ADCON0,ADON

start

bsf ADCON0,GO
waiting
btfsc ADCON0,GO
goto waiting

start2

movf ADRESH,W
movwf timer1
movwf timer2
start3
bsf RL1 ;turn on

call DEMORA
decfsz timer1,1
goto start3
pause1
bcf RL1
CALL DEMORA
decfsz timer2,1
goto pause1

test_puls3
btfss PULS
goto start
bcf ADCON0,ADON
goto main







delay500
movlw     .239      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .232      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  goto PDelL3         ; 2 ciclos delay
PDelL3  clrwdt              ; 1 ciclo delay
        decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  goto PDelL6         ; 2 ciclos delay
PDelL6  goto PDelL7         ; 2 ciclos delay
PDelL7  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


DEMORA  movlw     .80       ; 1 set numero de repeticion
        movwf     PDel0     ; 1 |
PLoop50  clrwdt              ; 1 clear watchdog
        decfsz    PDel0, 1  ; 1 + (1) es el tiempo 0  ?
        goto      PLoop50    ; 2 no, loop
        clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


delay20  movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop10  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop20  clrwdt              ; 1 clear watchdog
        decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop20    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop10    ; 2 no, loop
PDelL10  goto PDelL20         ; 2 ciclos delay
PDelL20  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.



END                       ; directive 'end of program'


He usado un pote de 10k con extremos entre masa y +5v y su punto medio a GP0, salida por GP4 y pulso a masa por GP5.
Al graduar el pote varía el ADRESH (of course  :mrgreen:) y lo cargo en un contador timer1 para el pulso en 1
 y en un cntador timer2 para el pulso en 0 .
Luego pequeña pausita de unos 320us hasta agotar el timer1
La misma pausita de 320us hasta agotar el timer2 pero esta vez para mantenerlo en 0
Miro que no suelten el pulsador y sino vuelvo a repetir la cadena, logrando una salida de onda cuadrada graduable en frecuencia.
Claro que es totalmente configurable en frecuencia variando el la tensión de entrada o simplemente utilizando la pausita de distinta duración.

Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 18 de Abril de 2009, 03:25:40
Continuando con las operaciones matemáticas, subo la que faltaba para completar las 4 operaciones básicas de las matemáticas, se trata de la división.

Esta rutina es para dividir 32 bit con otro valor de 32 bit y como resultato puede llegar a dar otro valor de 32 bit. La ventaja de esta rutina es que además se puede dividir en dividendo de 32 bit por un divisor de 32 bit o menos.

Esta rutina tiende 2 grandes desventajas, la primera no es nada eficiente, consume muchos ciclos de máquina y como una segunda desventajas, consume 21 posiciones de la RAM (pero cuando no se usa la división ni la resta, se pueden usar para otra cosa, la ventaja es que comparten la RAM con la resta).
Como ventaja principal, no consume casi nada de memoria de programa, por lo que si andamos justo de memoria y no necesitamos rapidez, esta rutina es la indicada.
Título: Re: Rutinas para compartir
Publicado por: Suky en 17 de Mayo de 2009, 15:51:42
Título: Re: Rutinas para compartir
Publicado por: jim_17 en 02 de Julio de 2009, 21:40:42
Me gustan mucho esas rutinas, pero yo creo que siempre es mejor que uno mismo se rompa un poco el coco y cada uno intente entenderlas o crearlas por uno mismo yo aporto una idea que he pensado por si alguien tiene que hacer una multiplicación o división en lenguaje ensamblador.

Yo voy a dar una pista para que uno mismo puedas crear la rutina.

Si quieres multiplicar 2*5 lo puedes hacer de dos maneras:

1º) Directamente como ya nos sabemos las tablas de multiplicar pues 2*5=10 (en ensamblador no puedes utilizar este recurso y tendrás que utilizar la 2a opción).

2º) De pequeños cuando no sabes multiplicar te enseñan que es multiplicar, multiplicar es sumar un numero X veces, por ejemplo 2*5 es igual a sumar el numero 2, cinco veces o sumar el numero 5, dos veces 2*5=2+2+2+2+2=5+5

Ahora para dividir debemos hacerlo de otra manera si queremos dividir el numero 10 entre 2 personas y queremos saber qué numero da devemos hacer lo siguiente, son matemáticas puras y duras.

10=2+2+2+2+2, entonces igualamos la ecuación hacia el otro lado 10-2-2-2-2-2=0, directamente ya sabemos que 10/2 da 5, y si miramos la equación vemos que el 2 pasa a restar 5 veces

entonces una rutina para dividir seria la siguiente: (no lo hago en ensamblador, solo es para dar una idea)

Dividendo: 10
Divisor: 2
-------------------
dividendo-divisor, el resultado es 0 ? (NO) 10-2 = 8 Guardamos el resultado en dividendo
sumamos 1 al registro cociente. (1)
dividendo-divisor, el resultado es 0? (NO) 8-2 = 6 Guardamos el resultado en dividendo
sumamos 1 al registro cociente. (2)
dividendo-divisor, el resultado es 0? (NO) 6-2=4 Guardamos el resultado en dividendo
sumamos 1 al registro cociente. (3)
dividendo-divisor, el resultado es 0? (NO) 4-2=2 Guardamos el resultado en dividendo
sumamos 1 al registro cociente. (4)
dividendo-divisor, el resultado es 0? (Si) 2-2=0 Guardamos el resultado en dividendo
Saltamos de linea y sumamos 1 al registro cociente. (5)
---------------------------------------------

Es una idea que me ha revivido al ver el hilo, espero no desviar el tema del hilo.






Salu2.




Título: Re: Rutinas para compartir
Publicado por: Suky en 02 de Julio de 2009, 21:47:27
Esta muy bien lo que dices jim_17. Pero muchas veces eso es perder el tiempo sin razón, ya que lo importante del programa se basa en otras cosas y esto son complementos, nada más. :wink:
Título: Re: Rutinas para compartir
Publicado por: jim_17 en 03 de Julio de 2009, 11:01:01
Ya lo sé, no digo que esas rutinas no sirvan para nada, te facilitan la faena, pero mi opinión es que la primera vez, siempre es mejor tender a crearla tu mismo (ya que no son muy complejas) o entenderlas. Todos sabemos que las cosas aprendidas mecánicamente no sirven para nada, siempre es mejor entender el concepto y luego aplicarlo. :-/

Lo expuesto era una idea que me vino a la cabeza y no quería dejarlo ahí, no se quería compartirlo con los demás. :D


Salu2.
Título: Re: Rutinas para compartir
Publicado por: Suky en 03 de Julio de 2009, 11:12:02
 :D  :D Por eso dije que esta muy bien lo expuesto! Pero mi di mi opinión al respecto.  :mrgreen:
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 03 de Julio de 2009, 15:21:05
Para ser sincero, muchos se pasan al C, al BASIC porque muchos problemas están resueltos, como por ejemplo, multiplicar, dividir, comunicación RS232, USB y muchos etc. Con ese criterio, todos deberíamos quedarnos con el ASM.

Entiendo muy bien tu punto de vista, y si es necesario saber porque se hace de esa manera las cosas pero muchas veces nos juega en contra.
Por ejemplo, la rutina que subí de división, está echa de la manera que vos explicaste, y si te das cuenta, no es nada eficiente. Un mismo proceso que le estoy haciendo hacer al PIC con la rutina de dividir, tardó más de 20 minutos (medidos con el watchclock del MPLAB) y con la rutina que subió SUKY tardó poco más de 1 segundo.

De echo, la rutina de suky tuve que modificarla porque no dividía la cantidad de dígitos que yo necesitaba, así que me vi a la obligación de estudiar como funciona y la modificación fue muy sencilla.

Aprovecho para darte las gracias SUky  :-/ :-/ :-/
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 04 de Julio de 2009, 06:32:28
hola, yo estoy deacuerdo con Leon, si tuviesemos una libreria tan amplia y bien echa como el c o basic... no acabariamos a veces "clrf cerebro" en mi humilde opinion.  esta muy bien la iniciativa de explicar como funciona, pero pienso que un ejemplo, vale mas que 1000les de palabras, y si ademas lleva explicacion, olE¡¡ por lo menos para mi que soy duro de mollera  :mrgreen:
 traduccion del 16f876 datasheet  (http://www.4shared.com/account/file/105492464/fb10b85b/Manual_PIC16F876.html) espero os sirva

un saludo
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 05 de Julio de 2009, 00:19:53
Me parece muy bien que tengas otro punto de vista  :-/ Lo que no te logro entender es esta frase: (debe ser por la hora y porque tengo mucho sueño)

si tuviesemos una libreria tan amplia y bien echa como el c o basic... no acabariamos a veces "clrf cerebro" en mi humilde opinion. 
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 05 de Julio de 2009, 05:45:23
pues eso, estas  :ni) clrf cerebro  :D, que si tuviesemos librerias de todo, no nos pasariamos al c, basic... en un futuro, o a lo mejor no es necesario y se puede seguir con asm. pero efectivamente creo que es la causa de que la gente opte por otro tipo de lenguaje
 en lo que me gusta a mi, sonido, midi... y esas cosillas que por aqui no gustan nada  :mrgreen: casi todos utilizan arduino (pduaj), dicen solo por el lenguaje, (siempre me lo intentan comparar con los pic. :shock: arduino esto si, aquello tambien, pic de eso nada...) y hay que verles la cara cuando ven un programa en assembler, parece les diera miedo u algo asi :evil:. tan complicado es :huh: o tan facil son los otros

un saludo
Título: Re: Rutinas para compartir
Publicado por: tapi8 en 05 de Julio de 2009, 05:52:36
Alogic_on muy bueno el data del 16f876, si tienes mas subelos  :P
Respecto de esta discusion yo, personalmente, creo que todo lo que tengamos ya hecho ( rutinas, librerias, etc ) vienen muy bien, porque si ya de por si porogramar en ensamblador es mas lento y tedioso que en C o basic, tener estas rutinas y librerias, hace que el ensamblador tenga menos desventajas a la hora de programar, al igual que los programas para calcular delays etc. Pero es bueno entenderlas porque hay veces que tal y como estan no te sirven y si tienes que adaptarlas a tu programa, si no sabes como funcionan no podras hacerlo.

tapi8
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 05 de Julio de 2009, 06:29:54
pues eso, estas  :ni) clrf cerebro  :D, que si tuviesemos librerias de todo, no nos pasariamos al c, basic... en un futuro, o a lo mejor no es necesario y se puede seguir con asm. pero efectivamente creo que es la causa de que la gente opte por otro tipo de lenguaje
 en lo que me gusta a mi, sonido, midi... y esas cosillas que por aqui no gustan nada  :mrgreen: casi todos utilizan arduino (pduaj), dicen solo por el lenguaje, (siempre me lo intentan comparar con los pic. :shock: arduino esto si, aquello tambien, pic de eso nada...) y hay que verles la cara cuando ven un programa en assembler, parece les diera miedo u algo asi :evil:. tan complicado es :huh: o tan facil son los otros

un saludo
Pero Alogic, entonces estás de acuerdo conmigo. Tal vez yo me expresé mal. Me refiero a lo mismo que tu dice.
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 05 de Julio de 2009, 14:21:23
 sigues  :ni) adormilao  :D, lo mismo que tu  8)
Citar
Para ser sincero, muchos se pasan al C, al BASIC porque muchos problemas están resueltos, como por ejemplo, multiplicar, dividir, comunicación RS232, USB y muchos etc
mas menos lo mismo ;)

Citar
Alogic_on muy bueno el data del 16f876, si tienes mas subelos

ojala tuviese mas como ese, a mi me llamo la atencion sobre todo el capitulo del i2c, creo que hasta lo voy entendiendo  :mrgreen: de todas formas cada uno tendra algun datasheet o tutoriales de mplab u otros que tengan que ver, quien sabe
Citar
hay veces que tal y como estan no te sirven y si tienes que adaptarlas a tu programa, si no sabes como funcionan no podras hacerlo.
yo creo que mas que tener que adaptarlas a nuestros programas las usamos de ejemplo para desarrollar y entender lo que necesitamos, aunque a veces coincida con lo que queremos, pero ya sea estudiandolas o solo copiando/pegando algo seguro que se aprende

un saludo
Título: Re: Rutinas para compartir
Publicado por: bigluis en 07 de Julio de 2009, 02:41:03
Me gustaria saber si se pueden utilizar las subrutinas del c que trae el mplab en archivos asambler. Para asi evitarnos estar haciendo nuestras propias rutinas.
Título: Re: Rutinas para compartir
Publicado por: tapi8 en 07 de Julio de 2009, 11:48:45
Citar

A mi me llamo la atencion lo bien traducido que esta, es muy raro ver un texto tecnico tan bien traducido, y despues de ver tantas traducciones automaticas es para alucinar  :P.

Es una pena que con tanta informacion como tenemos de esta serie 16f87X nos la quiten

tapi8
Título: Re: Rutinas para compartir
Publicado por: jhozate en 07 de Julio de 2009, 16:10:28
van a quiitar la serie 16F87X??? :shock: :? y porque???
Título: Re: Rutinas para compartir
Publicado por: tapi8 en 07 de Julio de 2009, 18:11:34
Si hozate si miras en las hojas de microchip veras que solo aparece en productos maduros y la sustituyen por la serie 16f88X que hay que reconocer que es mejor y a mitad de precio, pero Alogic_on creo que no tiene "datas" traducidos  :( :lol: mala suerte

tapi8
Título: Re: Rutinas para compartir
Publicado por: BrunoF en 08 de Julio de 2009, 21:06:23
Bueno, dejo esta rutina que acabo de hacer como desafío personal para ver cuál era la manera más fácil y rápida para detectar una tecla presionada de un teclado 4x4(podria modificarse para teclados de menor tamaño facilmente):

Requerimientos:

Observaciones:

Código: ASM
  1. ;Función para leer un teclado en el PORTB[C3 C2 C1 C0 F3 F2 F1 F0] by BrunoF. http://www.todopic.com.ar/foros
  2. ;El TRISB debe haber sido seteado previamente al valor 0xF0;
  3. ;Si el uC posee weak pullups en el puertob[4.7] deben ser activadas. Caso contrario deberá colocarse una pullup por Columna del teclado.
  4.  
  5. LEE_TECLADO     movlw   b'11111110'             ;Fila 0
  6.                 movwf   PORTB
  7.                 nop                             ;dar tiempo a que se efectivicen los cambios
  8.                 xorwf   PORTB,W                 ;comparar buscando diferencias
  9.                 btfss   STATUS,Z                ;Ninguna tecla presionada?
  10.                 goto    Encontrada              ;Hay tecla presionada
  11.  
  12.                 movlw   b'11111101'             ;Fila 1
  13.                 movwf   PORTB
  14.                 nop                             ;dar tiempo a que se efectivicen los cambios
  15.                 xorwf   PORTB,W                 ;comparar buscando diferencias
  16.                 btfss   STATUS,Z                ;Ninguna tecla presionada?
  17.                 goto    Encontrada              ;Hay tecla presionada
  18.  
  19.                 movlw   b'11111011'             ;Fila 2
  20.                 movwf   PORTB
  21.                 nop                             ;dar tiempo a que se efectivicen los cambios
  22.                 xorwf   PORTB,W                 ;comparar buscando diferencias
  23.                 btfss   STATUS,Z                ;Ninguna tecla presionada?
  24.                 goto    Encontrada              ;Hay tecla presionada
  25.  
  26.                 movlw   b'11110111'             ;Fila 3
  27.                 movwf   PORTB
  28.                 nop                             ;dar tiempo a que se efectivicen los cambios
  29.                 xorwf   PORTB,W                 ;comparar buscando diferencias
  30.                 btfss   STATUS,Z                ;Ninguna tecla presionada?
  31.                 goto    Encontrada              ;Hay tecla presionada
  32.  
  33.                 movlw   0xF0
  34.                 movwf   PORTB                   ;dejar preparadas las entradas para interrupcion
  35.                 retlw   0xFF                    ;volver indicando que no hay tecla presionada(W=255)
  36. Encontrada
  37.                 comf    PORTB,W                 ;acomodar valor...
  38.                 addlw   0x11
  39.                 bcf     PORTB,0                 ;dejar preparadas las entradas para interrupcion SIN AFECTAR A W
  40.                 bcf     PORTB,1
  41.                 bcf     PORTB,2
  42.                 bcf     PORTB,3
  43.                 return                          ;volver con W=Nro tecla presionada [0,15]

El esquema de conexión:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=23812.0;attach=9584)

Saludos.
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 09 de Julio de 2009, 05:23:14
veis a que me refiero, por ej te pueden contar la teoria un millon de veces, pero llega en este caso BrunoF... y a mi casi siempre me cambia la forma de ver las cosas. ahora mismo ya estoy dandole vueltas a esa
una preguntica, BrunoF?? si no es mucha indicrecion  :mrgreen: cuanto tiempo llevas programando en ensamblador (segun lo que me respondas me tiro al pozo :D)

respecto a lo de que desaparezca la serie 16f87x creo recordar en el foro tecnico (no lo encuentro, puede ser mi imaginacion) que iban a sacar la serie mejorada, pero buscando encontre este otro de Bruno Saravia (http://www.todopic.com.ar/foros/index.php?topic=25963.0) en el que habla del seminario de microchip en argentina y dice esto
Citar
... presentar brevemente las características sobresalientes de la Arquitectura PIC Linea Media Mejorada, integrada por los PIC16F1XXX y PIC12F1XXXX que se caracterizan por ampliar la capacidad de los PIC Linea Media y el Set de Instrucciones, luego haré un informe especial sobre los mismos...
habria que plantearse probarlos, la puñeta es en mi caso la de siempre, la informacion, no me entero con el ingles, asi que ya saben a ver cuando empiezan a sacar los datas traducidos estos de uC. que somos muchos los que estamos varados  :8} :8}

un saludo
Título: Re: Rutinas para compartir
Publicado por: tapi8 en 09 de Julio de 2009, 07:19:31
Si Aalogic_on Bruno siempre nos da sorpresas agradables, no te desesperes si no llegas aser tan bueno como el, da la impresion de que hay una escuela Argentina de programadores en asembler no? muy buena ademas.
Acabo de mirar las novedades de Microchip:


                       precio      osc_interno      memoria     pines I/O

16f877            $4.26          NO                   8K             33
16F876           $3.90          NO                    8K             2

16F886            $1.49        8Mz                     8k            25
16f887            $1.78         8Mz                     8k           36

16f1934            $1.47       32Mz                    4k             36
16f1936           $1.30       32                        8K             25
16F1937           $1.54       32                        8K            36

De momento son los tres que hay en produccion, la serie incluira uno de 64 pines y 54 I/O con 16Kwords, la llevan promtiendo desde finales del año pasado, les debe estar dando algun problemilla.
Hay que reconocer que la 16f88x es mejor que la 87x pero me pasa como a ti Alogic_on, el tener que aprenderlo en ingles me jode mucho.

tapi8
Título: Re: Rutinas para compartir
Publicado por: BrunoF en 09 de Julio de 2009, 16:30:15
veis a que me refiero, por ej te pueden contar la teoria un millon de veces, pero llega en este caso BrunoF... y a mi casi siempre me cambia la forma de ver las cosas. ahora mismo ya estoy dandole vueltas a esa
una preguntica, BrunoF?? si no es mucha indicrecion  :mrgreen: cuanto tiempo llevas programando en ensamblador (segun lo que me respondas me tiro al pozo :D)

No hay problema en preguntar eso. No debes tirarte a ningún pozo. La primera vez que intenté programar una bendita línea en asm fue en Marzo de 2003. Para ese entonces ya había aprendido Pascal y algo de Java en la Universidad. También programaba en Basic y VB, pero los aprendí por mi cuenta a temprana edad.

Estaban dando un curso de uC PIC en la Universidad de Ingeniería y me anoté. Fuí a las clases pero creo que no lo tomé mucho en serio. "No di pie con bola", es decir, no logré entender nada. Ahora me doy cuenta que el error no era solo mío sino de los profesores también que intentaban explicar todo en poco tiempo(1 clase de 2 horas por semana, durante 16 semanas) y de manera errónea(porque todavía andan dando vueltas sus apuntes y al mirarlos son desastrosos).
Abandoné el curso casi cuando estaba por terminar porque ya no podía seguir las clases y no tenía sentido seguir haciendolo...

Comence a revolver cielo y tierra para conseguir un libro que pudiese ayudarme a programar uCs PIC en asm. No sería fácil tarea pero me conseguí uno prestado(que jamás habían leído) y empece a leer. Otra vez era chino básico.Venía medianamente legible el texto hasta que te topabas con el código asm: te mostraban las instrucciones para cómo hacer para saber si A=B, A<B o A>B, indicandote que revisaras los flags Z y C pero no te decía en ningún momento por qué había que revisar esos flags. Claro! yo como loco porque parecía que el uC más que lindo era mágico. Las cosas sucedían milagrosamente sin saber el ¿por qué? de las mísmas.

Construí el programador NOPPP. Me bajé el MPLAB e intenté grabar uno de los programitas que había aprendido en el curso. Frustrante. Lograba ensamblarlo(copiando fielmente de mis apuntes, sin lograr modificar nada...) pero no lograba grabarlos con el NOPPP. Sólo logré quemar 2 16F84...costaban más de 15 dólares cada uno, y yo no tenía una moneda...fué frustrante y abandoné todo.

En el 2004, mi papá comienza con un microemprendimiento en el cual necesitaba una alarma perimetral. Vuelvo a la carga para intentar ayudarlo. Esta vez busco a ver si exíste algo ya hecho. Revolviendo la web encuentro una alarma (http://jap.hu/electronic/combination_lock.html) hecha por Peter Jakab (http://jap.hu). Comienzo a intentar modificarla. Esta vez, no recurro a ningún libro. Bajo el datasheet del 16F84 y lo leo hasta el hartazgo. Intento aprender todas las instrucciones disponibles del uC. No logro obviamente asociarlas o combinarlas para lograr algoritmos complejos, pero de a poco comienzo a entender "algo". Pregunto a Peter(a quien le he agradecido y le sigo agradeciendo) ciertas dudas que me surgen. En menos de 2 meses de haber retomado, estaba modificando y creando mi propio código. Modifiqué su diseño de alarma para que le sirviera a mi papá y la publiqué en mi difunta página web(http://ar.geocities.com/brunodini/Alarma.htm).

A partir de allí todo se tornó mucho más fácil. Comencé a estudiar a fondo cada registro del uC. Comencé a desarrollar algoritmos que realizacen funciones complejas en pocas líneas de código. Me enamoré perdidamente del potencial de las instrucciones IOR,XOR,AND yCOMF. En los años 2004,2005 y 2006 programé mucho en asm. Desde el 2007 hasta el momento, programo poco y nada uC PICs. Un pequeño porcentaje de ese poco es en asm y el resto es en CCS. El 90% del código asm que he programado desde el 2007 ha sido en respuesta, o como aporte, a este foro.

Ultimamente no programo en asm para proyectos personales porque se pierde demasiado tiempo cuando se quieren utilizar módulos avanzados del uC o se migra a familias más avanzadas, lo que no quiere decir que mi gran amor haya sido, es y será por siempre el lenguaje ensamblador...

Si Aalogic_on Bruno siempre nos da sorpresas agradables, no te desesperes si no llegas aser tan bueno como el, da la impresion de que hay una escuela Argentina de programadores en asembler no? muy buena ademas.

Por supuesto que cualquiera puede ser tan "bueno... :roll:" o mejor que yo. .No te desanimes. Me hubiese venido bien esa escuelita! ja ja ja! Realmente desconozco de escuela alguna!

Un saludo.
Título: Re: Rutinas para compartir
Publicado por: Suky en 09 de Julio de 2009, 16:35:31
  :shock: :rolleyes: Que el hilo no pierda su tema principal. Leer las reglas del Foro  :mrgreen:
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 10 de Julio de 2009, 03:13:13
Por supuesto que cualquiera puede ser tan "bueno... :roll:" o mejor que yo. .No te desanimes.
Si Aalogic_on Bruno siempre nos da sorpresas agradables, no te desesperes si no llegas aser tan bueno como el
jej que es coña, soy mucho mas cabezota y para desanimarme vais a necesitar algo mas  :D n veas si me queda por seguiros dando el peñaso por aqui con mis electrotrastornos  :D :D
  :shock: :rolleyes: Que el hilo no pierda su tema principal. Leer las reglas del Foro  :mrgreen:
traaaaaanki  :D :D que no lo pierde
 tenemos rutinas para matematicas X : + -...., tambien IIC, ADC,eeprom.... que nos falta para cubrir rutinas para compartir, así a ojo de buen cubero.... usart,  modulo comparador de las tres formas, escribir leer en la flash y perifericos que podriamos ir añadiendo un larguisimo etc luego subo alguna para no perder el hilo Suky  :D

un saludo
Título: Re: Rutinas para compartir
Publicado por: Suky en 10 de Julio de 2009, 09:36:36
 :shock: :rolleyes: Que el hilo no pierda su tema principal. Leer las reglas del Foro  :mrgreen:
traaaaaanki  :D :D que no lo pierde
 tenemos rutinas para matematicas X : + -...., tambien IIC, ADC,eeprom.... que nos falta para cubrir rutinas para compartir, así a ojo de buen cubero.... usart,  modulo comparador de las tres formas, escribir leer en la flash y perifericos que podriamos ir añadiendo un larguisimo etc luego subo alguna para no perder el hilo Suky  :D

un saludo
Mejor que así sea!   :?
:D  :D  :D
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 30 de Agosto de 2009, 16:07:53
bueno no es que sea mucho, pero se me ocurrio que porqué estar calculando el valor del registro spbrg, para configurar la usart. si el mplab lo hace por nosotros  :mrgreen:
para calcular el Baud rate tenemos la famosa formula
;  Baud Rate=Fosc/(16(X+1)) para (Higth Speed) en modo Asincrono
;  Baud Rate=Fosc/(64(X+1)) para (Low Speed)   en modo Asincrono


despejamos la X que se queda asi
;  X = (Baud_rate / (Fosc * 16) ) - 1
u asi
;  X = (Baud_rate / (Fosc * 64) ) - 1

con lo que ponemos en el mplab asin
Código: ASM
  1. ;AUTO_CALC SPBRG
  2. #DEFINE BAUD_RATE       .31250
  3. #DEFINE Fosc            .20000000
  4. #DEFINE H_L_SPEED       'L'     ;Ó 'H'         ;64 o 16 SEGUN SEA ALTA O BAJA VELOCIDAD
  5.  
  6.         IF      H_L_SPEED=='L'
  7.                 MOVLW (Fosc / (BAUD_RATE * .64) ) - .1
  8.         ENDIF
  9.         IF      H_L_SPEED=='H'
  10.                 MOVLW   (Fosc / (BAUD_RATE * .16) ) - .1
  11.         ENDIF
  12.         MOVWF   SPBRG
  13. ;aparte el bit BRGH
  14.         IF      H_L_SPEED=='H'
  15.                 BCF             TXSTA,BRGH              ;BAJA VELOCIDAD DE TRANSMISION
  16.         ENDIF
  17.         IF      H_L_SPEED=='L'
  18.                 BSF             TXSTA,BRGH              ;ALTA VELOCIDAD DE TRANSMISION
  19.         ENDIF
en mi caso. a 31250 bauds, Fosc 20.000.000 en modo baja velocidad da .9  :mrgreen: clavao
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 30 de Agosto de 2009, 19:19:28
¡Uy! me viene como anillo al dedo.
Es unos días retomo mi proyecto y voy a experimentar con esto.
Título: Re: Rutinas para compartir
Publicado por: bigluis en 14 de Septiembre de 2009, 03:02:59
Acabo de conceguir todas las rutinas del libro "Microcontrolador 16F84 Desarrollo de proyectos" y me gustaria saber si no es contra las reglas del foro subirlas debido a los derechos de autor.
Título: Re: Rutinas para compartir
Publicado por: migsantiago en 14 de Septiembre de 2009, 12:54:07
El libro tiene copyright y no se deben publicar tales contenidos en el foro.
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 20 de Octubre de 2009, 19:59:46
Comunicación USART entre dos pic en forma unidireccional (una sola dirección).
9 bit paridad par.

Tx. Ejemplo de utilización.

Código: [Seleccionar]
LIST P=16F877A
INCLUDE <P16F877A.INC>
__CONFIG _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _BODEN_OFF & _LVP_OFF & _WRT_OFF
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
CBLOCK H'20'
dato_enviar
dato_enviar_temp
contador
cont_bit
ENDC
;
RESET ORG H'00'
GOTO INICIO
ORG H'04' ;VECTOR INTERRUPCIÓN
;
#INCLUDE USART_TX.INC
INICIO
;
BCF STATUS,RP0
BCF STATUS,RP1 ;BANCO 0
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE
BSF STATUS,RP0 ;BANCO 1
CLRF TRISA
MOVLW H'FF'
MOVWF TRISB
CLRF TRISC
CLRF TRISD
CLRF TRISE
MOVLW 0x06
MOVWF ADCON1
;
;EJEMPLO DE UTILIZACIÓN
;----------------------
;
;ENVÍA EL ESTADO DEL PORTB POR MEDIO DE LA USART.
;
BCF STATUS,RP0
CALL INI_USART
MOVFW PORTB
CALL DETERMINAR_PARIDAD
BCF contador,0 ;RETORNA CON LA FINALIZACIÓN DE LA TRANSMISIÓN
CALL TRANSMITIR
GOTO $-4
;
END

Rx Ejemplo de utilización.

Código: [Seleccionar]
LIST P=16F877A
INCLUDE <P16F877A.INC>
__CONFIG _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _BODEN_OFF & _LVP_OFF & _WRT_OFF
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
CBLOCK H'20'
bit_recepcion
bit_cont
bit_cont_temp
dato_recibido
dato_recibido_temp
                        RCSTA_temp
SALVAR_W
SALVAR_STATUS
SALVAR_FSR
SALVAR_PCLATH
SALVAR_OPTION_REG
ENDC
;
RESET ORG H'00'
GOTO INICIO
ORG H'04' ;VECTOR INTERRUPCIÓN
INTERRUP
                        MOVWF SALVAR_W ;SALVA EL CONTENIDO DE W
SWAPF STATUS,W ;PASAMOS A W STATUS (ES CON SWAPF PARA NO AFECTAR EL BIT Z)
MOVWF SALVAR_STATUS ;SALVA EL CONTENIDO DE STATUS
SWAPF FSR,W ;PASAMOS A W FSR
MOVWF SALVAR_FSR ;SALVA FSR
SWAPF PCLATH,W ;PASAMOS A W PCLATH (Pagina de programa)
MOVWF SALVAR_PCLATH ;SALVA EL CONTENIDO DE PCLATH
BCF STATUS,RP1
BSF STATUS,RP0 ;BANCO 1
SWAPF OPTION_REG,W ;PASAMOS A W OPTION_REG (Bancos)
MOVWF SALVAR_OPTION_REG ;SALVA EL CONTENIDO DE OPTION_REG
BCF STATUS,RP0 ;BANCO 0
                        BTFSS PIR1,RCIF ;¿SE ACTIVÓ RECEPCIÓN USART?
GOTO        SALIR ;FALSA INTERRUPCIÓN
BCF PIR1,RCIF ;SI, REESTABLECEMOS EL BIT DE RCIF
;
#INCLUDE RX_USART_INTERRUPCION.INC
;
SALIR BSF STATUS,RP0 ;BANCO 1
SWAPF SALVAR_OPTION_REG,W ;RESTAURA EL VALOR A OPTIO_REG
MOVWF OPTION_REG
SWAPF SALVAR_PCLATH,W ;RESTAURA EL VALOR A PCLATH
MOVWF PCLATH
SWAPF SALVAR_FSR,W ;RESTAURA EL VALOR A FSR
MOVWF FSR
SWAPF SALVAR_STATUS,W ;RESTAURA EL VALOR A STATUS
MOVWF STATUS
SWAPF SALVAR_W,W ;RESTAURA EL VALOR A W
RETFIE
;
#INCLUDE RX_USART.INC

;
INICIO BCF STATUS,RP0
BCF STATUS,RP1 ;BANCO 0
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE
BSF STATUS,RP0 ;BANCO 1
CLRF TRISA
CLRF TRISB
CLRF TRISC
CLRF TRISD
CLRF TRISE
MOVLW 0x06 ;PORTA TODAS DIGITALES.
MOVWF ADCON1
;
;EJEMPLO DE UTILIZACIÓN.
;
;RECIBE EL ESTADO DEL PORTB DE TX POR MEDIO DE LA USART Y LO MUESTRA EN EL PORTB.
;
CALL INI_USART_RX
CALL ACTIVAR_USART
BTFSS bit_recepcion,0
GOTO $-1
BCF bit_recepcion,0
MOVFW dato_recibido
MOVWF PORTB
GOTO $-5

END
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 21 de Octubre de 2009, 02:57:43
te habrás quedao agusto¡¡¡  :D :D :D

Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 21 de Octubre de 2009, 09:48:48
te habrás quedao agusto¡¡¡  :D :D :D



Sin ofender, pero no te entiendo :oops:
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 22 de Octubre de 2009, 02:47:50
Citar
Sin ofender, pero no te entiendo
jej vas a tener que decir algo mas para ofender  :D :D :D era como un piropo que me salio asi en ese momento
 :D :D :D te habras quedao agusto = que tas sobrao = mu buen trabajo. :mrgreen: y un par de estas  :-/ :-/

ademas a mi me viene de perlas el tema, estoy comparando la de rX con la que utilizo yo para mi proximo juguete. quiero usar un sid6581 y tengo que usar rx si o si, veremos en que queda :mrgreen:

un saludo
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 22 de Octubre de 2009, 06:41:57
Gracias Alogic.on

De todas maneras, gracias a este foro logré hacerlo andar. ;-)
Título: Re: Rutinas para compartir
Publicado por: MAXI en 04 de Noviembre de 2009, 10:10:13
Hola muchachos:
Soy bastante nuevo en el foro y me gustaria hacer un aporte de rutina en la conversión bin a bcd. Esta rutina me a servido mucho en varios de mis proyectos. Se llama conversión bin a bcd por ajustes sucesivos. No soy muy frecuente en el foro por razones de tiempo. Pero quiero ayudar. Saludos y espero que les sirva.

;**************************************************************************
; Binary to BCD conversion
;   Bin (Bin_H Bin_l)   --->      BCD_H BCD_L (0000 - 9999)
;      Hexa            BCD (abcde)
;   Usa: Contador        Contador.
;   Usa: FSR   File Select Register.
;   Usa: Temporal        Temporal.
;**************************************************************************
Bin2BCD
      bcf   STATUS,C
      movlw   .16
      movwf   Contador
      clrf   BCD_L
      clrf   BCD_H
loop16
      rlf   Bin_L,f
      rlf   Bin_H,f
      rlf   BCD_L,f
      rlf   BCD_H,f
      decfsz   Contador,f
      goto   adjDEC
      return
adjDEC
      movlw   BCD_L
      movwf   FSR
      call   adjBCD

      movlw   BCD_H
      movwf   FSR
      call   adjBCD

      goto   loop16
adjBCD
      movlw   3
      addwf   INDF,w
      movwf   Temporal
      btfsc   Temporal,3
      movwf   INDF
      movlw   0x30
      addwf   INDF,w
      movwf   Temporal
      btfsc   Temporal,7
      movwf   INDF
      return
;*********************************************************************************************
;---------------------------------------------------------------------------------------------
;*********************************************************************************************
;* Nombre: Convierte.asm
;* Descripción: Rutina de conversión y carga de buffers de display
Convierte
      movf   CNT_H,w      ;carga parametros para conversion   
      movwf   Bin_H      
      movf   CNT_L,w
      movwf   Bin_L

      call   Bin2BCD      ;convierte binario a BCD

      swapf   BCD_H,w      ;guarda millares
      andlw   0x0F
      movwf   BCD_1
      movf   BCD_H,w      ;guarda centenas
      andlw   0x0F
      movwf   BCD_2
      swapf   BCD_L,w      ;guarda decenas
      andlw   0x0F
      movwf   BCD_3
      movf   BCD_L,w      ;guarda unidades
      andlw   0x0F
      movwf   BCD_4
      return
;***************************************************************************
Título: Re: Rutinas para compartir
Publicado por: alogic.on en 04 de Noviembre de 2009, 14:00:55
oisss, que buena. con millares  :mrgreen: :mrgreen: gracias, a la carpeta que va

un saludo
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 04 de Noviembre de 2009, 17:10:42
Muchas gracias MAXI  :-/
Título: Re: Rutinas para compartir
Publicado por: canival35 en 20 de Noviembre de 2009, 07:07:14
Hola comparto una rutina hecha por mi para prender y apagar el bit D0   en un segundo del PIC18F4550 con los calculos hechos para un cristal de 20MHz, solo hace un toogle y genera retardos que segun mis calculos y el osciloscopio es 1 segundo y algunos cuandos nanosegundos de sobra, espero sea de ayuda

Código: [Seleccionar]

#INCLUDE <p18F4550.inc>
LECTURA EQU 0x0050 ;Variable de estado
LECTURA_PRUEBA EQU 0x0055 ;Variable de estado
temp EQU 0x0054
temp_retraso EQU 0x0051
temp2_retraso EQU 0x0052
temp3_retraso EQU 0x0053
Ind_Buf EQU 0x00 ; Contador de número de datos copiados
Buf_Dat EQU 0x20 ; Bufer de recepción/transmisión
ORG 0x00 ;Vectorizacion 
; GOTO inicio

;------------------------------------------

BCF INTCON,7 ;DESACTIVAR INTERRUPCIONES
BCF WDTCON,0 ;dESACTIVAR WDT
MOVLW b'10001000' ;timer 0 ON-16bits-TImer0 prescaler off
MOVWF T0CON ;
;registros de interrupciones
BCF   INTCON,7 ;deshabilitar interrupciones
; configurar puertos
CLRF PORTD
CLRF LATD
MOVLW 0x00 ;d SALIDA DE MATRIZ DE LEDS
MOVWF TRISD



;=========================
;=====inicio del progama==
;=========================

MOVLW d'248'
MOVWF temp_retraso
MOVLW d'255'
MOVWF temp2_retraso
MOVLW d'24'
MOVWF temp3_retraso



BTG LATD,0 ;INVIERTE D0
CLRF TMR0L
CALL retraso_
BRA 0X1E  ;te manda a BTG LATD






;==========rutina de retrasos=============
retraso_:
movlw 0x18 ;1
movwf temp3_retraso ;1
decfsz temp_retraso,1,0  ;1 --- 3 ciclos cuando es cero  ;FF-- salta si file es cero
goto    retraso1        ;2  = [(20332*(248-2)]+7=5001679---> 5001679*200nSeg=1 seg aprox ^
movlw 0xF8 ;1 ni maiz 246+2=248=F8    /|\
movwf temp_retraso      ;1       / | \
  ;   1 segundo sera={[246(254(80)+12)]+7}200x10^-9=1.000335 segundos / |  \
  ; / |   \
return ;2 +  3 del decfsz cuando es cero     Tercer ciclo [246*ans]+7
retraso1: |
decfsz temp2_retraso,1,0 ;1 --- 3 ciclos cuando es cero ;FF-- salta si file es cero |
goto    retraso2 ;2    (255-1)(80)+12=20332 |
movlw 0xFF ;54h=84d ;1 |
movwf temp2_retraso ;1 Segundo ciclo [254*80]+12
goto retraso_ ;2 |
|
retraso2: ;El ciclo debe de ser igual a 77 para que 255*255*77*200ns= 1.00925 segundo |
decfsz temp3_retraso,1,0 ;1 --- 3 ciclos cuando es cero |
goto    retraso2 ;2    Secuencia ascendente para
movlw 0x18 ;18h=24d ;+1 77+3=80 obtener los tiempos
movwf temp3_retraso ;+1    3 del ciclo anterior en retraso1 de retardo totales
nop ;+1 |
goto retraso1 ;+2 Primer ciclo 80
;+3 del ciclo anterior en retraso1 |


;------------------------------------------
Fin_intT0:
RETFIE
END
;------------------------------------------

Título: Re: Rutinas para compartir
Publicado por: willie_rosario_salsa en 26 de Diciembre de 2009, 18:45:46
  • Suma 16bits + 16bits
  • Resta 16bis – 16 bits
  • División 8bits/8bits
  • División 24bits/16bits
  • Multiplicación 16bitsx16bits=32bits
  • Conversión binario de 8 bits a BCD
  • Conversión binario de 16 bits a BCD


Estimado Suky,

Buscando los temas acerca de los mensajes en LCD (tenía un pequeño problemita por eso acudí al foro) encontré esta rutina que me parece muy util y a la vez sencilla para poder enviar los bytes que se deseen a una LCD. Una vez más, gracias compadre, espero me puedan ayudar cuando se complique el proyecto que estoy realizando, ya que de hecho así será porque es un producto que debo considerar algunas variables y hay cosas que desearía me asesoren un poco más.

Con SaLsa,
Julio
Título: Re: Rutinas para compartir
Publicado por: carlostex en 31 de Diciembre de 2010, 05:28:51
Hola a todos, pues soy nuevo en este foro, y un poco en la programación de microcontroladores pic de 8 bits, en estas vacaciones me dediqué a estudiarlo por mi cuenta y ya hice algunas cosas con los pic's, y pues quiero empezar aportando unas bibliotecas que uso.
Una es para hacer retardos la cual lo único que hice fue recopilar en un solo archivo los retardos producidos con http://www.piclist.com/cgi-bin/delay.exe, puse los mas usados para no ocupar mucha memoria.

otra es para realizar sumas, restas y multiplicaciones con números de 16 bits, esta no la hice yo, la tome de un post pero no recuerdo de cual, no es mi intención hacerme créditos de algo que no hice yo,  asi que no le puse nombre de autor al archivo fuente y tampoco lo tenía, le hice unas modificaciones al original por que tenia para dividir y unifiqué los registros que utilizan las 3 operaciones para no ocupar mucha ram.

La ultima es algo que considero muy útil, cuando se trabajan con LCD o Displays es común mostrar un número, para lo que se utiliza algunas de las muchas rutinas expuestas en este foro, pero cuando queremos leer de un teclado matricial se necesita ir a la inversa lo cual es un proceso muy simple. así que sirve para eso, para convertir BCD a BIN. Trabaja con números de 16 bits, por lo que uso la biblioteca de operaciones de 16 bits. Vi posteado en este foro aquí (http://www.todopic.com.ar/foros/index.php?topic=9348.0) una rutina para hacer lo mismo pero como es bajada de microchip creo que tiene derechos y no se puede copiar sin el permiso del autor,
así que me hice una intentado usar poca memoria ram, se usa bastante memoria rom, pero se puede crear una rutina para multiplicar y acumular, le agregaré la rutina pero lo dejare para otro día.

Y pues publicaré los trabajos que haga con los pic's que no estén en el foro, porai tengo una rutina para trabajar con el protocolo 1 wire y el sensor ds18b20 la cual alguien la modificó para soportar ese dispositivo pues el que trae el libro es otro, y yo la modifiqué para acceder a varios dispositivos conectados al mismo puerto usando el comando match_rom, pues lo quiero para controlar varios de esos sensores pero busqué mucho por la red y no encontré una biblioteca o ejemplo que lo haga, asi que investigue en el data sheet y el protocolo 1 wire y logré hacer una implementación de uso sencillo, pero lastima que no se pueden publicar contenidos de ese libro, veré si tengo tiempo y hago una implementación propia para manejar el protocolo y el sensor.

Saludos
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 02 de Enero de 2011, 11:59:41
Muchas gracias Carlos  :-/ :-/
Y bienvenido al foro de Todopic  :-/ :-/
Título: Re: Rutinas para compartir
Publicado por: c@Lic_0 en 08 de Febrero de 2011, 19:58:26
Estas rutinas tambien se las puede usar en los pic18? :mrgreen:  o tendre problemas al usarlas con estos pics
Título: Re: Rutinas para compartir
Publicado por: Leon Pic en 08 de Febrero de 2011, 21:09:39
No c@Lic_0 No funcionan en los pic de 18F
Título: Re: Rutinas para compartir
Publicado por: emiro99 en 15 de Marzo de 2012, 14:44:42
  • Suma 16bits + 16bits
  • Resta 16bis – 16 bits
  • División 8bits/8bits
  • División 24bits/16bits
  • Multiplicación 16bitsx16bits=32bits
  • Conversión binario de 8 bits a BCD
  • Conversión binario de 16 bits a BCD


Muchísimas gracias, por esas rutinas  :-/ :-/ :-/ :-/ :-/
Título: Re: Rutinas para compartir
Publicado por: Arkantox en 08 de Agosto de 2012, 13:04:18
Un saludo a todos;

Soy nuevo en el foro y pues no tan nuevo en esto del PIC este a año termino casi la carrera de Ingenieria electronico, digo casi porque me falta hacer la tesis  :? , no se si alguno le ha pasado cuando empezaron a querer usar el lcd y por razones economicas compraron un lcd barato y usaron la libreria del foro y nos le funciono, bueno pues a mi me paso algo parecido y fue toda una odicea pues no conocia este foro, pues les adjunto una libreria para esos lcd que son de bajo costos y por ende muy lentos en su inicializacion, la rutina es un hibrido pues agarre una parte del codigo de una libreria qe tenia, hoy en dia esta es la que uso para cualquier LCD ya sea de alto costo o barato igual te va a funcionar. Es para LCD-4bit
Título: Re: Rutinas para compartir
Publicado por: groundman en 15 de Agosto de 2012, 15:14:34
pues a compartir se ha dicho. :)

Código: [Seleccionar]
;*********************************** CONVERTIR VALOR BCD A HEX ******************************************************
; Convierte valor bcd a hexagesimal .
; ejemplo: 0x15(15 segundos del RTC) a 0x0F (valor 15 en decimal)BCD_HEX
BANK7                     ;selecciona banco 7 de ram
movwf       ByteL      ;carga valor a convertir contenido en W
movwf       ByteH     ;carga valor a convertir contenido en W
movlw       0x0f        ;selecciona el nibble bajo de W
andwf        ByteL,f    ;introducelo en el registro ByteL
movlw       0xf0        ;selecciona el nibble alto de W
andwf        ByteH,f    ;introducelo en el registro ByteH
swapf        ByteH,w   ;invierte los nibles de ByteH e introduce el resultado en W
mullw        .10          ;multiplica el contenido de W por 10d
movf         PRODL,w  ;caga el resultado en W
addwf        ByteL,w    ;suma el contenido de ByteL a W
return

esta rutina es muy util para utilizar los valores horarios que entrega un RTC.ya que este ultimo entrega los datos en formato BCD y para gestionarlos en el pic
los pasa a hexagesimales.

se carga en W el valor a convertir.y la conversion se establece de nuevo en W

PD: alguien sabe como eliminar los espacios del tabulador? es un rollo tener que eliminarlos a mano.y sin eliminarlos el texto es inteligible. :x
Título: Re: Rutinas para compartir
Publicado por: groundman en 06 de Enero de 2014, 14:24:11
aqui pongo una rutina para usar un teclado por resistencias.hay que configurar ADCON0 correctamente antes de su llamada.es para un 18f2550



Código: [Seleccionar]
;ESTE PROGRAMA DEVUELVE EN W,EL VALOR ANALOGICO INTRODUCIDO EN AN0,AN1,AN2 O A43 aunque esta modificado para funcionar solo con AN3
;si introducimos un valor inferior a TOPE_TECLA,y metemos un valor de voltage en uno de las cuatro entradas analogicas,
;ese valor se introduce en TEMP_ANALOG.el programa solo lee un pin a la vez,es decir si introducimos voltage en los dos
;pin,solo se tendra encuenta el primer voltage que se halla aplicado.
;
;la peculariedad de que este programa sea tan grande,es que tiene un sistema de comprovacion de errores,que al pulsar
;una tecla.se almazenan en memoria 10 valores de esa tecla y se coje el valor mas repetido.de esa forma se evita el que al
;pulsar un boton resistivo,no cojamos el valor mas aproximado al real de ese boton.y que nos falle la identificacion de esa tecla.

;el programa tarda en ejecutarse 118ms a 48Mhz

CBLOCK BOTON_PULS_VAR
TEMP_ANALOG ;registro de tecla pulsada
COMPARADOR
PREVALECE
CONT_REG
CONT_COINC
  ENDC

#define VALOR_TOPE .240 ;valor tope de tecla sin pulsar
#define INI_RAM 0XF6 ;zona donde se ubicaran los datos analogicos de tecla pulsada
#define INI_TABLA 0XEC


BOTON_PULS movlw INI_RAM
movwf FSR0L
movlw BANCO_GENERAL
movwf FSR0H

REPE call DAT_AN ;lee dato analogico
movlw VALOR_TOPE
cpfslt TEMP_ANALOG
return ;si el valor analogico de la tecla es superior a TOPE_TECLA repite busqueda analogica(sin pulsar)
movff TEMP_ANALOG,INDF0
incf FSR0L,F ;incrementa FSR
clrf WREG
cpfseq FSR0L
goto REPE ;si no se ha llegado al tope de la ram repite

;********************************************************BUSCA_REP**********************************************************************;
; ;
;//////////////////////////////////////aqui leemos la ram y buscamos el dato mas repetido///////////////////////////////////////////////;
;//en este subprograma se cogen los valores almacenados entre las direcciones seleccionadas y se coge valor que tenga mas numeros repetidos.

BUSCA_REP movlw BANCO_GENERAL ;banco donde trabajaremos con los registros generales
movwf FSR2H ;selecciona bancos de direccionamiento indirecto
movwf FSR1H
movwf FSR0H

movlw INI_TABLA ;inicio de tabla ram donde estan los valores a comparar
movwf FSR0L ;selecciona indice de tabla
decf FSR0L,F ;decrementa una direccion para luego incrementarla

movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR2L ;selecciona indice de tabla
decf FSR2L,F ;decrementa una direccion para luego incrementarla

movlw .11 ;bytes a comparar menos 1
movwf CONT_COINC ;contador de comparaciones
regsig2 dcfsnz CONT_COINC,F ;decrementa el contador de comparaciones
goto discrim ;si se ha terminado de comprobar las coincidencias salta a esta direccion


movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR1L ;selecciona indice de tabla
incf FSR2L,F ;incrementa indice de tabla
decf FSR1L,F

movff INDF2,COMPARADOR ;introduce valor de la tabla en registro comparador
movlw .11 ;registros a comparar
movwf CONT_REG ;contador de registros a comparar
incf FSR0L,F ;incrementa  indice de registros

regsig1 incf FSR1L,F ;incrementa indice de comparaciones
movf INDF1,W ;lee el registro indexado
dcfsnz CONT_REG,F ;decrementa contador de registros
goto regsig2 ;si se ha llegado al limite salta a lectura de siguiente registro
cpfseq COMPARADOR ;comprueba si w es igual a COMPARADOR
goto regsig1 ;siguiente comparacion
incf INDF0,F ;incrementa direccion seleccionada si hay coincidencia
goto regsig1 ;siguiente comparacion


;busca el valor mas alto
discrim movlw .9 ;cantidad de registros a comparar
movwf CONT_REG ;registro contador
movlw INI_TABLA ;inicio de tabla
movwf FSR0L ;direcciona tabla ram
movff INDF0,PREVALECE ;introduce el valor contenido en ram al registro prevalescente
dis1 incf FSR0L,F ;siguiente direccion
movf INDF0,W ;carga valor direccionado en W
cpfsgt PREVALECE ;comprueba si es mayor
movff INDF0,PREVALECE ;si es mayor introduce el valor en el registro prevalescente
decfsz CONT_REG,F ;decrementa contador de comprobaciones
goto dis1 ;siguiente comprovacion

;busca el valor mas alto de las coincidencias
movlw INI_TABLA ;carga inicio de tabla
movwf FSR0L
pre1 movf INDF0,W ;carga el valor direccionado en W
xorwf PREVALECE,W ;comparalo con el valor mas alto
btfsc STATUS,Z ;si se ha encontrado,
goto pre2 ;salta a pre2
incf FSR0L,F ;incrementa direccion
goto pre1 ;repite comparacion
pre2 movlw .10 ;valor de salto a tabla de valores
addwf FSR0L ;salta al valor
movf INDF0,w ;introduce valor en W
return ;retorna


;//////////////////////////////////(conversor A/D)////////////////////////////////////////////////////////////////////////////////////////////////
;///////////////busca el dato analogico introducido por el pin seleccionado/////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;Si queremos que funcionen todas las entradas analogicas.hay que habilitar las lineas deshabilitadas

DAT_AN ;BANK0 ;selecciona banco 0
;GIE_OFF ;GIE0 ;deshabilita las interrupciones
;btfsc INTCON,GIE
;goto GIE_OFF
bsf ADCON0,GO_DONE ;inicia la conversion
AD_GOIN btfsc ADCON0,GO_DONE ;comprueva si la conversion ha finalizado
goto AD_GOIN ;si la conversion ha finalizado continua
movf ADRESH,w ;carga dato analogico en el acumulador
movwf TEMP_ANALOG ;carga el dato de w en TEMP_ANALOG
;movf ADCON0,W
;movwf CANAL ;mete el contenido de ADCON0 en CANAL
;movf CONT_AD,W ;dato que se suma a ADCON0 para que a la siguiente lectura sea en el proximo canal de AD
;addwf ADCON0,F ;incrementa el canal analogico(AN0->AN4)
;movlw b'00100001';valor para usar AN5 -> b'00101001' ;valor del ultimo registro del conversor analogico
;xorwf ADCON0,w
;btfss STATUS,Z ;si llega a este valor
;return
;movlw 0x01 ;selecciona de nuevo el conversor AN0
;movwf ADCON0
return

Título: Re: Rutinas para compartir
Publicado por: sam_20 en 14 de Abril de 2014, 15:09:24
Hola a todos

Soy nueva en el foro y me pareció muy buena idea lo de aportar las rutinas "básicas" para los pic. Concuerdo con que ahorrar tiempo, y ayudan a resolver dudas; aunque no siempre hay que estar atenidos de que nos hagan todo :). 

Bueno dejo me aporte al tema, ya que a mi me sirvió mucho y espero a muchos otros también les ayude. Mi programa no es gran cosa, pero puede que beneficie a alguien.

Es un convertidor de hexadecimal a binario y a decimal, que despliega el resultado de la conversión en la terminal de la computadora, el despliegue es en formato ASCII. Esta todo comentado. Puede optimizarse, yo ya no lo hice debido al tiempo y a que me dio un poco de flojera XD, pero pueden modificarlo si gustan.

Adjunto el archivo. Muchas gracias por su atención y espero les sirva
Título: Re:Rutinas para compartir
Publicado por: Argonaut en 17 de Febrero de 2016, 12:53:57
Ole... :-)   Gracias a todos... estoy intentando aprender ASM por libre, y estas rutinas me van de perlas para ir aprendiendo los comandos. Saludos.
Título: Re:Rutinas para compartir
Publicado por: AnalexaCastillo en 13 de Agosto de 2016, 19:49:15
Hola chic@s, yo soy nueva en el grupo pero me han ayudado mucho, les dejo un aporte, conversor A/D, para pic16f887
Título: Re:Rutinas para compartir
Publicado por: groundman en 02 de Septiembre de 2017, 15:14:48
hola.me hizo falta realizar una rutina que convirtiera un numero HEX de 4 bytes (16bit) a un numero decimal.

utilizo dos registros: DEC_H y DEC_L para el valor hexagesimal.

y recojo el resultado en DEC_U,DEC_H y DEC_L.

el valor 0000h daria 0x00,0x00,0x00   =0

y el valor FFFFh daria 0x06,0x55,0x35  =65535.

despues de esto ya es facil coger estos valores y pasarlos a ASCII.o usarlos tal cual segun nuestras necesidades.


   movlw   0Xff          ;valor hexagesimal para el byte bajo a convertir
      movwf   DEC_L          ;byte bajo del valor hexagesimal a convertir
      movlw   0Xff          ;valor hexagesimal para el byte alto a convertir
      movwf   DEC_H          ;byte alto del valor hexagesimal a convertir
      
      
      call   BIN16_TO_DEC
      NOP
      
Código: [Seleccionar]
;******************************************************* BIN16_TO_DEC ***************************************************
;conversor
BIN16_TO_DEC movff DEC_H,ADD_DEC_H
clrf CIENTOS     ;registro de las centenas
clrf ACUMULADOR
clrf DEC_U

SUB1 movlw .100     ;valor a restar
subwf DEC_L,W     ;restalo al acumulador
btfss STATUS,C
goto SUB     ;si es menor salta a SUB.pero si es mayor o igual,sigue restando
movlw .100     ;valor a restar
subwf DEC_L,F     ;restalo del byte bajo
incf CIENTOS,F     ;incrementa el registro de las centenas
call incre_cientos     ;incremento de los registros contadores
goto SUB1     ;repite
;*********************************************************** SUB ******************************************************
SUB movf DEC_L,W     ;recoge el resto
addwf ACUMULADOR,F     ;y sumalo al acumulador
movlw .100    
subwf ACUMULADOR,w     ;si no llega a 100,
btfss STATUS,C
goto acu1     ;continua calculo
movlw .100
subwf ACUMULADOR,F     ;si ACUMULADOR es igual o superior a 100. resta 100 al acumulador y
incf CIENTOS,F     ;incrementa el registro de las centenas
call incre_cientos     ;incremento de los registros contadores

acu1 clrf WREG     ;valor 0
cpfseq DEC_H     ;comprueba el valor del registro de las centenas (fin del contaje)
goto acu5     ;salta aqui si se llego al tope de descuento del registro de centenas.

acu_fin movf ADD_DEC_H,W    
addwf ACUMULADOR,f     ;ajusta el valor final
btfsc STATUS,C
call incre_doble     ;otro ajuste
movlw .100
subwf ACUMULADOR,w
btfss STATUS,C     ;comprueba si ACUMULADOR es mayor o igual a 100
goto fin2
movlw .100     ;si es asi,
subwf ACUMULADOR,F     ;resta elvalor a ACUMULADOR
incf CIENTOS,F     ;he incrementa CIENTOS
call incre_cientos
;por si el valor era 200d
movlw .100
subwf ACUMULADOR,w
btfss STATUS,C     ;comprueba si ACUMULADOR es mayor o igual a 100
goto fin2
movlw .100     ;si es asi,
subwf ACUMULADOR,F     ;resta elvalor a ACUMULADOR
incf CIENTOS,F     ;he incrementa CIENTOS
call incre_cientos     ;incremento de los registros contadores

fin2 movlw .100
subwf CIENTOS,w     ;comprueba si CIENTOS es superior a 100
btfss STATUS,C
goto fin3    
movlw .100     ;si lo es,
subwf CIENTOS,f     ;restale 100 al registro de las centenas
incf DEC_U,F     ;he incrementa el de los diezmiles

fin3 movff ACUMULADOR,DEC_L    ;intercambia registros
movff CIENTOS,DEC_H     ;intercambia registros
return     ;fin del la rutina
;******************************************************************************************************************
acu5 setf DEC_L     ;setea el registro para una nueva resta
decf DEC_H,F     ;decrementa el registro de las centenas
goto SUB1     ;vuelve al principio

;circunstancia que se da en el valor 0xB000.donde hay un desbordamiento que hay que ajustar.
incre_doble incf CIENTOS,F
incf CIENTOS,F
movlw .56
addwf ACUMULADOR,F
return

;incremento del contador de los cientos y los miles
incre_cientos movlw .100     ;valor a comparar
cpfseq CIENTOS;subwf CIENTOS,w
return     ;retorna si no lo es
incf DEC_U,F     ;incrementa el contador de los diez miles
clrf CIENTOS     ;
return     ;retorna

      
Título: Re:Rutinas para compartir
Publicado por: KILLERJC en 02 de Septiembre de 2017, 15:50:21
Esta pagina tambien tiene algunos groundman:

http://www.piclist.com/techref/microchip/math/radix/index.htm

los unpacked es 1 registro por cada valor. Y los packed es como vos lo tenes.
Título: Re:Rutinas para compartir
Publicado por: groundman en 02 de Septiembre de 2017, 17:57:29
gracias no lo sabia.igual me hubiera ahorrado mucho tiempo.pero bueno.ya esta hecho.

ya que lo he hecho.pondre un complemento para pasar los valores a ASCII.

Código: [Seleccionar]

;*************************************************************** DEC_TO_ASCII *********************************************************

DEC_TO_ASCII movf DEC_L,w
call DEC_HEX
movwf DEC_L
movff DEC_L,TEMP_DEC_L
;call DEC_HEX
andlw 0x0F

movwf Un
movf TEMP_DEC_L,W
;call DEC_HEX
andlw 0xF0
swapf WREG
movwf Dc

movf DEC_H,W
call DEC_HEX
movwf DEC_H
movff DEC_H,TEMP_DEC_H
;movf TEMP_DEC_L,W
;call DEC_HEX
andlw 0x0F

movwf Cn
movf TEMP_DEC_H,W
;call DEC_HEX
andlw 0xF0
swapf WREG
movwf Um



movf DEC_U,W
call DEC_HEX
movwf DEC_U
movff DEC_U,TEMP_DEC_U
;movf TEMP_DEC_L,W
;call DEC_HEX
andlw 0x0F
movwf Dm

call ASCII_CONV


;xorwf TEMP_DEC_L,f
return
ASCII_CONV movlw 0x30
addwf Un,f
addwf Dc,f
addwf Cn,f
addwf Um,f
addwf Dm,f
return
;*********************************** CONVERTIR VALOR DECIMAL EN HEX ******************************************************
; Convierte valor decimal en hexgesimal
; ejemplo: 0x0f -> 0x15
DEC_HEX ;BANK7 ;selecciona el banco 7 de ram
movwf      reg1 ;carga valor a convertir contenido en W
        setf Resultado ;pon a 1 todos los bits del registro Resultado.
        movlw   .10 ;carga el valor 10d en W
div  incf    Resultado,f ;incrementa el registro Resultado
        subwf   reg1,F ;restar a reg1 el valor .10
        btfsc   STATUS,C ;comprueba si ha habido acarreo
        goto    div ;repite div
        movlw   .10 ;carga el valor 10d en W
        addwf   reg1,W ;sumalo a reg1
        movwf   Resto ;carga la suma enterior en Resto
swapf Resultado ;invierte los nibles
addwf Resultado ;suma el contenido de w a Resulatado
movf Resultado,w
return ;retorna