TODOPIC
FORO TÉCNICO => Foro Técnico => Mensaje iniciado por: juaperser1 en 08 de Enero de 2020, 18:21:30
-
¿Alguien que me pueda explicar en que consiste este proceso de calibración?
Lo poco que encuentro es solo en el "reference manual" y no termino de entenderlo. Trabajo con un STM32G030 y un reloj externo de 32,768KHz y el rtc se me adelanta 8 segundos diarios.
Por lo que veo es que hay que calibrarlo.
Pero no veo como y tampoco encuentro como hacerlo, ni en los ejemplos de ST ni de nadie, solo he encontrado una cosa bastante vieja que utiliza librerias antiguas y que es bastante dificil de leer, por que no puedo abrirlo en el STM32CubeIDE (antiguo atollic).
En el caso de que esto sea muy difícil, ¿me aconsejais mejor colocar un rtc externo? los externos hay que calibrarlos o vienen calibrados de fabrica?
un saludo.
-
Lo que tenes de "calibracion" es el trimming de los osciladores internos, el oscilador externo no se puede calibrar (por software).
Generalmente estos osciladores internos varian bastante la frecuencia con el voltaje y con la temperatura. Asi que usualmente si tenes algun reloj externo podes calibrarlo, es decir modificar apenas la frecuencia con el trimming para que en 1 ciclo del reloj externo entre justos los 100 ciclos internos (un ejemplo). De esa forma calibrarlo.
Es de observarse que si o si se requiere un reloj externo estable y mientras mas preciso/exacto mejor. Pero si usas un reloj que varia en frecuencia entonces no hay forma de calibrarlo a los internos :P.
Ajustar un reloj externo no es posible mas alla del cristal, sino sera problemas del layout del cristal.
-
esto es lo que quiero hacer:
Generalmente estos osciladores internos varian bastante la frecuencia con el voltaje y con la temperatura. Asi que usualmente si tenes algun reloj externo podes calibrarlo, es decir modificar apenas la frecuencia con el trimming para que en 1 ciclo del reloj externo entre justos los 100 ciclos internos (un ejemplo). De esa forma calibrarlo.
tengo un reloj externo de 32.768 Khz con un rutado, aconsejado por el fabricante y con unos condensadores de 6,8pF.
Y aunque entiendo el procedimiento, no se llevarlo a cabo, esto es lo que me dice el reference manual, pero no se como plasmarlo a C, a ver si alguien me echa una mano en eso o sabe de algun ejemplo de aplicación de ST o algo:
RTC smooth digital calibration
The RTC frequency can be digitally calibrated with a resolution of about 0.954 ppm with a
range from -487.1 ppm to +488.5 ppm. The correction of the frequency is performed using
series of small adjustments (adding and/or subtracting individual RTCCLK pulses). These
adjustments are fairly well distributed so that the RTC is well calibrated even when observed
over short durations of time.
The smooth digital calibration is performed during a cycle of about 220 RTCCLK pulses, or
32 seconds when the input frequency is 32768 Hz. This cycle is maintained by a 20-bit
counter, cal_cnt[19:0], clocked by RTCCLK....
punto 23.3.13 de la pagina 645.
https://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/fd/a3/20/58/ac/b0/48/23/DM00463896/files/DM00463896.pdf/jcr:content/translations/en.DM00463896.pdf
-
Tal ves este PDF te ayude a entenderle:
https://www.st.com/content/ccc/resource/technical/document/application_note/group0/71/b8/5f/6a/8e/d5/45/0a/DM00226326/files/DM00226326.pdf/jcr:content/translations/en.DM00226326.pdf
Supuestamente tenes ejemplos, aplicados a microcontroladores ST.
Estoy intentando ayudarte en el poco tiempo que poseo juaperser, disculpa que no me pueda poner a investigar y explicarte las cosas, realmente no tengo demasiado tiempo.
-
Tal ves este PDF te ayude a entenderle:
https://www.st.com/content/ccc/resource/technical/document/application_note/group0/71/b8/5f/6a/8e/d5/45/0a/DM00226326/files/DM00226326.pdf/jcr:content/translations/en.DM00226326.pdf
Supuestamente tenes ejemplos, aplicados a microcontroladores ST.
Estoy intentando ayudarte en el poco tiempo que poseo juaperser, disculpa que no me pueda poner a investigar y explicarte las cosas, realmente no tengo demasiado tiempo.
No te preocupes, ayuda lo que puedas y cuando puedas y si quieres claro, yo te lo agradezco.
Este documento no lo había visto, había visto otro mas antiguo, voy a leermelo y a ver que saco en claro, a ver si esta tarde puedo postear algún avance.
muchas gracias.
-
A ver despues de leerme el documento este veo que existen varias formas:
existen dos registros para sumar o enmascarar pulsos del reloj y así ajustar la frecuencia, el CALP y el CALM del registro RTC_CALR
estos pulsos se suman o restan por ventanas de 32 segundos (aunque pueden ser de 16 u 8 tambien si los configuras pero por defecto 32)
El problema es como medir este error, el documento dice que para verificarlo puedo usar la salida de 1Hz, Alarmas de menos de 1 seg, o el temporizar de wake up.
Vale para calibrar uno mediria la salida de 1 Hz con un osciloscopio y lo haría a mano, pero que pasa si quiero hacer 2000 sistemas iguales? no puedo hacerlos uno a uno.
Si realimento el pin de 1Hz por otro pin y lo capturo con un timer, estoy también metiendo el error del reloj del sistema, no se si esto es buena idea.
luego hay otro registro, que sirve para sumar o restar segundos el "RTC shift" este lo pones tu manualmente por lo que entiendo.
¿cual seria la mejor manera de proceder?
En el ejemplo, necesitas una señal de 1Hz externa para calibrar el sistema, no creo que sacarla de otra para del micro sea correcto por que tendrá incluso mas error, pero para un aparato del que se vayan a fabricar cientos o miles no me parece muy lógico tener que hacer esto uno a uno ademas de tener que esperar 32 segundos a que se calibre cada uno.
y añadir un sistema que de una señal de 1Hz exacta tampoco me parece que sea la solucion ya que encarece el sistema,
The application is based on the following four steps:
1. A 1 Hz reference clock is connected to TIM3 through the PD2 GPIO.
2. TIM3 is configured to generate a rising edge after 32 x 1 Hz reference rising edges.
This gives an event every 32 seconds.
3. TIM2 is configured to increment its counter on CLK_RTC, to get the counter value on
the rising edge generated by TIM3 and to store it in the TIM2_CCR1 register. It then
reset itself.
4. The Cortex®-M4 core gets the TIM2_CCR1 value, compares it with the number of
CLK_RTC cycles expected in 32 seconds and processes the comparison results to
update the CALP and CALM fields of the RTC_CALR register.
The calibration is continuous.
un saludo.
-
Estuve leyendo y tratando de entender lo que plantea el documento.
La calibración es para cuando tengas un oscilador que NO es demasiado exacto. Tal como el LSE del micro.
Y siempre necesitas una referencia externa y precisa, que seria tu oscilador externo.
El problema es que creo que estas planteando "corregir" lo que te presenta el cristal de 32KHz, y para eso necesitas otro oscilador externo MEJOR que el anterior.
Encima tenes desviaciones de frecuencia por temperatura y voltajes por lo tanto como bien dice al ultimo, este proceso de calibracion debe ser continuo y no solo una ves al inicio.
¿A que lleva a esto?
Que si o si uses un oscilador externo "bueno". No queda otra.
ademas de tener que esperar 32 segundos a que se calibre cada uno.
Depende, si haces llegar la señal a todos juntos, si 32 segundos te podria llevar caibrar muchos de golpe.
-
Lo primero que necesitas es una señal calibrada de 1Hz, de referencia.
Te recomiendo comenzar con un GPS, que tiene una señal de 1PPS (Pulso Por Segundo) con bastante precisión (unos cientos de nanosegundos).
A continuación necesitas hacer un buen frecuencímetro que mida la frecuencia del clock del RTC con precisión de 1 parte por millón (6 decimales) y a partir de ahí calcular el smooth calibration necesario para compensar el error.
Ese frecuencímetro puede ser externo al micro y enviar la calibración o puede ser interno al micro (más recomendable para simplificar el circuito total)
Por ejemplo puedes comenzar a medir pulsos del RTC clock cuando llegue el primer pulso por segundo. Después mides 32764 pulsos del reloj y a continuación mides los microsegundos hasta que llega el siguiente pulso por segundo. Deberían ser 122 microsegundos. Cualquier desviación es el error a corregir. Es solo un ejemplo. Hay más maneras de realizarlo.
Un Saludo.
-
Con el frecuencímetro me he equivocado un poco, porque el método anterior pierde hasta un pulso inicial de 32kHz y eso es mucho.
Lo mejor es medir el tiempo desde la señal de 1 PPS hasta el siguiente pulso de 32kHz y medir los pulsos de 32kHz entre 2 señales de 1 PPS. A partir de ahí se calcula el tiempo total y el número de pulsos de 32kHz totales. Con eso se puede calcular la frecuencia y a partir de la frecuencia, el ajuste necesario.
Un poco laborioso, pero en 1 segundo tienes tu calibración hecha internamente con solo recibir una señal de 1PPS en el microcontrolador y entrar en el modo "Calibración".
Un saludo.
-
El método anterior funciona incluso con un oscilador principal de baja precisión, porque la mayor parte del tiempo se va a medir con la señal de 1PPS que tiene mucha precisión, de manera que se puede realizar incluso con el oscilador interno del microcontrolador.
-
Estuve leyendo y tratando de entender lo que plantea el documento.
La calibración es para cuando tengas un oscilador que NO es demasiado exacto. Tal como el LSE del micro.
Y siempre necesitas una referencia externa y precisa, que seria tu oscilador externo.
El problema es que creo que estas planteando "corregir" lo que te presenta el cristal de 32KHz, y para eso necesitas otro oscilador externo MEJOR que el anterior.
Encima tenes desviaciones de frecuencia por temperatura y voltajes por lo tanto como bien dice al ultimo, este proceso de calibracion debe ser continuo y no solo una ves al inicio.
¿A que lleva a esto?
Que si o si uses un oscilador externo "bueno". No queda otra.
ademas de tener que esperar 32 segundos a que se calibre cada uno.
Depende, si haces llegar la señal a todos juntos, si 32 segundos te podria llevar caibrar muchos de golpe.
Es un reloj externo de 32,678 KHz, es uno de la tabla de los recomendados por ST, un NX3215SA-32.768K-STD-MUA-14
https://www.mouser.es/datasheet/2/905/c_NX3215SA-STD-MUA-14_e-1317539.pdf
y si es el LSE, que es el externo el interno de 32KHz es el LSI, que además no es bueno usarlo debido a una errata del silicion que hace que no funcione bien cuando lo activas junto al CCS.
Con el frecuencímetro me he equivocado un poco, porque el método anterior pierde hasta un pulso inicial de 32kHz y eso es mucho.
Lo mejor es medir el tiempo desde la señal de 1 PPS hasta el siguiente pulso de 32kHz y medir los pulsos de 32kHz entre 2 señales de 1 PPS. A partir de ahí se calcula el tiempo total y el número de pulsos de 32kHz totales. Con eso se puede calcular la frecuencia y a partir de la frecuencia, el ajuste necesario.
Un poco laborioso, pero en 1 segundo tienes tu calibración hecha internamente con solo recibir una señal de 1PPS en el microcontrolador y entrar en el modo "Calibración".
Un saludo.
Esto me parece un sistema complejo para algo que necesite un reloj muy muy exacto como un semáforo por ejemplo, pero es que lo que yo busco es poner un reloj al sistema para saber la hora que si se desvia un poco cada cierto tiempo pues me da igual, siempre que sea algo razonable.
Pero es que ahora mismo se desvia 8 segundos por día.
Se lo consulte al servicio técnico y me dijo que le hiciera el smooth calibration, pero dudo que todos los sistemas que llevan un reloj hagan esto.
¿Puede que el error este en el hardware? ¿debería cambiar a un reloj de 4 patas para anclar las otras dos a masa?
este es mi rutado:
- Tienes que ingresar para ver archivos adjuntos -
Como veis tengo una isla de GND aislada del resto de gnd (solo unida por un punto) ademas de un "guard ring", ¿deberia usar un reloj de 4 pines o uno through hole? podría esto eliminar mi problema?
un saludo.
-
8 segundos al día es un error de 93ppm, que es mucho mayor de +-20ppm, la tolerancia de frecuencia de ese oscilador a 20º.
Puede que tengas algún error en el diseño de hardware o una temperatura extrema.
Para corregirlo, en principio solo tienes que aplicar una smooth calibration de -93ppm y ya está.
Pero si quieres hacerlo automático para corregir muchos, no tienes más remedio que hacer lo que puse antes. Tienes que medir de alguna forma el error de frecuencia y lo normal es hacerlo con 6 cifras decimales de precisión, que es la precisión del smooth calibration.
A propósito, el error que comentas de 8 segundos, le faltan los decimales. Si tienes un error de 8.5 segundos y solo corriges el error de 8 segundos, seguirás teniendo un error de 15 segundos al mes, que se podría corregir.
Un saludo.
-
Para hacerlo de manera manual, también puedes utilizar un frecuencímetro de más de 6 cifras de precisión y medir la señal de 1PPS del micro sin smooth calibration. Luego calculas el error en partes por millón y aplicas la corrección al smooth calibration.
Se supone que el error máximo a 20º debería ser de 2.5 segundos al mes.
-
Se lo consulte al servicio técnico y me dijo que le hiciera el smooth calibration, pero dudo que todos los sistemas que llevan un reloj hagan esto.
Los relojes de pulsera lo hacen habitualmente para ajustar el error del oscilador de cuarzo.
Un oscilador de cuarzo normal puede tener un error de +-20ppm que se traduce a +-50 segundos al mes. Eso es mucho error y con el smooth calibration puedes reducirlo en un factor de 20, a solo 2 o 3 segundos al mes, siempre que la temperatura se mantenga entre 20 y 30 grados.
-
Perdon por tardan en contestar, he tenido algunos problemas de indole personal.
Entonces, recapitulando para calibrarlo necesito una señal de 1Hz exacta, y medir la imprecisión, que podría hacerlo reconduciendo el pin de salida del RTC a otro del micro y medirlo en el propio micro, supongo que ha 64MHz de funcionamiento del reloj principal no tendré problemas para medir un herzio con precisión.
El problema es para producción y solo lo calibrare una vez, no puedo incluir un sistema que de un pulso de 1Hz, por que lo encarecería considerablemente, asi que supongo que comprará algo que me de 1Hz y a la hora de programar los calibraré.
Tambien creo que existe la posibilidad de utilizar la señal de la red de 50 o 60 Hz para que este siempre calibrado (menos cuando funcione la bateria de respaldo que entonces supongo que se quedará con la ultima calibración que tome de la red. ¿podría ser esto otra solución a estudiar viable? se podría tomar esta señal de 50Hz de la salida del transformador para asi tener ya el aislamiento de la red?
un saludo.
Por cierto para medir las frecuencias, me compro un frecuencimetro verdad? algo asi?
https://www.amazon.es/SODIAL-Contador-frecuencia-precision-Inteligente/dp/B07HHQ1Z1X/ref=sr_1_5?__mk_es_ES=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=1DD8876PVQYZD&keywords=frecuencimetro&qid=1579517255&sprefix=freciu%2Caps%2C171&sr=8-5
-
A ver, el servicio técnico me ha respondido con una solución que parece ser bastante buena para mi, ya que da una resolucion de 1ppm en menos de 1 segundo y no parece necesitar ningún sistema externo.
(lo he traducido)
Calibración suave, requiere un reloj preciso de 1s en producción y durante 2x 32s se realiza la calibración, lo que parece llevar mucho tiempo.
La opción similar de cómo lograr una precisión de medición de hasta 1 ppm es implementar un contador con un reloj interno de 32 MHz más preciso.
La señal de cuarzo del pin MCO se usa como entrada para el contador y se cuentan 976.5 ciclos internos durante un período LSE.
Entonces, después de al menos 1/32 segundos (1024 períodos LSE) también se obtiene la precisión de medición de 1 ppm.
Según la medición, se puede cargar el registro de calibración adecuado.
Con el uso, cualquier margen de tiempo para la observación y verificación de la medición del proceso de calibración se puede realizar en aproximadamente <1 segundo.
Necesito ayuda para implementarlo ya que hay algunas cosas que no me quedan del todo claras, a ver:
Primero, debo justar el pin MCO como salida del reloj LSE, eso es fácil:
- Tienes que ingresar para ver archivos adjuntos -
Ahora no entiendo muy bien que debo hacer, utilizar un timer con la fuente de reloj MCO? utilizar un timer en modo captura y unir fisicamente el pin MCO??
-
La red eléctrica es muy exacta a largo plazo, pero a corto plazo (horas) no es nada exacta.
Puedes utilizarla de RTC, pero no para realizar calibraciones.
Ese frecuencímetro es bastante malo. Es mejor que te hagas uno tu mismo con un micro, o que compres uno profesional.
Si quieres te ayudo a hacer un frecuencímetro que mida con mucha precisión valores de frecuencia pequeños (32kHz ó 1Hz del pulso por segundo)
Lo primero que necesitas es dos contadores. Uno para contar pulsos de reloj y otro para contar pulsos de entrada.
-
Lo que no entiendo es qué significa MCO o LSE. Ese micro no lo conozco.
Saludos.
-
Si quieres te ayudo a hacer un frecuencímetro que mida con mucha precisión valores de frecuencia pequeños (32kHz ó 1Hz del pulso por segundo)
Lo primero que necesitas es dos contadores. Uno para contar pulsos de reloj y otro para contar pulsos de entrada.
Estaria bien para las siguientes tiradas, pero para este primer pedido no tengo tiempo, deberé dejar preparado los sistemas para cuando tenga el frecuencímetro pero los primeros tengo que calibrarlos como pueda.
Lo que no entiendo es qué significa MCO o LSE. Ese micro no lo conozco.
Saludos.
MCO es Master clock output, es una salida que puedes configurar para que sea la del LSE, el LSI, el HSI etc, y estos son los distintos tipos de reloj del micro por ejemplo:
LSI es el reloj interno de baja frecuencia (32KHz)
LSE el reloj externo de baja freciencia, es decir donde pones el 32,768KHz
HSE el reloj externo de alta frecuencia.
etc.
si quieres echarle un ojo es el stm32g030:
https://www.st.com/resource/en/datasheet/stm32g030c8.pdf
https://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/fd/a3/20/58/ac/b0/48/23/DM00463896/files/DM00463896.pdf/jcr:content/translations/en.DM00463896.pdf
- Tienes que ingresar para ver archivos adjuntos -
-
Necesitas medir de alguna manera la señal de 32kHz con mucha precisión (1ppm)
Para eso necesitas un frecuencímetro con reciprocal counting, que muestre al menos dos decimales en el display cuando mida la frecuencia de 32kHz.
O te compras un buen frecuencímetro o haces un programa para medir la frecuencia con decimales. En el último caso también necesitarás un patrón de frecuencia bien calibrado, como el que te dan los GPS.
Un saludo.
-
Otra forma un poco rústica es medir el RTC durante mucho tiempo (dos días por ejemplo) con un buen cronómetro y haces el ajuste a mano.
Saludos.
-
Si al final decides medir la frecuencia con tu propio microcontrolador, necesitarás un cristal externo de cuarzo de alta frecuencia (HSE) para que te de la frecuencia principal (MCO).
Puedes utilizar por ejemplo un xtal de 10MHz para multiplicarla con el PLL y trabajar a 80MHz.
Luego tienes que contar pulsos de reloj y pulsos de la señal de 32kHz
Esperas más o menos un segundo y lees los contadores justo cuando la señal de 32kHz tenga un flanco de positivo a negativo (por ejemplo con una interrupción o por polling). Luego la frecuencia la calculas con facilidad en coma flotante:
Frecuencia = (Pulsos de la señal de 32kHz * 80000000.0) / (Pulsos de reloj)
El valor lo mandas por UART al PC para ahorrarte el display. printf("%7.3f\n", Frecuencia);
Y ya tienes tu frecuencímetro barato pero con mucha resolución.
Para conseguir precisión, mides también una señal de 1PPS del GPS y corriges el error que midas.
Un saludo.
-
Si al final decides medir la frecuencia con tu propio microcontrolador, necesitarás un cristal externo de cuarzo de alta frecuencia (HSE) para que te de la frecuencia principal (MCO).
Puedes utilizar por ejemplo un xtal de 10MHz para multiplicarla con el PLL y trabajar a 80MHz.
Luego tienes que contar pulsos de reloj y pulsos de la señal de 32kHz
Esperas más o menos un segundo y lees los contadores justo cuando la señal de 32kHz tenga un flanco de positivo a negativo (por ejemplo con una interrupción o por pooling). Luego la frecuencia la calculas con facilidad en coma flotante:
Frecuencia = (Pulsos de la señal de 32kHz * 80000000.0) / (Pulsos de reloj)
El valor lo mandas por UART al PC para ahorrarte el display. printf("%7.3f\n", Frecuencia);
Y ya tienes tu frecuencímetro barato pero con mucha resolución.
Para conseguir precisión, mides también una señal de 1PPS del GPS y corriges el error que midas.
Un saludo.
Creo que esto que me comentas es basicamente lo mismo que esto verdad?
Calibración suave, requiere un reloj preciso de 1s en producción y durante 2x 32s se realiza la calibración, lo que parece llevar mucho tiempo.
La opción similar de cómo lograr una precisión de medición de hasta 1 ppm es implementar un contador con un reloj interno de 32 MHz más preciso.
La señal de cuarzo del pin MCO se usa como entrada para el contador y se cuentan 976.5 ciclos internos durante un período LSE.
Entonces, después de al menos 1/32 segundos (1024 períodos LSE) también se obtiene la precisión de medición de 1 ppm.
Según la medición, se puede cargar el registro de calibración adecuado.
Con el uso, cualquier margen de tiempo para la observación y verificación de la medición del proceso de calibración se puede realizar en aproximadamente <1 segundo.
Entonces lo que necesitaría seria usar un HSE para tener mas precisión y poder medir el cristal de 32,768KHz es ¿asi?
Este micro solo llega a los 64Mhz, pero utilizo el cristal interno el HSI, supongo que este no puedo usarlo para esta tarea verdad?
-
Creo que es lo mismo.
Con que trabajes a 10MHz ya vas a tener suficiente velocidad.
El cristal de alta frecuencia te sirve para medir con muchos decimales de resolución, pero también tiene error en su precisión. Necesitas un GPS para corregir ese error.
Saludos.
-
Creo que es lo mismo.
Con que trabajes a 10MHz ya vas a tener suficiente velocidad.
El cristal de alta frecuencia te sirve para medir con muchos decimales de resolución, pero también tiene error en su precisión. Necesitas un GPS para corregir ese error.
Saludos.
Ok pues voy a intentar corregir ese error con los 64Mhz de funcionamiento del micro, a ver que precisión se puede corregir sin recurrir al gps, voy a modificar un poco el hardware para medir los relojes y lo posteo por aquí a ver que tal.
un saludo gracias.
-
Sin GPS no corriges nada. Ten en cuenta que el cristal de alta frecuencia tiene un error semejante al del cristal de baja frecuencia.
-
Sin GPS no corriges nada. Ten en cuenta que el cristal de alta frecuencia tiene un error semejante al del cristal de baja frecuencia.
¿Entonces para hacer un despertador por ejemplo necesitas un GPS? no quiero que sea una precisión de reloj atómico, solo que no tenga un margen de error alto.
-
Si. Lo necesitas para medir y corregir. Luego ya no hace falta que esté en el aparato final.
Es el GPS de 10€ o el frecuencímetro calibrado de 1500€. Tu eliges.
Saludos.
-
¿Entonces para hacer un despertador por ejemplo necesitas un GPS? no quiero que sea una precisión de reloj atómico, solo que no tenga un margen de error alto.
Con smooth calibration puedes corregir el error hasta 1 parte por millón (1ppm). Necesitas un patrón con esa precisión y eso te lo da este sencillo aparato:
https://www.ebay.es/itm/GY-NEO6MV2-NEO-6M-GPS-Module-NEO6MV2-with-Small-Antenna-for-Arduino/183417647166?hash=item2ab48b303e:g:Q5MAAOSwlUhbj~XD
Si necesitas un patrón mejor o más independiente del GPS y con antena larga, puedes comprar esto:
https://www.ebay.es/itm/NEW-10MHz-Sinwave-PLL-GPSDO-GPS-DISCIPLINED-OSCILLATOR-adapter-GPS-ANT/262038924752?hash=item3d02bcadd0:g:ZmsAAOSwkvFafGgr
Un saludo.
-
No encuentro casi nada de información del primer modulo barato que me has pasado, tiene algun pin de salida a 1pps como por ejemplo el EM406A??
veo algún vídeo de como usar la localizacion con el arduino con su uart pero poco mas, ami lo que me interesa es el herzio
-
Tiene un pin de 1PPS.
En la tercera foto se puede ver, en la serigrafia del bottom.
El módulo es estándar. Busca «neo6 datasheet u-blox» en google y te aparece el datasheet.
El error de la señal es de 60ns cada segundo (mejor que 0,1ppm).
Se sincroniza con el flanco de subida.
Saludos.
-
Tiene un pin de 1PPS.
En la tercera foto se puede ver, en la serigrafia del bottom.
El módulo es estándar. Busca «neo6 datasheet u-blox» en google y te aparece el datasheet.
El error de la señal es de 60ns cada segundo (mejor que 0,1ppm).
Se sincroniza con el flanco de subida.
Saludos.
Ok pues me comprare un gps de estos y lo calibraré con esto. Pero estoy teniendo problemas para comprender el ejemplo de aplicación del smooth calibration (https://www.st.com/en/embedded-software/x-cube-rtc.html)
La verdad es que nunca he utilizado un timer como contador o capturador o como lo este esando en el ejemplo, a ver si alguien me lo puede aclarar, dejo los codigos:
inicializacion de los timer:
/* TIM2 init function */
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef s_clock_source_config;
TIM_SlaveConfigTypeDef s_slave_config;
TIM_MasterConfigTypeDef s_master_config;
TIM_IC_InitTypeDef s_config_ic;
TIM_OC_InitTypeDef s_config_oc;
hTim2.Instance = TIM2;
hTim2.Init.Prescaler = 0;
hTim2.Init.CounterMode = TIM_COUNTERMODE_UP;
hTim2.Init.Period = 0xFFFFFFFF;
hTim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&hTim2) != HAL_OK)
{
Error_Handler();
}
s_clock_source_config.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
s_clock_source_config.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
s_clock_source_config.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
s_clock_source_config.ClockFilter = 0;
if (HAL_TIM_ConfigClockSource(&hTim2, &s_clock_source_config) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&hTim2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&hTim2) != HAL_OK)
{
Error_Handler();
}
s_slave_config.SlaveMode = TIM_SLAVEMODE_RESET;
s_slave_config.InputTrigger = TIM_TS_ITR2;
if (HAL_TIM_SlaveConfigSynchronization(&hTim2, &s_slave_config) != HAL_OK)
{
Error_Handler();
}
s_master_config.MasterOutputTrigger = TIM_TRGO_RESET;
s_master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&hTim2, &s_master_config) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIMEx_RemapConfig(&hTim2, TIM_TIM2_ETR_LSE) != HAL_OK)
{
Error_Handler();
}
s_config_ic.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
s_config_ic.ICSelection = TIM_ICSELECTION_TRC;
s_config_ic.ICPrescaler = TIM_ICPSC_DIV1;
s_config_ic.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&hTim2, &s_config_ic, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
s_config_oc.OCMode = TIM_OCMODE_TOGGLE;
s_config_oc.Pulse = 0;
s_config_oc.OCPolarity = TIM_OCPOLARITY_HIGH;
s_config_oc.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&hTim2, &s_config_oc, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&hTim2);
}
/* TIM3 init function */
void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef s_clock_source_config;
TIM_MasterConfigTypeDef s_master_config;
TIM_OC_InitTypeDef s_config_oc;
hTim3.Instance = TIM3;
hTim3.Init.Prescaler = 0;
hTim3.Init.CounterMode = TIM_COUNTERMODE_UP;
hTim3.Init.Period = 15;
hTim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&hTim3) != HAL_OK)
{
Error_Handler();
}
s_clock_source_config.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
s_clock_source_config.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
s_clock_source_config.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
s_clock_source_config.ClockFilter = 0;
if (HAL_TIM_ConfigClockSource(&hTim3, &s_clock_source_config) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&hTim3) != HAL_OK)
{
Error_Handler();
}
s_master_config.MasterOutputTrigger = TIM_TRGO_RESET;
s_master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&hTim3, &s_master_config) != HAL_OK)
{
Error_Handler();
}
s_config_oc.OCMode = TIM_OCMODE_TOGGLE;
s_config_oc.Pulse = 0;
s_config_oc.OCPolarity = TIM_OCPOLARITY_HIGH;
s_config_oc.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&hTim3, &s_config_oc, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&hTim3);
}
el main:
int main(void)
{
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
MX_RTC_Init();
MX_TIM2_Init();
if (HAL_TIM_Base_Start_IT(&hTim3) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 1 in Output compare mode */
if (HAL_TIM_OC_Start_IT(&hTim3, TIM_CHANNEL_1) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/*##-1- Start TIM2 generation in interrupt mode ####################*/
if (HAL_TIM_Base_Start_IT(&hTim2) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 1 in Input capture mode */
if (HAL_TIM_IC_Start_IT(&hTim2, TIM_CHANNEL_1) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 2 in Output compare mode */
if (HAL_TIM_OC_Start_IT(&hTim2, TIM_CHANNEL_2) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/*##-2- Start TIM2 generation in interrupt mode ####################*/
/* Infinite loop */
while (1)
{
if (CalibrationStatus == SET)
{
calibrate();
CalibrationStatus = RESET;
}
}
}
la funcion de calibracion:
static void calibrate(void)
{
const int32_t cycles_expected = 0x100000; /* expected number of RTCCLK cycles during 32-seconds */
int32_t smooth_calib_plus_pulses = RTC_SMOOTHCALIB_PLUSPULSES_RESET;
int32_t smooth_calib_minus_pulses_value = 0x0;
if (Calibration1stITDone == RESET)
{
Calibration1stITDone = SET;
}
else
{
/* update RTC_Calib */
if ( (uint32_t) (TIM2->CCR1 >= cycles_expected))
{
smooth_calib_plus_pulses = RTC_SMOOTHCALIB_PLUSPULSES_RESET;
smooth_calib_minus_pulses_value = (uint32_t) (TIM2->CCR1 - cycles_expected );
}
else
{
smooth_calib_plus_pulses = RTC_SMOOTHCALIB_PLUSPULSES_SET;
smooth_calib_minus_pulses_value = (uint32_t) ((RTC_SMOOTH_CALIB_MINUS_MASK) - (cycles_expected - TIM2->CCR1 ));
}
if (smooth_calib_minus_pulses_value > RTC_SMOOTH_CALIB_MINUS_MASK)
{
smooth_calib_minus_pulses_value = (uint32_t) (RTC_SMOOTH_CALIB_MINUS_MASK);
}
HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, smooth_calib_plus_pulses, smooth_calib_minus_pulses_value);
}
}
y las interrupciones:
void TIM2_IRQHandler(void)
{
TIM_HandleTypeDef *htim = &hTim2;
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) != RESET)
{
if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00)
{
CalibrationStatus = SET;
}
}
}
HAL_TIM_IRQHandler(&hTim2);
}
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&hTim3);
}
-
Por lo que yo entiendo a ver si esta bien.
aunque en el ejemplo pone los canales de input y output de los timer en pines, esto no es necesario y se puede hacer de manera interna.
la fuente de reloj del timer 3 es el reloj de 1Hz conectado a PD2.
¿Pero usar el CH1 del timer 3 como comparador en modo toggle? esto que es?
luego el timer 2:
Este tiene como fuente de reloj el reloj LSE, el CH1 como input capture del TRC, y el CH2 como output compare de nuevo como togle on match.
y resulta que es esclavo en modo reset.
Por favor que alguien me explique como esta trabajando esto.
un saludo y gracias.
-
Yo no puedo ayudarte con la configuración concreta de ese micro de 32bits, pero si puedo darte las líneas generales de cómo lo he programado en otros microcontroladores de 8 y de 16bits.
En principio puedes dejar a los contadores correr libremente (sin capturas ni nada). Un contador para contar pulsos de reloj de alta frecuencia (64MHz en tu caso) y otro contador para contar los pulsos de la frecuencia que quieres medir (32kHz internos o bien 1Hz externo).
Hasta ahí no deberías tener mayor problema. Los contadores trabajan de forma libre sin interrupciones ni paradas ni reseteos.
Después debes leer los valores de los contadores cuando venga un flanco de subida de la señal que estás midiendo en frecuencia (32kHz o bien 1Hz). Esto tampoco debería ser un problema.
Por último restas de la última lectura realizada, la penúltima lectura realizada. Así tendrás las diferencias de pulsos entre un flanco y el siguiente (tanto de reloj como de pulsos de la señal a medir).
Esas diferencias son las que se utilizan en la fórmula para calcular la frecuencia. La ventaja de este método (llamdo continuous counting) es que los pequeños errores se compensan de una medición a la siguiente.
Si no sabes implementarlo en tu micro de 32 bits, pásate a uno de 8 bit y te ayudo a implementarlo.
Un saludo.
-
Yo no puedo ayudarte con la configuración concreta de ese micro de 32bits, pero si puedo darte las líneas generales de cómo lo he programado en otros microcontroladores de 8 y de 16bits.
En principio puedes dejar a los contadores correr libremente (sin capturas ni nada). Un contador para contar pulsos de reloj de alta frecuencia (64MHz en tu caso) y otro contador para contar los pulsos de la frecuencia que quieres medir (32kHz internos o bien 1Hz externo).
Hasta ahí no deberías tener mayor problema. Los contadores trabajan de forma libre sin interrupciones ni paradas ni reseteos.
Después debes leer los valores de los contadores cuando venga un flanco de subida de la señal que estás midiendo en frecuencia (32kHz o bien 1Hz). Esto tampoco debería ser un problema.
Por último restas de la última lectura realizada, la penúltima lectura realizada. Así tendrás las diferencias de pulsos entre un flanco y el siguiente (tanto de reloj como de pulsos de la señal a medir).
Esas diferencias son las que se utilizan en la fórmula para calcular la frecuencia. La ventaja de este método (llamdo continuous counting) es que los pequeños errores se compensan de una medición a la siguiente.
Si no sabes implementarlo en tu micro de 32 bits, pásate a uno de 8 bit y te ayudo a implementarlo.
Un saludo.
Perfecto pues así lo voy a hacer, mucho mas simple que la manera enrevesada del ejemplo del stm32, además que en el micro que estoy usando, no puedo configurar un timer con la entrada LSE y que se dispare por el ITR, ya que es con el timer 2 y este micro no lo tiene, tiene el 1 y el 3 pero no el 2.
Por cierto, cuantas veces debería realizar la resta para dar una calibración decente?
un saludo
-
Con una medición de un segundo tendrás suficiente.
-
Con una medición de un segundo tendrás suficiente.
Pues de tu solución, a la que ofrece st con el smooth calibration, que tarda 64 segundos... anda que no hay diferencia la verdad.
voy ha hacer el hardware para capturar la señal de 1Hz y ya comentaré cuando lo tenga acabado o lo pruebe.
un saludo y gracias.
-
Puedes comenzar por hacer la medición de frecuencia de 32kHz.
La medición de 1Hz es para corregir el error del oscilador de alta frecuencia.
-
Voy ha hacer un pedido a mouser y rs, el modulito que me indicaste no esta en ninguno de los dos.
¿Conoces alguno que pueda comprar por uno de estos dos sitios? Las funciones que tenga me dan igual siempre que tenga el reloj de 1PPS.
un saludo.
son muy caros voy a comprar el de ebay y ya esta, por cierto este modulito es darle alimentación y tener disponible el 1PPS o hay que programarlo?
-
Hay que darle alimentación y acceso a los satélites. Con eso es suficiente.
Si no te funciona en interior, tendrás que sacar la antena por la ventana o salir fuera del edificio.
-
Prueba con el GPS del teléfono móvil. Es similar.
-
Ok, he probado en mi taller con el GPS de 3 moviles y parece que no hay ningun problema, por lo que supongo que tampoco debe de existir con el modulito este.
Para medir la señal de 32,768 KHz, en este prototipo que no tengo conexión externa seria colocar el TIM17 en modo captura del LSE, para saber cuando me llega un flango del cristal de 32KHz, por ejemplo?
un saludo.
-
Tienes que configurar un contador para que cuente los pulsos del cristal de 32kHz.
Luego por interrupciones o por polling tienes que detectar el flanco de la señal de 32kHz para sincronizar la lectura de los contadores justo después del flanco.
-
Tienes que configurar un contador para que cuente los pulsos del cristal de 32kHz.
Luego por interrupciones o por pooling tienes que detectar el flanco de la señal de 32kHz para sincronizar la lectura de los contadores justo después del flanco.
Vale, he puesto el TIMER17 como input capture mapeado al pin MCO configurado en LSE, capturando asi los flancos de subida, he puesto que me haga toggle de un pin cada vez que tenga un flanco ascendente y veo en el osciloscopio que ese pin tiene una frecuencia de ~16,34 que es la mitad de los 32,678 al solo detectar el flanco de subida.
¿Con esto sirve o necesito controlar los dos flancos, de subida y de bajada?
-
Con eso sirve.
Ahora tienes que configurar otro contador para que cuente los pulsos de alta frecuencia del oscilador principal.
Los dos contadores deben funcionar a la vez.
-
Siento no haber contestado antes, he estado fuera de servicio un tiempo :?
Pero bueno, este tiempo ha servido para que me lleguen los GPS que me recomendaste Picuino.
Ya los he probado y medido con un osciloscopio y da los pulsos a 1 segundo exactos, ademas coge señal bastante rápido.
Vale, lo dejamos que ya había configurado un timer para capturar los pulsos del LSE (reloj externo de 32.768KHz).
Con eso sirve.
Ahora tienes que configurar otro contador para que cuente los pulsos de alta frecuencia del oscilador principal.
Los dos contadores deben funcionar a la vez.
¿Para que necesito los pulsos del reloj principal de 64Mhz? aquí me he perdió un poco. Ademas no creo que pueda capturar los pulsos del reloj de 64Mhz, ya que el propio programa deberia ir mas rapido para poder capturarlos no?
un saludo.
-
Los necesitas para medir tiempo y tener una medida con mayor exactitud.
Si no puedes capturar esa frecuencia, el micro dejará la opción de capturar la frecuencia de reloj dividida por dos (en los micros de 32bits de Atmel al menos es así)
-
Los necesitas para medir tiempo y tener una medida con mayor exactitud.
Si no puedes capturar esa frecuencia, el micro dejará la opción de capturar la frecuencia de reloj dividida por dos (en los micros de 32bits de Atmel al menos es así)
A ok no te habia entendido, lo que te refieres es que configure un timer con un TICK de 64 MHz del reloj interno, si eso no hay problema le pongo el prescaler a 1 y ya esta, lo que daria que un tick seria 1/64Mhz.
pues ya están los dos timer, uno que captura el pulso en alto del LSE y otro que funciona a una frecuencia de 64Mhz.
al timer que captura el LSE le he puesto una interrupción para que me salte cada vez que me llega el pulso.
un saludo.
-
Ahora tienes que tomar mediciones de un segundo. Cada segundo tienes que borrar el bit de interrupción y habilitar la interrupción para que lea los contadores y deshabilitas la interrupción dentro de la propia rutina.
En una variable guardas el valor anterior y en otra variable guardas el nuevo valor de cada contador.
La resta de ambas te dará el número de pulsos en un segundo.
La frecuencia es igual a pulsos del contador de LSE * 64000000.0 / pulsos del contador de TICKS
Todo calculado con flotantes de doble precisión (double)
-
Te dejo pseudocódigo
int32 time_now, time_old, pulses_now, pulses_old;
volatile bit lectura = 0;
double frecuencia;
main() {
setup_contadores()
reset_contadores()
time_now = 0
pulses_now = 0
while(1) {
time_old = time_now
pulses_old = pulses_now
delay_ms(1000)
Interrupt Flag = 0
Interrupt Enable = 1
esperar hasta que (lectura == 1)
lectura = 0
frecuencia = 64000000.0 * (double)(pulses_now - pulses_old) / ((double)(time_now - time_old));
printf("Tiempo=%lu\n", time_now - time_old)
printf("Frecuencia=%5.5f\n", frecuencia)
}
}
ISR() {
pulses_now = contador de LSE
time_now = contador de TICKS
Interrupt Enable = 0
Interrupt Flag = 0
lectura = 1
}
-
Con eso tendrás la lectura de frecuencia del oscilador de 32kHz.
Ahora necesitas también tener la lectura de frecuencia del pulso por segundo del GPS.
Para ello configura el contador del oscilador de 32kHz para que cuente pulsos externos y colocas en el pin correspondiente la señal de 1PPS del GPS.
En realidad deberías medir primero el GPS, ajustar la fórmula de frecuencia y luego medir la señal de 32kHz
-
Te dejo pseudocódigo
int32 time_now, time_old, pulses_now, pulses_old;
volatile bit lectura = 0;
double frecuencia;
main() {
setup_contadores()
reset_contadores()
time_now = 0
pulses_now = 0
while(1) {
time_old = time_now
pulses_old = pulses_now
delay_ms(1000)
Interrupt Flag = 0
Interrupt Enable = 1
esperar hasta que (lectura == 1)
lectura = 0
frecuencia = 64000000.0 * (double)(pulses_now - pulses_old) / ((double)(time_now - time_old));
printf("Tiempo=%lu\n", time_now - time_old)
printf("Frecuencia=%5.5f\n", frecuencia)
}
}
ISR() {
pulses_now = contador de LSE
time_now = contador de TICKS
Interrupt Enable = 0
Interrupt Flag = 0
lectura = 1
}
Contar los pulsos del LSE no es problema, pero el contador de TICK para el tiempo se me va ha desbordad si esta contando pulsos a 64Mhz durante 1 segundo, ya que el timer solo es de 16bits. El timer a 64Mhz da como mucho para 1mS.
1/64MHz * 2^16 = 0,001024 Segundos.
Siguiendo tu idea, ¿podría ser por ejemplo cuando reciba el pulso del GPS echo a andar un timer con la frecuencia del LSE, y al segundo pulso ver cuanta diferencia existe en el timer del LSE y cuando deberia ser?
-
Creía que tenías contadores de 32 bit.
En ese caso es más complejo, tienes que ampliar el contador a 32 bit contando los desbordamientos con una rutina de interrupción. Evitar que en la lectura se produzca un desbordamiento es difícil, pero no creo que plantee problemas en tu aplicación y no veo necesario que lo tengas en cuenta.
-
A ver, pues esto es lo que he podido hacer.
No he conectado todavia el GPS, pero estoy simulandolo con un timer a milisegundo (timer14). cuando llega a 1000, conecto enciendo los timer 17(64MHz) y el timer 16 que captura los pulsos ascendentes del LSE (32,768KHz)
cuando llega al segundo 2 paro los timer (es decir al segundo pulso que me de el GPS) y miro los valores de los contadores.
el timer que mide el LSE tengo que tenerlo con una interrupcion y un contador cada vez que entra, no se por que pero si no no cuenta:
void TIM14_IRQHandler(void)
{
/* USER CODE BEGIN TIM14_IRQn 0 */
/* USER CODE END TIM14_IRQn 0 */
HAL_TIM_IRQHandler(&htim14);
/* USER CODE BEGIN TIM14_IRQn 1 */
static uint32_t Contador = 0;
static uint8_t ContadorPulsosGPS = 0;
Contador++;
if (Contador >= 1000 && Contador < 2000)
{
HAL_TIM_Base_Start(&htim17);
HAL_TIM_IC_Start_IT(&htim16, TIM_CHANNEL_1);
ContadorPulsosGPS++;
}
else if(Contador >= 2000)
{
ContadorPulsosGPS++;
ContadorPulsos_64MHz = __HAL_TIM_GetCounter(&htim17);
ContadorPulsos_1Segundo = __HAL_TIM_GetCounter(&htim14);
HAL_TIM_Base_Stop(&htim17);
HAL_TIM_Base_Stop_IT(&htim14);
HAL_TIM_IC_Stop_IT(&htim16, TIM_CHANNEL_1);
ContadorPulsos_32KHz = 0;
}
/* USER CODE END TIM14_IRQn 1 */
}
/**
* @brief This function handles TIM16 global interrupt.
*/
void TIM16_IRQHandler(void)
{
/* USER CODE BEGIN TIM16_IRQn 0 */
/* USER CODE END TIM16_IRQn 0 */
HAL_TIM_IRQHandler(&htim16);
/* USER CODE BEGIN TIM16_IRQn 1 */
ContadorPulsos_32KHz++;
/* USER CODE END TIM16_IRQn 1 */
}
al segundo 2 tenemos los valores:
ContadorPulsosGPS = 2;
ContadorPulsos_32KHz ~=33034 (me bailan los valores supongo que es por que empiezo a capturar los valores en un pulso en bajo o en alto etc, o que aun no estoy usando el GPS.
ContadorPulsos_64MHz = 12549 (Estos si salen clavados, y logicamente se habrá desbordado varias veces.
-
Primero debes contar pulsos de alta frecuencia cada segundo, entre dos flancos ascendentes de la señal de 1PPS. Cuenta también los desbordamientos.
Con eso sabrás exactamente cuantos pulsos por segundo tienes en alta frecuencia.
-
Despues cuenta cuantos pulsos de alta frecuencia tienes comenzando a contar en un flanco del LSE y terminando después de 32768 flancos LSE.
Si el reloj LSE fuese perfecto, tendría que darte el mismo valor que en el caso anterior.
Como se va a desviar un porcentaje, ese es el ajuste que debes hacer.
-
Pues creo que hay un problema, los pulsos registrados de 64Mhz entre dos pulsos del gps varian mucho.
es decir, mido y me da (sin contar desbordamientos) 14185, vuelvo a repetir la prueba y me da 5017, y así todas las veces.
Se me ocurre otra manera, que creo que ya me lo comento el servicio técnico, hace tiempo.
medir los pulsos de 64Mhz en un periodo del LSE, lo he hecho y me da valores comprendidos entre (1975-1969). Eso es un periodo de entre 0,00003085937-0,00003076562 es decir, coinciden 6 cifras decimales siempre.
Sabiendo que el periodo de un LSE perfecto (32.768KHz) seria de 0,00003051757 o 1953 pulsos de 64Mhz puedo ver la diferencia con lo que estoy midiendo, tomando por ejemplo 1953-1975 = -22
si lo ajusto a mi reloj y tendiendo en cuenta que nos vamos al otro extremo (1969 en el peor caso) tendríamos 1969-22 = 1947
que sería 1947 pulsos de 64Mhz = 0,00003042187 (perfecto=0,00003051757) estoy dándole una precisión de 6 cifras decimales 1PPM, sin necesidad del GPS.
¿esto es así?
-
Así sólo consigues tener una precisión de 3 cifras decimales (precisión de 500ppm).
Además estás midiendo con un reloj de 64MHz que no está calibrado y puede tener error.
Tienes que medir pulsos de 64MHz entre 32000 pulsos LSE y ahí si que tienes precisión.
-
Así sólo consigues tener una precisión de 3 cifras decimales (precisión de 500ppm).
Además estás midiendo con un reloj de 64MHz que no está calibrado y puede tener error.
Tienes que medir pulsos de 64MHz entre 32000 pulsos LSE y ahí si que tienes precisión.
¿Por que 3 cifras decimales?
el problema es que si cuento pulsos de 64Mhz entre los pulsos de 1 segundo del gps me da valores distintos.
-
Lo normal es que haya un error en la cuenta de +-0.5 pulsos. Es decir, que el error será aproximadamente de 1 pulso.
Si cuentas 1947 pulsos, el error relativo será de 1/1947 = 0.0005136
Que significa que solo puedes tomar como válidas las primeras 3 cifras de cualquier cálculo que hagas con ese número que has contado (1947).
Cuenta pulsos entre dos flancos ascendentes del GPS. A mí me sale bastante bien con cualquier micro. El error está en 0.1ppm aproximadamente. Si soplas un poco el oscilador, puede cambiar hasta varias partes por millon, pero si la temperatura la mantienes estable no debe haber problemas.
Si tienes dudas del GPS, utiliza otro micro que tenga un oscilador a cristal para generar una señal de 1 pulso por segundo y prueba con esa señal. Solo para descartar que sea error del GPS.
Un saludo.
-
¿Estás seguro de que comienzas la cuenta con un flanco ascendente y terminas de contar con el siguiente flanco ascendente?
-
Lo normal es que haya un error en la cuenta de +-0.5 pulsos. Es decir, que el error será aproximadamente de 1 pulso.
Si cuentas 1947 pulsos, el error relativo será de 1/1947 = 0.0005136
Que significa que solo puedes tomar como válidas las primeras 3 cifras de cualquier cálculo que hagas con ese número que has contado (1947).
Cuenta pulsos entre dos flancos ascendentes del GPS. A mí me sale bastante bien con cualquier micro. El error está en 0.1ppm aproximadamente. Si soplas un poco el oscilador, puede cambiar hasta varias partes por millon, pero si la temperatura la mantienes estable no debe haber problemas.
Si tienes dudas del GPS, utiliza otro micro que tenga un oscilador a cristal para generar una señal de 1 pulso por segundo y prueba con esa señal. Solo para descartar que sea error del GPS.
Un saludo.
No dudo del GPS, lo veo en el osciloscopio y parece que va perfecto, dudo del reloj interno del micro de 64Mhz, entre que es un micro de 60 centimos y que tengo que manejar las interrupciones para ver los desbordamientos y demás, cada vez me sale una cuenta distinta entre dos pulsos del gps.
¿Estás seguro de que comienzas la cuenta con un flanco ascendente y terminas de contar con el siguiente flanco ascendente?
Si de eso estoy seguro, he comprobado con el osciloscopio que entra en la interrupcion de comienzo de la rutina en el flanco ascendente del pulso.
No se si has visto mi otro post, pero no me fio mucho del reloj interno, los timer me hace cosas raras con algunas configuraciones.
http://www.todopic.com.ar/foros/index.php?topic=49964.0
Lo que si he visto haciendo pruebas, es que los pulsos de 32,768KHz del cristal LSE si me dan siempre igual si los mido entre dos pulsos del GPS. Me da siempre una diferencia entre lo que mido y lo que deberia ser de -3 (32768 - PulsosMedidos).
¿Esto me podría servir para calibrarlo? si debo ver 32768 pulsos LSE en un periodo del LSE, me puede servir para ver los pulsos que faltan o sobran.
un saludo.
PD: Esto ya como duda personal, yo pensaba que el reloj de 32768 KHz era mas estable que los relojes de frecuencias mas altas. Pero entre lo que me comentas, y que el otro dia vi un ejemplo de ST, para sincronizar el RTC ya no estoy seguro.
En el ejemplo utilizaban un micro con un cristal externo, y lo tenian rodando a 100MHz y utilizaban un timer para generar el pulso de 1 segundo para sincronizar el RTC del propio micro :?
Para que narices se utiliza entonces el reloj de 32Khz si el otro es mas preciso?
-
Lo que si he visto haciendo pruebas, es que los pulsos de 32,768KHz del cristal LSE si me dan siempre igual si los mido entre dos pulsos del GPS. Me da siempre una diferencia entre lo que mido y lo que deberia ser de -3 (32768 - PulsosMedidos).
¿Esto me podría servir para calibrarlo? si debo ver 32768 pulsos LSE en un periodo del LSE, me puede servir para ver los pulsos que faltan o sobran.
Puedes calibrarlo con ese método, pero no tendrás mucha precisión. Deberías contar pulsos durante 30 segundos para tener una precisión de 1 parte por millón. Ahora solo tienes una precisión de +-30 partes por millón y eso es demasiado pobre.
El oscilador de 32kHz se utiliza porque consume muy poco, no porque sea más preciso.
Un saludo.
-
El oscilador de 32kHz se utiliza porque consume muy poco, no porque sea más preciso.
Un saludo.
¿Entonces mientras mas rápido sea el reloj mas precisión no?
Si sigo este método (ya que parece que el reloj de 64Mhz tiene mucha incertidumbre), ¿mientras mas tiempo lo deje contando mas precisión alcanzaré. ¿como has hecho la cuenta para saber que son 30 segundos para 1ppm? ¿si lo dejo 8 segundos por ejemplo?
un saludo?
-
No, los dos relojes son igual de precisos.
La precisión te la da el numero de cuentas que haces. 10 cuentas te dan un dígito de precisión. 1000000 de cuentas te dan 6 dígitos de precisión o un error de 1 parte por millón.
-
No creo que el reloj de 64MHz tenga mucha incertidumbre. Debe ser un error de software.
-
¿Que error de software puede haber?
he hecho una prueba mas sencilla aun.
capturo los pulsos en alto del reloj LSE este seria el seudocodigo:
-Encender timer17 (64MHz corriendo libremente)
-delay 1000mS
-Encender timer16 (salta la interrupción cada vez que lee un flanco ascendente del LSE)
while(1)
#interrupciones
if (PrimeraEntrada== 0)
{
htim17.Instance->CNT = 0;
PrimeraEntrada++;
}
else if (PrimeraEntrada>= 1)
{
Pulsos64MHz = __HAL_TIM_GetCounter(&htim17);
}
}
Cada vez que reinicio el programa obtengo un valor distinto, 1962,1965,1964,1963,1962,1960... (el ideal seria 1953,125)
eso solo en un periodo de LSE5, imagina en un segundo las diferencias que me encuentro.
-
Prueba con esto:
#interrupciones
if (CuentasLSE == 0) {
htim17.Instance->CNT = 0;
}
if (CuentasLSE < 32000) {
CuentasLSE++;
Pulsos64MHz = __HAL_TIM_GetCounter(&htim17);
}
A ver cuanto cuenta en 32000 pulsos LSE.
Cuando CuentasLSE llegue a 32000, entonces Pulsos64MHz debería tener una cuenta más o menos estable.
-
if(CuentasLSE == 0)
{
htim17.Instance->CNT = 0;
}
if(CuentasLSE < 32000)
{
CuentasLSE++;
Pulsos64MHz = __HAL_TIM_GetCounter(&htim17);
}
else
{
CuentasLSE = 0;
}
el else lo he puesto simplemente para parar la depuración y comprobar el valor de Pulsos64MHz, y los resultados igual de dispares, cada vez que compilo y quemo.
-36663
-50915
-50280
-26160
-38241
...
-
No entiendo por qué pasa eso. Las pruebas que he hecho con cristales salen mucho más estables, con errores de una o dos cuentas por segundo y como mucho una desviación de veinte a cuarenta cuentas por segundo cuando se calienta el cristal un poco.
Puede que te venga bien hacerte un pequeño frecuencímetro con otro microcontrolador, por ejemplo un PIC. En ese caso yo te puedo ayudar con el código y las pruebas.
Te recomiendo el PIC18F2550
-
No entiendo por qué pasa eso. Las pruebas que he hecho con cristales salen mucho más estables, con errores de una o dos cuentas por segundo y como mucho una desviación de veinte a cuarenta cuentas por segundo cuando se calienta el cristal un poco.
Puede que te venga bien hacerte un pequeño frecuencímetro con otro microcontrolador, por ejemplo un PIC. En ese caso yo te puedo ayudar con el código y las pruebas.
Te recomiendo el PIC18F2550
Supongo que sera el micro que no da para mas.
bueno pues esta vez lo calibraré usando los pulsos de 32,768 KHz que es lo unico que si sale estable entre dos pulsos de gps, aunque tenga que dejar mas de un segundo par darle mas precisión.
cuando vuelva a rehacer el circuito cambiare el micro y retomaré el tema, entonces ya si que me montare el frecuencimetro para poder hacer las cosas bien desde el principio.
Muchas gracias por tu ayuda Picuino, retomare el tema en cuanto pueda.
un saludo.
-
Ok, un saludo.
-
Hacer contadores por software te agrega error por el tiempoºenºque se demora ingresar a la interrupcion y llegar a capturar el reguistro a una variable.
Yo se hacer en un micro de 8bit creo el programa simulo y utiliso una frecuencia de 1hertz y obtengo los pulsos extra que tengo, luego seria solo restar
-
Basicamente eso hemos hecho, el 1 Hz es de un GPS pero utilizo los pulsos del reloj LSE por que los reloj interno tiene mucho error.
Si fuera por el retraso de las interrupciones no existiria una deriva tan grande entre el mismo experimento una y otra vez.