Migrar codigo asm para 16F84A al 16F628A

Hola a todos.
Soy muy novato con esto de los PIC, y quisiera modificar este código para usarlo con un 16f628 en lugar del 16f84, ya que este último es casi imposible de encontrar.

Muchas gracias.
Os paso mi código para ver las modificaciones a realizar:
PHP:
;
;
; DTMF DECODER 






    list    p=16c84; definicion del microcontrolador usado

    include "p16c84.inc"; libreria de uso general 

    __FUSES _CP_OFF & _XT_OSC  & _WDT_OFF & _PWRTE_ON ; configuracion de los fuses



OPTREG    equ    01  ;  Definicion de las  equivalencias de registros

TRIS_A    equ    05  ;

TRIS_B    equ    06  ;

relays    equ    10  ;

mfcode    equ    11  ;

cntdown    equ    12  ;

timeout    equ    13  ;

slocnt1    equ    14  ;

slocnt2    equ    15  ;



    org 0000            ;llama al ensamblador a arrancar en 000H



init    goto start



    org 0004            ;vector  de interrupcion



rtc_interrupt

    decfsz slocnt1,F        ;decrementa 1st el preescaler

    goto rtc_int_1

    decfsz slocnt2,F        ;decrementa 2nd el preescaler

    goto rtc_int_1

    bcf relays,4            ;pone el rele 6 en off

    bcf PORTB,4

rtc_int_1

    decfsz cntdown,F        ;la cuenta atrás y pase siguiente si = 0

    goto counting            ;contar aún si no se llega a cero

    bsf timeout,0            ;set timed out bit

    bcf INTCON,2            ;Limpiamos la el flag de la interrupcion

    retfie                ;regresamos



counting

    bcf timeout,0            ;Limpiamos el bit del timed out

    bcf INTCON,2            ;Limpiamos la el flag de la interrupcion

    retfie                ;regresamos



; SUBRUTINAS



wait_strobe

    btfsc timeout,0            ;miramos si  a acabado por timed out

    goto set_z            ;set Z flag if timeout ocurred

    btfss PORTA,4            ;miramos si el Strobe es activo en RA4

    goto wait_strobe        ;bucle hasta que lo sea

    movfw PORTA            ;recibe el codigo desde el 8870

    movwf mfcode            ;Lo guardamos en "mfcode"

    bcf mfcode,4            ;nos aseguramos que el strobe no se ve como un dato

    bcf STATUS,2            ;regresamos con Z=0 si el tono es decodificado

    return



set_z    bsf STATUS,2            ;regresamos con Z=1 si el tiempo de espera

    return



wait_no_strobe

    btfsc PORTA,4            ;miramos si el Strobe es activo en RA4

    goto wait_no_strobe        ;bucle hasta que no lo sea

    return



start_timer

    movlw H'54'            ;Preescaler activado para 7 segundos 

    movwf cntdown                   ;esto lo hacemos para que si hay alguna pausa entre tonos no se alargue mas de 7 segundos.

    return




                                   ;--------------------------------------------------------;
                                   ; INICIO DE LAS RUTINAS DE CONFIGURACION Y DECODIFICACION; 
                   ;--------------------------------------------------------;



start    movlw B'00100000'        ;Pasamos al banco 1 

    movwf STATUS



    clrf TRIS_B            ;configuramos todos los pines del puerto B a modo de salida

    movlw B'00011111'        

    movwf TRIS_A                    ;configuramos todos los pines del puerto A a modo de entrada

        movlw B'10000111'

    movwf OPTREG            ;ponemos :     pull-up del port B OFF

                    ;    RTCC cuenta del clock interno 

                    ;    preescaler connectado a RTCC

                    ;    el prescaler divide por 256

                    ;    "los otros bits no son importantes"

    clrw                ;limpiamos el registro de trabajo work

    movwf STATUS            ;regresamos a la pagina del registro 0

    clrf PORTB            ;ponemos todas las salidas en OFF

    clrf relays

    clrf timeout

    movlw B'10100000'

    movwf INTCON            ;global,y  RTCC interrupts activados



decode    call wait_no_strobe        ;empieza a correr cuando no hay tono presente

    clrf timeout            ;establecer condiciones de tiempo de espera hasta más tarde

    call wait_strobe        ;esperar a recibir un tono

    movlw H'0B'            ;0B es el codigo para  DTMF "*"

    subwf mfcode,W            ;poner en cero la bandera si "*" se recibió

    btfsc STATUS,2            ;skip siguiente si no era un "*"

    goto got_star

    goto decode            ;buscar otro



got_star

    call start_timer        ;iniciar el tiempo de espera del temporizador

    call wait_no_strobe        ;esperamos para el tercer tono

    call wait_strobe

    btfsc STATUS,2            ;abortar si el tiempo de espera se ha acabado

    goto decode

    

    movlw H'01'

    subwf mfcode,W                  ;poner en cero la bandera si el tono segundo, era 1

    btfsc STATUS,2            ;skip siguiente si no era un 1

    goto got_1

    

    movlw H'0A'

    subwf mfcode,W                  ;poner en cero la bandera si el tono segundo fue "0"

    btfsc STATUS,2            ;skip siguiente si no era un 0

    goto got_2

    goto get_#            ;esperar # para finalizar la secuencia invalida





                                        ;de acuerdo a los próximos 2 tonos, pero no hace la acción hasta que ve un "#".



got_1    call wait_no_strobe

    call wait_strobe        ;espera al tercer tono

    btfsc STATUS,2            ;aborta si se acaba el tiempo de los 7 seg.

    goto decode



    call wait_no_strobe        ;espera hasta que acaba el tono

    movf mfcode,W            ;recoger, el digito introducido

    addwf PCL,F            ;saltar hacia adelante,hacia el vector

    goto decode            ;5D (mf codigo 0000)

    goto got_11

    goto got_12

    goto got_13

    goto got_14

    goto got_15

    goto got_16

    goto got_17

    goto got_18

    goto decode

    goto got_10

    goto decode            ;*

    goto decode            ;#

    goto decode            ;5A

    goto decode            ;5B

    goto decode            ;5C (mf codigo 1111)



got_10    movlw B'11111111'        ;ponemos todas las salidas en on

    movwf relays

    goto get_#





got_11    bsf relays,0            ;ponemos salida 1 on

    goto get_#



got_12    bsf relays,1            ;ponemos salida 2 on

    goto get_#



got_13    bsf relays,3            ;ponemos salida 3 on

    goto get_#



got_14    bsf relays,2            ;ponemos salida 4 on

    goto get_#



got_15    bsf relays,5            ;ponemos salida 5 on

    goto get_#



got_16    bsf relays,4            ;ponemos salida 6 on

    goto get_#



got_17    bsf relays,6            ;ponemos salida 7 on

    goto get_#



got_18    bsf relays,7            ;ponemos salida 8 on

    goto get_#





; para llegar aqui la secuendia de tono "*<numa><numb><numc><numd>2"  se ha encontrado, Ahora decodificar solicitud

; de acuerdo con los siguientes 2 tonos, pero no realizar la acción hasta que se vea "#"


got_2    call wait_no_strobe

    call wait_strobe        ;espera al sexto tono

    btfsc STATUS,2            ;abortamos si se acaba el tiempo

    goto decode



    call wait_no_strobe        ;esperamos a que acabe el tono

    movf mfcode,W            ;recoger, dígito introducido

    addwf PCL,F            ;saltar hacia adelante, hacia el vector

    goto decode            ;5D (mf codigo 0000)

    goto got_01

    goto got_02

    goto got_03

    goto got_04

    goto got_05

    goto got_06

    goto got_07

    goto got_08

    goto decode

    goto got_00

    goto decode            ;*

    goto decode            ;#

    goto decode            ;5A

    goto decode            ;5B

    goto decode            ;5C (mf codigo 1111)



got_00    movlw B'0000000'

    movwf relays            ;ponemos todas las salidas en off

    goto get_#





got_01    bcf relays,0            ;ponemos la salida 1 off

    goto get_#



got_02    bcf relays,1            ;ponemos la salida 2 off

    goto get_#



got_03    bcf relays,3            ;ponemos la salida 3 off

    goto get_#



got_04    bcf relays,2            ;ponemos la salida 4 off

    goto get_#



got_05    bcf relays,5            ;ponemos la salida 5 Off

    goto get_#



got_06    bcf relays,4            ;ponemos la salida 6 Off

    goto get_#



got_07    bcf relays,6            ;ponemos la salida 7 Off

    goto get_#



got_08    bcf relays,7            ;ponemos la salida 8 Off

    goto get_#



get_#    call wait_strobe        ;esperamos al septimo tono

    btfsc STATUS,2            ;abortamos si se acaba el tiempo

    goto decode



    movlw H'0C'            ;0C es el codigo DTMF del "#"

    subwf mfcode,W            ;Si # es recibido  set Z flag

    btfsc STATUS,2            ;saltamos al siguiente si no  a #

    goto got_#

    call wait_no_strobe

    goto get_#            ;Solo # es valido, loop hasta encontrarlo 

                    ;o acabemos por timeout



got_#   call wait_no_strobe        ;esperamos a que acabe el tono

    movfw relays            ;usar la variable "relays"  to set RB

    movwf PORTB

    goto decode            ;todo hecho, comprobamos si hay nueva secuencia y volvemos a repetir todo.



    retlw 'v'

    retlw '2'

    retlw '.'

    retlw '1'

    retlw '.'

    retlw 'E'

    retlw 'A'

    retlw '3'

    retlw 'A'

    retlw 'B'

    retlw 'N'

    retlw 'c'

    retlw ' '

    retlw '2'

    retlw '0'

    retlw '1'

    retlw '7'
                 end
 
Última edición por un moderador:
En un vistazo general, son bastantes compatibles ambos PICs.

Consigue las hojas de datos, cambia las palabras de configuración y pon el código en MPLAB. Lo ejecutas, y vas eliminando posibles errores.
 
Hola, Lord Chango. Gracias por contestar.
En eso estoy, pero me quedo totalmente clavado.
He cambiado la palabra de configuración, pero sigo teniendo fallos al compilar.
PHP:
;******************************************************************
 processor 16f628a
 include <p16f628a.inc>
 __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _LVP_OFF & _BODEN_OFF & _CP_OFF
 
 ERRORLEVEL -302 ; suppress bank selection messages
FLAG_REG EQU 0x20
 ;CBLOCK  0x20
;*************************** OLD PIC CONFIGURATION   ***************
;
;    list    p=16c84
;
;    include "p16c84.inc"
;
;    __FUSES _CP_OFF & _XT_OSC  & _WDT_OFF & _PWRTE_ON
;
;***************************************************************

OPTREG    equ    01

TRIS_A    equ    05

TRIS_B    equ    06

relays    equ    10

mfcode    equ    11

cntdown    equ    12

timeout    equ    13

slocnt1    equ    14

slocnt2    equ    15


    org 0000            ;



Hola.
He realizado los cambios, y he recompilado, pero no me funciona en placa.
¿Alguna sugerencia?

Esta es la respuesta al compilar:
Debug build of project `E:\New code for 16F628A-2.mcp' started.
Language tool versions: MPASMWIN.exe v5.50, mplink.exe v4.48, mplib.exe v4.48
Preprocessor symbol `__DEBUG' is defined.
Tue Jun 27 14:15:39 2017
----------------------------------------------------------------------
Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F628A "dtmf L803-16F628A.asm" /l"dtmf L803-16F628A.lst" /e"dtmf L803-16F628A.err" /o"dtmf L803-16F628A.o" /d__DEBUG=1
Warning[219] E:\DTMF L803-16F628A.ASM 69 : Invalid RAM location specified.
Warning[219] E:\\DTMF L803-16F628A.ASM 87 : Invalid RAM location specified.
Warning[219] E:\\DTMF L803-16F628A.ASM 97 : Invalid RAM location specified.
Warning[219] E:\\DTMF L803-16F628A.ASM 111 : Invalid RAM location specified.
Warning[219] E:\\DTMF L803-16F628A.ASM 197 : Invalid RAM location specified.
Warning[219] E:\\DTMF L803-16F628A.ASM 207 : Invalid RAM location specified.
----------------------------------------------------------------------
Debug build of project `E:\MIGRATION 16F84A TO 16F628A\New code for 16F628A-2.mcp' succeeded.
Language tool versions: MPASMWIN.exe v5.50, mplink.exe v4.48, mplib.exe v4.48
Preprocessor symbol `__DEBUG' is defined.
Tue Jun 27 14:15:42 2017
----------------------------------------------------------------------
BUILD SUCCEEDED
 
Última edición por un moderador:
Hola...Aclaro que no programo en asembler pero te falta correr los registros ubicado en 10,11,..15 a 20,21...25 ya que los anteriores en el 628 están ocupados y te falta pasar el puerto a digital y apagar los comparadores.
No tengo el Mpla instalado si no lo probaba por aquí, fue copiado de lo que subiste, cámbiale la extensión de txt a asm.
Saludos.

Ric.

PD:envolver el código(el icono de #) en el redactor al subirlo para que conserve la forma/estructura.
Código:
;
;
; DTMF DECODER

;list p=16c84; definicion del microcontrolador usado

:include "p16c84.inc"; libreria de uso general

;__FUSES _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON ; configuracion de los fuses
    processor 16F628A
    #include <P16F628A.INC>
 __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _CP_OFF & _CPD_OFF & _MCLRE_OFF




OPTREG equ 01 ; Definicion de las equivalencias de registros
TRIS_A equ 05 ;
TRIS_B equ 06 ;
relays equ 20 ;10 para el 16C84
mfcode equ 21 ;11
cntdown equ 22 ;12
timeout equ 23 ;13
slocnt1 equ 24 ;14
slocnt2 equ 25 ;15

org 0000 ;llama al ensamblador a arrancar en 000H
init goto start
org 0004 ;vector de interrupcion

rtc_interrupt
decfsz slocnt1,F ;decrementa 1st el preescaler
goto rtc_int_1
decfsz slocnt2,F ;decrementa 2nd el preescaler
goto rtc_int_1
bcf relays,4 ;pone el rele 6 en off
bcf PORTB,4
rtc_int_1
decfsz cntdown,F ;la cuenta atrás y pase siguiente si = 0
goto counting ;contar aún si no se llega a cero
bsf timeout,0 ;set timed out bit
bcf INTCON,2 ;Limpiamos la el flag de la interrupcion
retfie ;regresamos

counting
bcf timeout,0 ;Limpiamos el bit del timed out
bcf INTCON,2 ;Limpiamos la el flag de la interrupcion
retfie ;regresamos

;----- SUBRUTINAS---------

wait_strobe
btfsc timeout,0 ;miramos si a acabado por timed out
goto set_z ;set Z flag if timeout ocurred
btfss PORTA,4 ;miramos si el Strobe es activo en RA4
goto wait_strobe ;bucle hasta que lo sea
movfw PORTA ;recibe el codigo desde el 8870
movwf mfcode ;Lo guardamos en "mfcode"
bcf mfcode,4 ;nos aseguramos que el strobe no se ve como un dato
bcf STATUS,2 ;regresamos con Z=0 si el tono es decodificado
return

set_z bsf STATUS,2 ;regresamos con Z=1 si el tiempo de espera
return

wait_no_strobe
btfsc PORTA,4 ;miramos si el Strobe es activo en RA4
goto wait_no_strobe ;bucle hasta que no lo sea
return

start_timer
movlw H'54' ;Preescaler activado para 7 segundos
movwf cntdown ;esto lo hacemos para que si hay alguna pausa entre tonos no se alargue mas de 7 segundos.
return

;--------------------------------------------------------;
; INICIO DE LAS RUTINAS DE CONFIGURACION Y DECODIFICACION;
;--------------------------------------------------------;

start movlw B'00100000' ;Pasamos al banco 1
movwf STATUS
clrf TRIS_B ;configuramos todos los pines del puerto B a modo de salida
movlw B'00011111'
movwf TRIS_A ;configuramos todos los pines del puerto A a modo de entrada
movlw B'10000111'
movwf OPTREG ;ponemos : pull-up del port B OFF
; RTCC cuenta del clock interno
; preescaler connectado a RTCC
; el prescaler divide por 256
; "los otros bits no son importantes"
clrw ;limpiamos el registro de trabajo work
movwf STATUS ;regresamos a la pagina del registro 0
movlw    0x07; Comparadores analogicos del puerto A = OFF
movwf    CMCON
clrf PORTB ;ponemos todas las salidas en OFF
clrf relays
clrf timeout
movlw B'10100000'
movwf INTCON ;global,y RTCC interrupts activados
decode call wait_no_strobe ;empieza a correr cuando no hay tono presente
clrf timeout ;establecer condiciones de tiempo de espera hasta más tarde
call wait_strobe ;esperar a recibir un tono
movlw H'0B' ;0B es el codigo para DTMF "*"
subwf mfcode,W ;poner en cero la bandera si "*" se recibió
btfsc STATUS,2 ;skip siguiente si no era un "*"
goto got_star
goto decode ;buscar otro

got_star
call start_timer ;iniciar el tiempo de espera del temporizador
call wait_no_strobe ;esperamos para el tercer tono
call wait_strobe
btfsc STATUS,2 ;abortar si el tiempo de espera se ha acabado
goto decode
movlw H'01'
subwf mfcode,W ;poner en cero la bandera si el tono segundo, era 1
btfsc STATUS,2 ;skip siguiente si no era un 1
goto got_1
movlw H'0A'
subwf mfcode,W ;poner en cero la bandera si el tono segundo fue "0"
btfsc STATUS,2 ;skip siguiente si no era un 0
goto got_2
goto get_# ;esperar # para finalizar la secuencia invalida
;de acuerdo a los próximos 2 tonos, pero no hace la acción hasta que ve un "#".
got_1 call wait_no_strobe
call wait_strobe ;espera al tercer tono
btfsc STATUS,2 ;aborta si se acaba el tiempo de los 7 seg.
goto decode

call wait_no_strobe ;espera hasta que acaba el tono
movf mfcode,W ;recoger, el digito introducido
addwf PCL,F ;saltar hacia adelante,hacia el vector
goto decode ;5D (mf codigo 0000)
goto got_11
goto got_12
goto got_13
goto got_14
goto got_15
goto got_16
goto got_17
goto got_18
goto decode
goto got_10
goto decode ;*
goto decode ;#
goto decode ;5A
goto decode ;5B
goto decode ;5C (mf codigo 1111)

got_10 movlw B'11111111' ;ponemos todas las salidas en on
movwf relays
goto get_#
got_11 bsf relays,0 ;ponemos salida 1 on
goto get_#
got_12 bsf relays,1 ;ponemos salida 2 on
goto get_#
got_13 bsf relays,3 ;ponemos salida 3 on
goto get_#
got_14 bsf relays,2 ;ponemos salida 4 on
goto get_#
got_15 bsf relays,5 ;ponemos salida 5 on
goto get_#
got_16 bsf relays,4 ;ponemos salida 6 on
goto get_#
got_17 bsf relays,6 ;ponemos salida 7 on
goto get_#
got_18 bsf relays,7 ;ponemos salida 8 on
goto get_#

; para llegar aqui la secuendia de tono "*<numa><numb><numc><numd>2" se ha encontrado, Ahora decodificar solicitud
; de acuerdo con los siguientes 2 tonos, pero no realizar la acción hasta que se vea "#"


got_2 call wait_no_strobe
call wait_strobe ;espera al sexto tono
btfsc STATUS,2 ;abortamos si se acaba el tiempo
goto decode



call wait_no_strobe ;esperamos a que acabe el tono
movf mfcode,W ;recoger, dígito introducido
addwf PCL,F ;saltar hacia adelante, hacia el vector
goto decode ;5D (mf codigo 0000)
goto got_01
goto got_02
goto got_03
goto got_04
goto got_05
goto got_06
goto got_07
goto got_08
goto decode
goto got_00
goto decode ;*
goto decode ;#
goto decode ;5A
goto decode ;5B
goto decode ;5C (mf codigo 1111)



got_00 movlw B'0000000'
movwf relays ;ponemos todas las salidas en off
goto get_#
got_01 bcf relays,0 ;ponemos la salida 1 off
goto get_#
got_02 bcf relays,1 ;ponemos la salida 2 off
goto get_#
got_03 bcf relays,3 ;ponemos la salida 3 off
goto get_#
got_04 bcf relays,2 ;ponemos la salida 4 off
goto get_#
got_05 bcf relays,5 ;ponemos la salida 5 Off
goto get_#
got_06 bcf relays,4 ;ponemos la salida 6 Off
goto get_#
got_07 bcf relays,6 ;ponemos la salida 7 Off
goto get_#
got_08 bcf relays,7 ;ponemos la salida 8 Off
goto get_#
get_# call wait_strobe ;esperamos al septimo tono
btfsc STATUS,2 ;abortamos si se acaba el tiempo
goto decode

movlw H'0C' ;0C es el codigo DTMF del "#"
subwf mfcode,W ;Si # es recibido set Z flag
btfsc STATUS,2 ;saltamos al siguiente si no a #
goto got_#
call wait_no_strobe
goto get_# ;Solo # es valido, loop hasta encontrarlo
;o acabemos por timeout

got_# call wait_no_strobe ;esperamos a que acabe el tono
movfw relays ;usar la variable "relays" to set RB
movwf PORTB
goto decode ;todo hecho, comprobamos si hay nueva secuencia y volvemos a repetir todo.

retlw 'v'
retlw '2'
retlw '.'
retlw '1'
retlw '.'
retlw 'E'
retlw 'A'
retlw '3'
retlw 'A'
retlw 'B'
retlw 'N'
retlw 'c'
retlw ' '
retlw '2'
retlw '0'
retlw '1'
retlw '7'

end
 

Adjuntos

  • DecoDTMF628.txt
    7 KB · Visitas: 2
Hola ricbevi,
He probado de reasignar las direcciones de memoria, y el programa compila bien,
per cuando lo pongo en la placa, algo sucede con las entradas que no funciona con el hardware.
Te paso el fichero en formato asm. a ver si das con el fallo..
yo llevo horas mirando y no hay manera.
Muchas gracias



Hola ricbevi,
He probado de reasignar las direcciones de memoria, y el programa compila bien,
per cuando lo pongo en la placa, algo sucede con las entradas que no funciona con el hardware.
Te paso el fichero en formato asm. a ver si das con el fallo..
yo llevo horas mirando y no hay manera.
Muchas gracias
 

Adjuntos

  • DTMF-New code for 16F628A.txt
    9.2 KB · Visitas: 3
Última edición:
Hola ricbevi,
He probado de reasignar las direcciones de memoria, y el programa compila bien,
per cuando lo pongo en la placa, algo sucede con las entradas que no funciona con el hardware.
Te paso el fichero en formato asm. a ver si das con el fallo..
yo llevo horas mirando y no hay manera.
Muchas gracias



Hola ricbevi,
He probado de reasignar las direcciones de memoria, y el programa compila bien,
per cuando lo pongo en la placa, algo sucede con las entradas que no funciona con el hardware.
Te paso el fichero en formato asm. a ver si das con el fallo..
yo llevo horas mirando y no hay manera.
Muchas gracias


Te reitero que no programo en asembler pero no veo por ningún lado donde pones el puerto A como digital que por defecto esta en analógico y apagas los comparadores internos del puerto.
Revisa el archivo que yo subí en la parte de ; INICIO DE LAS RUTINAS DE CONFIGURACION Y DECODIFICACION;

Ric.
 
Pá... Tenés que desactivar los comparadores 628 para dejarlo como el anciano 16F84a segun te indicaron, no funka ni para atrás si no lo haces...
Lo de las distintas posiciones de la memoria se manejan redefiniendo desde tu archivo de cabecera.
Solia tener varios programejos en asm del ancianito y los lleve al 16F628 y funcionaban impecablemente haciendo lo que te indicamos.
 
Última edición:
Hola de nuevo.
Disculpadme que sea tan tocho, pero es que no tengo prácticamente experiencia en estos temas
y me colapso.
He revisado el código que me enviaste, Ric, y lo he conseguido compilar con éxito, pero al grabar el PIC, sigo sin que me funcione, creo que te referías a esta parte del código:

PHP:
; INICIO DE LAS RUTINAS DE CONFIGURACION Y DECODIFICACION;
;--------------------------------------------------------;

start movlw B'00100000' ;Pasamos al banco 1
        movwf STATUS
        clrf TRIS_B ;configuramos todos los pines del puerto B a modo de salida
        movlw B'00011111'
        movwf TRIS_A ;configuramos todos los pines del puerto A a modo de entrada
        movlw B'10000111'
        movwf OPTREG ;ponemos : pull-up del port B OFF
                    ; RTCC cuenta del clock interno
                    ; preescaler connectado a RTCC
                    ; el prescaler divide por 256
                    ; "los otros bits no son importantes"
        clrw ;limpiamos el registro de trabajo work
        movwf STATUS ;regresamos a la pagina del registro 0
        movlw    0x07; Comparadores analogicos del puerto A = OFF
        movwf    CMCON
        clrf PORTB ;ponemos todas las salidas en OFF
        clrf relays
        clrf timeout
        movlw B'10100000'
        movwf INTCON ;global,y RTCC interrupts activados

Vuelvo a subir el código, a ver si encontráis algo que yo no he sabido ver.
Por cierto, muchas gracias por vuestra paciencia.
 

Adjuntos

  • dtmf.rar
    18.2 KB · Visitas: 7
Última edición por un moderador:
Hay dos cosas que creo pueden llegar a ser, te sugiero que lo revises.
-Las funciones 'retlw' del final del código nunca son accedidas en la forma en que están puestas, no hay ninguna subrutina que llege ahí.
-Todo lo que sea tablas se recomienda ponerlo en las primeras posiciones de memoria, deberías probar eso también.

Código:
[B];----- SUBRUTINAS---------[/B]

Salto1
                      addwf PCL,F ;saltar hacia adelante,hacia el vector
                      ...
Salto2
                      addwf PCL,F ;saltar hacia adelante,hacia el vector
[B]wait_strobe
        btfsc timeout,0 ;miramos si a acabado por timed out
        goto set_z ;set Z flag if timeout ocurred[/B]
 
Claro que si..
Tienes toda la razón!!!
Por cierto, sigo encallado, estoy seccionado el codigo por que me pasa una cosa curiosa,
con el 16F84A cuando llego hasta esta linea de codigo, las salidas me dan nivel bajo es decir GND,
y cuando uso el mismo codigo con el 16F628A no dan ese nivel, cosa que me parece del todo extraña,
todo esto lo pruebo con la misma placa, y no lo llego a entender, podría ser algo del cristal oscilador?
start movlw B'00100000' ;Pasamos al banco 1
movwf STATUS
clrf TRIS_B ;configuramos todos los pines del puerto B a modo de salida
movlw B'00011111'
movwf TRIS_A ;configuramos todos los pines del puerto A a modo de entrada
movlw B'10000111'
movwf OPTREG ;ponemos : pull-up del port B OFF
Saludos
 
Claro que si..
Tienes toda la razón!!!
Por cierto, sigo encallado, estoy seccionado el codigo por que me pasa una cosa curiosa,
con el 16F84A cuando llego hasta esta linea de codigo, las salidas me dan nivel bajo es decir GND,
y cuando uso el mismo codigo con el 16F628A no dan ese nivel, cosa que me parece del todo extraña,
todo esto lo pruebo con la misma placa, y no lo llego a entender, podría ser algo del cristal oscilador?
Código:
start
        movlw B'00100000' ;Pasamos al banco 1
        movwf STATUS
        clrf TRIS_B ;configuramos todos los pines del puerto B a modo de salida
        movlw B'00011111'
        movwf TRIS_A ;configuramos todos los pines del puerto A a modo de entrada
        movlw B'10000111'
        movwf OPTREG ;ponemos : pull-up del port B OFF
[B]        banksel   portb
        clrf   portb[/B]
Saludos

En las líneas que pasaste antes no hay nada que indique que el puerto b debe dar un valor 0, generalmente al arrancar dan un valor aleatorio si no me equivoco, por eso es práctica común limpiar los puertos al empezar.

El resto de las líneas de configuración parece bien, probá agregando las líneas en negrita

Saludos.
 
Hola de nuevo.
Me ha sido imposible probar la propuesta de Lord Chango, esta proxima semana lo cambiaré y os cuento.
Lo cierto es que la idea fué extraida de la pagina de Fo:LOL:elta, pero la version modificada para usar sin password. Esa versión me funciona correctamente con el PIC16F84A, pero ante la dficultad de conseguir ese PIC, y viendo que son del todo compatibles, se me ocurrió la idea de migrar el codigo, y así incluso desacerme del obsoleto PICSTART Plus, y programar con el PICKIt3 por ISCP.
Además de introducirme en la programación en assembler, pero me está costando.. ya que yo soy de soldador y resina...
Gracias a vosotros, sigo adelante con esta propuesta.
Un saludo y buen domingo
 
En realidad, para migrar ese programa a un 16F628A, no tiene mayor complicación.
Los fuses pueden ser los mismos porque se está usando oscilador a cristal.
La zona de memoria reservada para el 16F628A empieza en 0x20
Y como tiene comparadores análogos, tan sólo se configura el registro CMCON en el banco 0 con el valor 7.

Ese programa lo migré hace algunos años, también precisamente a un PIC16F628A y funcionó a la primera.
Ya que el 16F628A tiene oscilador interno, lo aproveché y no se notó ninguna diferencia.

Aquí el código modificado para un PIC16F628A, usando el oscilador interno:
PHP:
; DTMF.ASM - Tone decoder with relay control.

; reads output from an 8870 DTMF decoder and controls a bank of relays.
; 4 digit security code (abcd) precedes all commands 
; Code sequences "*abcd11#" through to "*abcd18#" turn on the corresponding relay
; code sequence "*abcd10#" turns on all relays
; Code sequences "*abcd21#" through to "*abcd28#" turn off the corresponding relay
; Code sequence "*abcd20#" turns off all relays
; Codes "*abcd?9#" through "*abcd?D#" are ignored.\
; Note "oa" is used for "0" in security code not"00"

    list        p=16f628a
    include        p16f628a.inc
    __config    _INTRC_OSC_NOCLKOUT  & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF
    errorlevel    -302

    cblock    0x20
        relays
        mfcode
        cntdown
        timeout
        slocnt1, slocnt2
        numa, numb, numc, numd
    endc

    org    0                    ; Tell assembler to start at 000H
    goto start
    org 4                    ; Interrupt vector

rtc_interrupt
    decfsz    slocnt1,F        ; Decrement 1st prescaler
    goto    rtc_int_1
    decfsz    slocnt2,F        ; Decrement 2nd prescaler
    goto    rtc_int_1
    bcf    relays,4            ; Turn relay 6 off
    bcf    PORTB,4
rtc_int_1
    decfsz    cntdown,F        ; Count down and skip next if = 0
    goto    counting        ; Still counting if not reached zero
    bsf    timeout,0            ; Set timed out bit
    bcf INTCON,2            ; Clear interrupt flag
    retfie                    ; Return from interrupt

counting
    bcf timeout,0            ; Clear timed out bit
    bcf INTCON,2            ; Clear interrupt flag
    retfie                    ; Return from interrupt

; Subroutines

wait_strobe
    btfsc    timeout,0        ; See if timed out
    goto    set_z            ; Set Z flag if timeout ocurred
    btfss    PORTA,4            ; See if Strobe is active on RA4
    goto    wait_strobe        ; Loop until it is
    movfw    PORTA            ; Retreive the code from the 8870
    movwf    mfcode            ; Store it in mfcode
    bcf    mfcode,4            ; Ensure strobe isn't seen as data
    bcf    STATUS,2            ; Return with Z=0 if tone decoded
    return

set_z
    bsf    STATUS,2            ; Return with Z=1 if timed out waiting
    return

wait_no_strobe
    btfsc    PORTA,4            ; See if strobe is active on RA4
    goto    wait_no_strobe    ; Loop until it isn't
    return

start_timer
    movlw    h'54'            ; Software prescaler for 7 seconds
    movwf    cntdown
    return


; Start of setup and decode routines:

start
    bsf        STATUS,RP0        ; Select register page 1
    clrf    TRISB            ; Set all port B pins to output mode
    movlw    b'10000111'
    movwf    OPTION_REG        ; Sets: pull-up on port B OFF
                            ; RTCC counts internal clock
                            ; Prescaler connected to RTCC
                            ; Prescaler divides by 256
                            ; (Other bits unimportant)

    bcf        STATUS,RP0        ; switch back to register page 0
    movlw    0x07
    movwf    CMCON            ; Puts comparators off.
    clrf    PORTB            ; All outputs off
    clrf    relays
    clrf    timeout
    movlw    b'10100000'
    movwf    INTCON            ; Global and RTCC interrupts enabled

set_sec
    movlw    1                ; Put the 4 access codes into memory
    movwf    numa            ; Note for a 0 the hex is H'0A'
    movlw    2
    movwf    numb
    movlw    3
    movwf    numc
    movlw    4
    movwf    numd

decode
    call    wait_no_strobe    ; Start running when no tone present
    clrf    timeout            ; Set timeout condition until later
    call    wait_strobe        ; Wait for a tone to be received
    movlw    h'0B'            ; 0B is the code for DTMF "*"
    subwf    mfcode,W        ; Set zero flag if "*" was received
    btfsc    STATUS,2        ; Skip next if it was not a "*"
    goto    got_star
    goto    decode            ; Look for another one

got_star
    call    start_timer        ; Start time-out timer
    call    wait_no_strobe    ; Wait for second tone
    call    wait_strobe
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode
    movf    numa,W
    subwf    mfcode,W        ; Set zero flag if second tone was 1
    btfsc    STATUS,2        ; Skip next if it was not a 1
    goto    got_A
    goto    get_#

got_A
    call    wait_no_strobe    ; Wait for third tone
    call    wait_strobe
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode
    movf    numb,W
    subwf    mfcode,W        ; Set zero flag if second tone was 1
    btfsc    STATUS,2        ; Skip next if it was not a 1
    goto    got_B
    goto    get_#

got_B
    call    wait_no_strobe    ; Wait for third tone
    call    wait_strobe
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode
    movf    numc,W
    subwf    mfcode,W        ; Set zero flag if second tone was 1
    btfsc    STATUS,2        ; Skip next if it was not a 1
    goto    got_C
    goto    get_#

got_C
    call    wait_no_strobe    ; Wait for third tone
    call    wait_strobe
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode
    movf    numd,W
    subwf    mfcode,W        ; Set zero flag if second tone was 1
    btfsc    STATUS,2        ; Skip next if it was not a 1
    goto    got_D
    goto    get_#

got_D
    call    wait_no_strobe    ; Wait for third tone
    call    wait_strobe
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode
    
    movlw    1
    subwf    mfcode,W        ; Set zero flag if second tone was 1
    btfsc    STATUS,2        ; Skip next if it was not a 1
    goto    got_1
    
    movlw    2
    subwf    mfcode,W        ; Set zero flag if second tone was 0
    btfsc    STATUS,2        ; Skip next if it was not a 0
    goto    got_2
    goto    get_#            ; Wait for # to end invalid sequence



; To reach here, the tone sequence "*<numa><numb><numc><numd>1" has been found, now decode request
; According to the next 2 tones but don't action it until a "#" is seen.

got_1
    call    wait_no_strobe
    call    wait_strobe        ; Wait for third tone
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode

    call    wait_no_strobe    ; Wait for tone to finish
    movf    mfcode,W        ; Pick up keyed digit
    addwf    PCL,F            ; Jump ahead to vector
    goto    decode            ; 5D (mf code 0000)
    goto    got_11
    goto    got_12
    goto    got_13
    goto    got_14
    goto    got_15
    goto    got_16
    goto    got_17
    goto    got_18
    goto    decode
    goto    got_10
    goto    decode            ; *
    goto    decode            ; #
    goto    decode            ; 5A
    goto    decode            ; 5B
    goto    decode            ; 5C (mf code 1111)

got_10
    movlw    b'11111111'        ; All outputs on
    movwf    relays
    goto    get_#


got_11
    bsf    relays,0            ; Set output 1 on
    goto    get_#
got_12
    bsf    relays,1            ; Set output 2 on
    goto    get_#
got_13
    bsf relays,3            ; Set output 3 on
    goto    get_#
got_14
    bsf    relays,2            ; Set output 4 on
    goto    get_#
got_15
    bsf    relays,5            ; Set output 5 on
    goto get_#
got_16
    bsf    relays,4            ; Set output 6 on
    goto    get_#
got_17
    bsf relays,6            ; Set output 7 on
    goto    get_#
got_18
    bsf    relays,7            ; Set output 8 on
    goto    get_#

; To reach here, the tone sequence "*<numa><numb><numc><numd>2" has been found, now decode request
; According to the next 2 tones but don't action it until a "#" is seen.

got_2
    call    wait_no_strobe
    call    wait_strobe        ; Wait for sixth tone
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode

    call    wait_no_strobe    ; Wait for tone to finish
    movf    mfcode,W        ; Pick up keyed digit
    addwf    PCL,F            ; Jump ahead to vector
    goto    decode            ; 5D (mf code 0000)
    goto    got_21
    goto    got_22
    goto    got_23
    goto    got_24
    goto    got_25
    goto    got_26
    goto    got_27
    goto    got_28
    goto    decode
    goto    got_20
    goto    decode            ; *
    goto    decode            ; #
    goto    decode            ; 5A
    goto    decode            ; 5B
    goto    decode            ; 5C (mf code 1111)

got_20
    clrw
    movwf    relays            ; Set all outputs off
    goto    get_#
got_21
    bcf    relays,0            ; Set output 1 off
    goto    get_#
got_22
    bcf relays,1            ; Set output 2 off
    goto    get_#
got_23
    bcf    relays,3            ; Set output 3 off
    goto    get_#
got_24
    bcf relays,2            ; Set output 4 off
    goto    get_#
got_25
    bcf relays,5            ; Set output 5 Off
    goto    get_#
got_26
    bcf relays,4            ; Set output 6 Off
    goto    get_#
got_27
    bcf    relays,6            ; Set output 7 Off
    goto    get_#
got_28
    bcf    relays,7            ; Set output 8 Off
    goto    get_#
get_#
    call    wait_strobe        ; Wait for 7th tone
    btfsc    STATUS,2        ; Abort if timed out
    goto    decode

    movlw    h'0C'            ; 0C is the DTMF code for "#"
    subwf    mfcode,W        ; If # received set Z flag
    btfsc    STATUS,2        ; Skip next if not a #
    goto    got_#
    call    wait_no_strobe
    goto    get_#            ; Only # is valid, loop until found or timeout

got_#
    call    wait_no_strobe    ; Wait for the tone to finish
    movfw    relays            ; Use the "relays" variable to set RB
    movwf    PORTB
    goto    decode            ; All done, check for new sequence

;    retlw 'v'
;    retlw '1'
;    retlw '.'
;    retlw '3'
;    retlw '.'
;    retlw 'W'
;    retlw 'W'
;    retlw '2'
;    retlw 'R'
;    retlw ' '
;    retlw 'm'
;    retlw 'a'
;    retlw 'y'
;    retlw '2'
;    retlw '0'
;    retlw '0'
;    retlw '0'

    end
Las últimas instrucciones retlw 'x', no están dentro del programa, viene siendo la firma del autor, así que se pueden comentar sin ningún problema.
 
Hola de nuevo,

He realizado las pruebas propuestas por Lord Chango, sin exito.
Y lo cierto es que tiene logica pero, no hay manera.....!!!!

Luego he probado el codigo de D@rkbytes, y se sigue comportando de la misma manera,
da la sensación de que el programa dentro del pic no arranca, he tenido en cuenta de desconectar el cristal de 3.5795 Mhz, y utilizar el interno del pic, y nada todo igual.
Lo cierto es que tengo dos 16F84A y les hago de todo y siempre me funcionan, y en cambio
con los 16F628A, no hay manera, los he programado con el Picstar Plus y con el Pickit3,
he borrado con la opción de "Erase Flash Device" y nada de nada.
Adjunto os envio foto de la placa que estoy usando de proto.
No se por donde puede venir el problema, según D@rkbytes, a el le funcionó sin problema en el
16F628A.
Que puedo estar haciendo mal.....???
Gracias
 

Adjuntos

  • PCB-DTMF.jpg
    PCB-DTMF.jpg
    111.5 KB · Visitas: 15
El programa que subí está funcionando perfectamente y con el oscilador interno.

¿A qué velocidad estás introduciendo la secuencia de tonos DTMF?
Deben introducirse algo rápido para que sea válida la comprobación de la secuencia.

Para comprobar el funcionamiento, usé un teléfono celular para ingresar los tonos DTMF.
Tuve que ingresar la secuencia manualmente lo más rápido que pude, para que se validara.

PD: Ten cuidado con esos relevadores, porque son de muy baja corriente.
Si te excedes, los puedes dañar y se quedarán pegados los contactos.
 
Última edición:
Hola D@rkbytes.
La secuencia de tonos, la envio de diferentes maneras:
1: Mediante un software llamado DTMF Dial Tone Generator 1.0, con los siguientes parametros



Tone Time ms 95
Breack time ms 95
Me funciona correctamente con el 16F84A.
2: Mediante un generador de radiotest Marconi que se usa para reparar equipos de radio.
3: Mediante un receptor de uhf y un emisor..
De cualquier manera que pruebo, siempre me funciona bien con el 16F84A.
Para grabar los pic uso el Pic Start plus, y para el 16F628A el pickit3.
Como entorno de programación, uso Mplab IDE v8.91.
En fin, no se si me dejo algo...
Gracias
 
Última edición:
Hola D@rkbytes.
La secuencia de tonos, la envio de diferentes maneras:
1: Mediante un software llamado DTMF Dial Tone Generator 1.0, con los siguientes parametros



Tone Time ms 95
Breack time ms 95
Me funciona correctamente con el 16F84A.
2: Mediante un generador de radiotest Marconi que se usa para reparar equipos de radio.
3: Mediante un receptor de uhf y un emisor..
De cualquier manera que pruebo, siempre me funciona bien con el 16F84A.
Para grabar los pic uso el Pic Start plus, y para el 16F628A el pickit3.
Como entorno de programación, uso Mplab IDE v8.91.
En fin, no se si me dejo algo...
Gracias

C8 de 100nF lo tenes puesto del lado del PCB con conexiones cortas entre los pines 5 y 14 del PIC?...en placas de ese tipo, el "ruido" puede ser un "dolor de cabeza" debido a la falta de buenos planos de tierra para su descarga/circulación y el cableado.

Ric.
 
Atrás
Arriba