Autor Tema: Problema con funcionamiento pic16c505  (Leído 2843 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado alegallos

  • PIC10
  • *
  • Mensajes: 3
Problema con funcionamiento pic16c505
« en: 30 de Diciembre de 2014, 13:27:06 »
Hola, buenas tardes.
Tras leer unos cuantos post, me he decidido a escribir por unas pequeñas dudas. Estoy haciendo un pequeño programa que al recibir un 0 o un 1 en la entrada cambie las salidas, en un principio en el mplab me funciona correctamente, pero al grabarlo y probarlo en la placa no funciona.
He leido que puede ser cosa del oscilador, estoy usando el interno del pic, cosa que no he hecho nunca, ya que trabajaba con pic16f84 y no lo tenia. Tras leer eso, he buscado como configurarlo y pone que tengo que leer el pic primero y buscar en la ultima dirección y grabarla en osccal, pero no me queda muy claro. Pongo el asm que funciona en el mplab y no en la placa, es muy sencillo y seguro que tiene cosas raras pero es que soy principiante y no tengo mucha idea.

Mi duda es si tengo mal configurado el oscilador o es otra cosa.

Muchas gracias


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema con funcionamiento pic16c505
« Respuesta #1 en: 30 de Diciembre de 2014, 18:23:20 »
AL comienzo del programa deberias tener algo asi:

 __CONFIG _OSC_IntRC_RB4EN & _WDT_OFF & _CP_OFF & _MCLRE_OFF

Donde configuras los FUSES ( los bits de configuracion ) Con esto asigna el uso del oscilador interno y RB4 es una entrada/salida, desactiva el WDT, desactiva la proteccion de codigo y pone internamente el MCLR a VCC para que puedas usar ese pin como entrada salida. El listado de esos valores estan en el archivo P16C505.INC

Código: [Seleccionar]
;----- CONFIG Options --------------------------------------------------
_OSC_LP              EQU  H'0FF8'    ; LP oscillator
_LP_OSC              EQU  H'0FF8'    ; LP oscillator
_OSC_XT              EQU  H'0FF9'    ; XT oscillator
_XT_OSC              EQU  H'0FF9'    ; XT oscillator
_OSC_HS              EQU  H'0FFA'    ; HS oscillator
_HS_OSC              EQU  H'0FFA'    ; HS oscillator
_OSC_IntRC_RB4EN     EQU  H'0FFC'    ; Internal RC No Clock
_IntRC_OSC_RB4EN     EQU  H'0FFC'    ; Internal RC No Clock
_OSC_IntRC_CLKOUTEN  EQU  H'0FFD'    ; Internal RC Clockout
_IntRC_OSC_CLKOUTEN  EQU  H'0FFD'    ; Internal RC Clockout
_OSC_ExtRC_RB4EN     EQU  H'0FFE'    ; External RC No Clock
_ExtRC_OSC_RB4EN     EQU  H'0FFE'    ; External RC No Clock
_OSC_ExtRC_CLKOUTEN  EQU  H'0FFF'    ; External RC Clockout
_ExtRC_OSC_CLKOUTEN  EQU  H'0FFF'    ; External RC Clockout

_WDT_OFF             EQU  H'0FF7'    ; WDT disabled
_WDT_ON              EQU  H'0FFF'    ; WDT enabled

_CP_ON               EQU  H'002F'    ; Code protection on
_CP_OFF              EQU  H'0FFF'    ; Code protection off

_MCLRE_OFF           EQU  H'0FDF'    ; RB3/MCLR pin function is digital I/O, MCLR internally tied to VDD
_MCLRE_ON            EQU  H'0FFF'    ; RB3/MCLR pin function is MCLR

Desconectado alegallos

  • PIC10
  • *
  • Mensajes: 3
Re: Problema con funcionamiento pic16c505
« Respuesta #2 en: 30 de Diciembre de 2014, 18:33:02 »
AL comienzo del programa deberias tener algo asi:

 __CONFIG _OSC_IntRC_RB4EN & _WDT_OFF & _CP_OFF & _MCLRE_OFF

Donde configuras los FUSES ( los bits de configuracion ) Con esto asigna el uso del oscilador interno y RB4 es una entrada/salida, desactiva el WDT, desactiva la proteccion de codigo y pone internamente el MCLR a VCC para que puedas usar ese pin como entrada salida. El listado de esos valores estan en el archivo P16C505.INC

Código: [Seleccionar]
;----- CONFIG Options --------------------------------------------------
_OSC_LP              EQU  H'0FF8'    ; LP oscillator
_LP_OSC              EQU  H'0FF8'    ; LP oscillator
_OSC_XT              EQU  H'0FF9'    ; XT oscillator
_XT_OSC              EQU  H'0FF9'    ; XT oscillator
_OSC_HS              EQU  H'0FFA'    ; HS oscillator
_HS_OSC              EQU  H'0FFA'    ; HS oscillator
_OSC_IntRC_RB4EN     EQU  H'0FFC'    ; Internal RC No Clock
_IntRC_OSC_RB4EN     EQU  H'0FFC'    ; Internal RC No Clock
_OSC_IntRC_CLKOUTEN  EQU  H'0FFD'    ; Internal RC Clockout
_IntRC_OSC_CLKOUTEN  EQU  H'0FFD'    ; Internal RC Clockout
_OSC_ExtRC_RB4EN     EQU  H'0FFE'    ; External RC No Clock
_ExtRC_OSC_RB4EN     EQU  H'0FFE'    ; External RC No Clock
_OSC_ExtRC_CLKOUTEN  EQU  H'0FFF'    ; External RC Clockout
_ExtRC_OSC_CLKOUTEN  EQU  H'0FFF'    ; External RC Clockout

_WDT_OFF             EQU  H'0FF7'    ; WDT disabled
_WDT_ON              EQU  H'0FFF'    ; WDT enabled

_CP_ON               EQU  H'002F'    ; Code protection on
_CP_OFF              EQU  H'0FFF'    ; Code protection off

_MCLRE_OFF           EQU  H'0FDF'    ; RB3/MCLR pin function is digital I/O, MCLR internally tied to VDD
_MCLRE_ON            EQU  H'0FFF'    ; RB3/MCLR pin function is MCLR
[/
Muchas gracias, mañana pruebo esto que me comentas y te cuento. Por otro lado sabes algo de configurar la velocidad del odcilador? Lo que comentaba del último bit

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema con funcionamiento pic16c505
« Respuesta #3 en: 30 de Diciembre de 2014, 18:43:58 »
Estaba viendo en tu programa que usas:

MOVWF   OSCCAL

En el vector de reset, y que no se sabe el valor de W en ese momento. Ademas  seria algo asi:

Código: [Seleccionar]
ORG 0x00
GOTO INICIO

ORG 0x04 ; Vector de interrupcion
GOTO INICIO ; en caso que no lo uses

INICIO
; Aca configuras lo que quieras.

En fin. Cambiar la frecuencia en este microcontrolador no vas a poder, como el oscilador interno es producido por un RC tiene variaciones de la freceuncia central de 4Mhz ( no es exacto ) y con ese registro vos podes dezplazar la frecuencia para que quede exacto 4Mhz a la temperatura deseada ( OSCCAL - Oscillator Calibration ? ), pero si no necesitas de un valor exacto seria mejor usar un cristal externo.

Este PIC no posee divisores/PLL internos asi que tampoco vas a poder modificar la frecuencia de lo que le pongas.

Eso conrespecto al clock, y por otra parte que manera de usar GOTO! hay uan cantidad impresionante de estos, creo que el 40 % de las lineas son GOTO a simple vista.

Desconectado alegallos

  • PIC10
  • *
  • Mensajes: 3
Re: Problema con funcionamiento pic16c505
« Respuesta #4 en: 30 de Diciembre de 2014, 18:50:44 »
Estaba viendo en tu programa que usas:

MOVWF   OSCCAL

En el vector de reset, y que no se sabe el valor de W en ese momento. Ademas  seria algo asi:

Código: [Seleccionar]
ORG 0x00
GOTO INICIO

ORG 0x04 ; Vector de interrupcion
GOTO INICIO ; en caso que no lo uses

INICIO
; Aca configuras lo que quieras.

En fin. Cambiar la frecuencia en este microcontrolador no vas a poder, como el oscilador interno es producido por un RC tiene variaciones de la freceuncia central de 4Mhz ( no es exacto ) y con ese registro vos podes dezplazar la frecuencia para que quede exacto 4Mhz a la temperatura deseada ( OSCCAL - Oscillator Calibration ? ), pero si no necesitas de un valor exacto seria mejor usar un cristal externo.

Este PIC no posee divisores/PLL internos asi que tampoco vas a poder modificar la frecuencia de lo que le pongas.

Eso conrespecto al clock, y por otra parte que manera de usar GOTO! hay uan cantidad impresionante de estos, creo que el 40 % de las lineas son GOTO a simple vista.

[/
Si, ya comentaba que no tengo mucha idea de programar, me imagino que habrá una forma mucho más sencilla de hacerlo pero tendrá que ser poco a poco, jajaj. Muchas gracias por contestarme. Entiendo que lo mejor es que no ponga nada de osccal y deje que la frecuencia varíe. Temo que usar el odcilador interno, eso es seguro. Entiendo que ese odcilador interno no necesita una resistencia y condensador externos verdad?.

Otra vez muchas gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema con funcionamiento pic16c505
« Respuesta #5 en: 30 de Diciembre de 2014, 19:31:13 »
Exactamente. El oscilador interno no necesitas ningun componente externo ( cristal o RC ) Y podes usar esos pines (RB5/OSC1/CLKIN y RB4/OSC2/CLKOUT) como salidas si los configuras como tal en los fuses.

La frecuencia va a ser "fija" en el unico caso que importaria esa desviacion de la frecuencia si es que tuvieras que hacer algo en X cantidad de tiempo exacto, ejemplo hacer titilar un led a 1Hz, y que sea exactamente 0.5s apagado y 0.5s encendido. pero si no te importa que pueda ser 0.49s y 0.49s entonces dale para adelante con eso.

Por ahi vi que tenes algunos problemas, con tantos GOTO cuando usas CALL por ahi no retorna y ese direccion queda guardada en el stack que luego con la intruccion RETURN o RETLW vuelve a la direccion, en este PIC tiene 2 niveles de stack ( guarda hasta 2 direcciones) Tu programa deberia asegurarse que que cuando se llama a un CALL el fin siempre sea un RETURN y o maximo que deberia ocurrir es:

CALL
  ....
  CALL
     ....
  RETURN
  ...
RETURN

Es decir 2 call anidados.
Para que te des cuenta donde hay un error miraria en tu codigo en NIVALTO,

este hace un CALL a SUB3 aca hay 2 opciones, una produce otro call y con un return ( lo cual seguirias teniendo 1 direccion guardad del primer call )
La otra es que siga y VUELVA a NIVALTO y se produzca otro CALL, entrando en un loop continuo. ( ya tenes 2 direcciones y tu stack esta lleno si pones otra ya no hay posibilidades de retornar.


Citar
SUB3        BTFSS   PORTB,2
            CALL    SUB1
            BTFSC   PORTB,1
            GOTO    NIVALTO
            BSF     PORTC,0
            GOTO    NIVALTO
            RETLW   
0

Lo que esta en negrita JAMAS se va a ejecutar, por que el GOTO lo envia a otro lado y es imposible que pase por ahi, hay otras funciones que tambien hacen lo mismo.

Otra de las cosas es que en fisico el micro va a una velocidad alta y no pausado como la simulacion en MPLAB, a 4Mhz el micro ejecuta cada instruccion a 1uS, esto lleva a tener consideracion cuando tenes una condicion como estas:

BTFSS   PORTB,2

Ya que en simulacion puede pasar 1 ves por ese punto, pero en real en un abrir y cerrar de ojos paso muchas veces mas.

Para la programacion Creo por mi parte que es mejor siempre tener una funcion principal y de esta irse a otros lados segun algunas condiciones.

Principal:
PORTA,1 en 1?
Call funcion1
PORTA,0 en 1?
CALL funcion0
PORTA,3 en 0
CALL funcion3
CALL Mostrar
Goto Principal

Luego de ahi  cada funcion va a realizar su codigo y va a retornar al programa principal, en estas funciones tambien se puede llamar a otra funcion sin ningun problema siempre y cuando retorne

funcion0:
   Prender led1
   CALL Demora
   Volver del call

Demora:
   Hago la demora
   Volver del call


Es decir hace funciones especificas para cada cosa, obviamente si es una sola instruccion no vale la pena hacer un call ( como en tu codigo en ESENx ) sino algo que tenga muchas instrucciones o se use en varios lados ( como la demora )

Creo que es todo lo que encontre. Cualquier otra duda preguntala sin problemas
Ah y no hace falta que me quotees :3 sino se va a hacer largo, solamente responde a no ser que tengas una seccion que quiseras preguntar xD