Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola, tengo una duda sobre realizar el código para controlar tiempos de pocos microsegundos en c.
Lo que quiero hacer es generar esta señal: http://www.jmnlab.com/miniz/miniz.html mediante un Atmega16 desde c.
Resumiendo ya que eso es un poco largo, necesito controlar el tiempo entre dos pulsos y lo mismo necesito pasos/precisión de 25 uS, lo he realizado en ensamblador para pic y funciona, pero mi duda es si es indicado utilizar un atmega16 desde c para realizar esto o tendría que hacerlo en ensamblador, cosa que me haría volver al asm del pic que ya conozco.
Gracias. Saludos.
A ver, si mi neurona ya empieza a estar despierta, lo que tu quieres generar es un tren de tres pulsos que se repitan cada 16 ms, de una duración fija de unos 500 us y cuya separación entre el primero y el segundo marque la dirección, mientras que la separación entre el segundo y el tercero te marque la velocidad, ¿correcto?.
Bueno, pues si es así, no veo inconveniente en hacerlo en C con un ATmega 16. Lo primero y más importante sería saber la frecuencia de trabajo. Doy por supuesto que usarás los 8MHz del RC interno, que sería lo que yo te recomendaría. Y como no creo que necesites mucha más cosa, seguramente usarás el timer 1 de 16 bits, para obtener la resolución que quieres o incluso mejor. Al menos, así es como lo haría yo.
Deja que le eche una ojeada al datasheet y al café, y te pongo algo.
Hola otra vez:
Bueno, pues yo lo que haría sería lo siguiente: Usaría el timer 1 de 16 bits, con el prescaler dividiento por 8. De esta manera, cada cuenta sería de 1 us, y podrías llegar hasta los 65500 us, o sea 65 ms.
Lo pondría en modo CTC, o 'Clear Timer on Compare', que lo que hace es empieza de cero cuando el contador llega al valor que se encuentra en el registro OCR1A o ICR1. Yo usaría el segundo, dejando el primero para generar el pulso.
El valor de OCR1A sería el de la duración del pulso que quieres en us, por ejemplo, 500. El valor de ICR1, sin embargo, lo cambiaría cada vez que se generase la interrupción de OC1. En este caso, con una variable static que contase de 0 a 2, y un 'array' de tres valores, lo tendríamos todo hecho.
La rutina de interrupción lo que hace es incrementar el valor del contador estático (que es una variable local que mantiene su valor entre diferentes llamadas de la interrupción), y pone en ICR1 el valor que se encuentra en el array de tiempos que has guardado.
Este array debe tener el valor de tiempo entre el primer pulso (el de sincronía) y el segundo (creo que dices que es el de dirección), el valor de tiempo entre el segundo y el tercero (que creo que es el tiempo de aceleración), y 16000 - T1 - T2, para que el siguiente pulso de sincronismo se genere al cabo de 16 ms del anterior.
Entonces, en el programa principal vas variando los valores de aceleración y de dirección (y recalculando el otro valor) a tu gusto.
Si quieres que te escriba el programa y lo pruebe, voy a necesitar un rato...
Hasta ahora.
No hombre, no lo escribas! sólo quiero saber si es posible trabajar en C y con esa precisión de microsegundos (25 uS por ejemplo), o me tenía que ir a ensamblador.
Lo que quiero hacer es lo que dices, los 3 pulsos el de sincronía, dirección y aceleración, su Ton es fijo de aproximadamente 400 uS. Luego la distancia entre ellos tiene que ser de 1 ms a 2 ms, es decir tengo que generar un Toff de 600uS a 1.6ms, y aquí es donde necesito la precisión.
A lo mejor este Toff tiene que ser de 625 us, 650, us, 675 us.... 950 us, etc... ya que los 1.4 ms de direrencia representa el 100% de la velocidad o del giro, esto lo asignaría un PID.
Como los atmega con c no los he tocado casi, pues era saber si hacer esto me iba a dar problema de tiempos con el c y tendría que pasarme a ensamblador. Es decir si desde C se puede hacer delays tan pequeños sin perder precisión.
Cristal usaría el externo de 16.
Pero si me dices que si sigo con la idea del atmega16, que por cierto me parece que el otro día queme uno al meterle 7 V sin darme cuenta... Y si no va en c pues lo mismo me pongo con su ensamblador, que siempre viene bien conocerlo.
Voy a probar a hacer el programa con el AVR, aunque tardaré que estoy mu pez con él.
Gracias por la respuesta. Saludos.
Si quieres, estoy disponible para echarte un cable. El programa no debería ser muy largo en lo que respecta al control del temporizador.
Si no voy equivocado, a 16MHz no deberías tener problemas con el Timer, pues aunque dividas por 8 la resolución sería de 0.5 us, con un máximo de 32,7 ms, que es más del doble. Eso sí no olvides multiplicar por dos el valor en us que quieras poner en los registros.
El tipo de funcionamiento del timer al que hago referencia es el número 12 de la tabla nº 47 de la página 113 del datasheet el ATmega16. Al menos, del que tengo yo.
Una vez le metí 12V a un ATmega32, se calentó un poco, y sólo se me quemaron algunos pines. Pero como no me fiaba, lo tiré y puse uno nuevo. Son cosas que pasan a los que toqueteamos la electrónica, 😉