TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: PulKon en 09 de Abril de 2013, 20:22:04
-
Estoy usando el PIC12F629 para generar una forma de onda que consiste en dar pulsos de 24ms en estado alto, 112ms en estado bajo cíclicamente durante aproximadamente 60 segundos y da otro en estado alto durante 750ms. y se repite constantemente.
Verificado con el Stopwatch del MPLAB me da 59.978910 segundos y cronometrado da 45 segundos.
No se ha modificado el OSCCAL porque uso el PICkit 2 y conserva su valor.
¿Por qué da tanto error?
Agradeceré me comenten sobre una posible solución.
Esto es el principio del programa:
;-------------------------------------------------------------------------------------
list p=12F629 ; Define el microcontrolador utilizado.
#include P12F629.inc ; Definición de las variables especificas del PIC
__CONFIG _MCLRE_OFF & _CP_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT ; Oscilador Interno.
;-------------------------------------------------------------------------------------
; Definición de variables.
;-------------------------------------------------------------------------------------
CBLOCK H'20'
PDel0 ; Seleccion de posiciones de la RAM para estos Registros
PDel1 ; para las temporizaciones.
PDel2
PDel3
PDel4
PDel5
PDel6
ONDAS1 ; Registro utilizado para el conteo de ondas
ONDAS2 ; Registro utilizado para el conteo.
ENDC
#define OPTOS GPIO,4 ; Define OPTOS como bit 2 GPIO.
#define LR GPIO,2 ; Define LR como bit 4 GPIO.
errorlevel -302 ; Elimina en MPLAB la advertencia de verificacion del banco.
;-------------------------------------------------------------------------------------
; Zona de código.
;-------------------------------------------------------------------------------------
Reset org 0x00 ; Aquí comienza el micro.
goto Inicio ; Salto a inicio de mi programa.
;-------------------------------------------------------------------------------------
; Configuración de puertos.
;-------------------------------------------------------------------------------------
org 0x05 ; Origen del código de programa.
Inicio
bsf STATUS,RP0 ; Acceso Banco 1.
; movlw b'110101' ; Carga w.
; movwf TRISIO ; Configura entradas y salidas.
call 3FFh ; Get the cal value
movwf OSCCAL ; Calibrate
bcf OPTOS ; Otra forma de hacerlo, OPTOS como salida.
bcf LR ; LR como salida.
bcf STATUS,RP0 ; Acceso Banco 0.
;-------------------------------------------------------------------------------------
; Condiciones iniciales.
;-------------------------------------------------------------------------------------
-
Hola no pusiste la rutina de retardo, como haces para saber los tiempos? Usa esta libreria de retardos que anda
-
Gracias soymoe, usé el programa del foro para la determinación de los retardos, este es el programa:
;-------------------------------------------------------------------------------------
; Programa principal.
;-------------------------------------------------------------------------------------
Continua
bsf OPTOS ; OPTOS=1 que corresponde al pulso de refuerzo.
call t750ms ; Deja encendido durante 750ms.
bcf OPTOS ; OPTOS=0 ahora se apaga, cada 60 seg. se realiza esto.
call PulsosControl ; Llama subrutina PulsosControl, que consiste en la
goto Continua ; generación de tren de pulsos: 112ms bajo y 24ms alto.
;-------------------------------------------------------------------------------------
; Subrutina "PulsosControl". Se generan 441 ondas de 112ms + 24ms para dar 60seg.
;-------------------------------------------------------------------------------------
PulsosControl
bcf OPTOS ; OPTOS=0 inicia en estado bajo.
call t112ms ; Valor que corresponde al estado bajo de la onda de
bsf OPTOS ; de control, después se enciende, OPTOS=1.
call t24ms ; Valor para el estado alto de la onda.
bcf OPTOS ; OPTOS=0, lo vuelve a apagar.
movlw .44 ; Carga w con 44 para ONDAS1
movwf ONDAS1
movlw .10 ; Carga w con 10 para ONDAS2
movwf ONDAS2 ; Así se obtienen 440 ondas mas una inicial.
Generando
bcf OPTOS ; OPTOS=0, asegura que este apagado.
call t112ms ; Asi permanece 112ms. Estado bajo.
bsf OPTOS ; OPTOS=1.
call t24ms ; Así permanece 24ms. Estado alto.
bcf OPTOS ; OPTOS=0, lo vuelve a apagar.
decfsz ONDAS2,1 ; Decrementa ONDAS2 y pregunta si es 0?
goto Generando ; No es cero, regresa a seguir generando.
decfsz ONDAS1,1 ; Si es 0, termino ese bucle, decrementa ONDAS1.
goto ReestableceONDAS2 ; No es 0 aún, entonces reestablece valor de ONDAS2.
goto Retorna ; Regresa al programa principal, termina la subrutina.
ReestableceONDAS2
movlw .10 ; Carga w con 10 para ONDAS2
movwf ONDAS2 ; Así se obtienen 440 ondas mas una.
goto Generando
Retorna
return
;-------------------------------------------------------------------------------------
; Subrutina "t750ms"
;-------------------------------------------------------------------------------------
t750ms
movlw .241 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLoop0 movlw .7 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLoop1 movlw .110 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------------------------------
; Subrutina "t24ms"
;-------------------------------------------------------------------------------------
t24ms
movlw .31 ; 1 set numero de repeticion (B)
movwf PDel3 ; 1 |
PLoop11 movlw .154 ; 1 set numero de repeticion (A)
movwf PDel4 ; 1 |
PLoop21 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel4, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop21 ; 2 no, loop
decfsz PDel3, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop11 ; 2 no, loop
clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------------------------------
; Subrutina "t112ms"
;-------------------------------------------------------------------------------------
t112ms
movlw .65 ; 1 set numero de repeticion (B)
movwf PDel5 ; 1 |
PLoop12 movlw .191 ; 1 set numero de repeticion (A)
movwf PDel6 ; 1 |
PLoop22 clrwdt ; 1 clear watchdog
PDelL12 goto PDelL22 ; 2 ciclos delay
PDelL22 goto PDelL32 ; 2 ciclos delay
PDelL32 clrwdt ; 1 ciclo delay
decfsz PDel6, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop22 ; 2 no, loop
decfsz PDel5, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop12 ; 2 no, loop
return ; 2+2 Fin.
;-------------------------------------------------------------------------------------
end
-
Este programa adaptado para el PIC16F628A funciona muy bien, pero para el PIC12F629 tiene un error muy grande, porque no está trabajando su oscilador interno a la frecuencia de 4MHz. esta mas alta su frecuencia porque esta dando menores tiempos.
Programé 10 PIC12F629 y en todos se presenta esta variación del tiempo.
Podría cambiar los datos de las subrutinas de tiempo y lograría dar lo que se desea pero la duda es porque no respeta los tiempos como debe ser.
Quizá me falte alguna instrucción o puse una configuración mal, el problema es que no se cual es.
Si alguien sabe, por favor coméntenlo.
Saludos.
-
Hola, el reloj interno de esta familia de 12F629 y 12F675 es demasiado inexacto de ahí que no sirve para hacer comunicaciones asíncronas, si requieres tiempos exactos , obviamente hay que hacer una buena rutina de tiempos, debes utilizar cristal externo, otra alternativa es que te pases a la versión mejorada de estos PIC, 12F1822 por ejemplo, su reloj interno si te garantiza mucha precisión.
Saludos.
-
Gracias Diego.
Voy a probar con el PIC12F1822 que me recomiendas, ya solicité unas muestras.
Saludos.
-
Ya tengo el PIC, voy a pasar el programa a este y comento los resultados.
-
Hola, el reloj interno de esta familia de 12F629 y 12F675 es demasiado inexacto de ahí que no sirve para hacer comunicaciones asíncronas, si requieres tiempos exactos , obviamente hay que hacer una buena rutina de tiempos, debes utilizar cristal externo, otra alternativa es que te pases a la versión mejorada de estos PIC, 12F1822 por ejemplo, su reloj interno si te garantiza mucha precisión.
Saludos.
como?.Pero, si segun el datasheet el oscilador esta calibrado. El problema es que rutina usas para el retardo.