Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Al contar el número de pulsos generados por un encoder es posible conocer el desplazamiento angular de
un eje, y si además se analiza este desplazamiento durante un intervalo de tiempo es posible calcular la
velocidad angular.
Para calcular índices de producción en una empresa manufacturera se requiere contar el número de
productos terminados durante intervalos de tiempo establecidos para el proceso.
En computadoras es posible manejar bases de tiempo y contar eventos, tanto por medio de rutinas de software
como por el uso de dispositivos específicamente diseñados para este fin.
La idea básica de la generación de retardos por software consiste en implementar una rutina cuyo tiempo de
ejecución sea igual al retardo que se requiere. El método más simple implementado en todos los procesadores es
por medio de la instrucción NOP (No operar), la cual hace que no exista ningún cambio en el procesador durante
un ciclo de instrucción.
Dependiendo del procesador un ciclo de instrucción puede durar uno o más periodos de reloj del sistema. Debido
a la arquitectura interna del procesador AVR, en el Atmega2560 las instrucciones se miden en ciclos de reloj del
sistema. En particular la ejecución de una instrucción NOP tarda un periodo de reloj del sistema, por lo tanto si se
conecta un cristal de 16 MHz a un Atmega2560 el procesador se tardará 62.5 ns (1/16.000.000) en ejecutarla.
Con base en lo anterior, bastaría con ejecutar diez instrucciones NOP consecutivas para implementar un retardo
de 625 ns:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
¿Cuántas instrucciones NOP consecutivas se tendrían que implementar para generar un retardo de 1 s utilizando
un Atmega2560 con un cristal de 16 MHz?, sería posible implementarlo de esta forma?.
Cuando los retardos requeridos son de larga duración se acostumbra utilizar ciclos, de tal forma que el código
generado no ocupe mucho espacio en la memoria de programa. Cuánto tiempo se tarda el procesador en ejecutar
el siguiente segmento de código?:
Para calcular el tiempo que tarda el procesador en ejecutar un segmento de código, es necesario analizar cuantas
veces se ejecuta cada instrucción del segmento y consultar en el manual del fabricante el tiempo que tarda el
procesador en ejecutar cada una de las instrucciones.
Cuál sería el retardo máximo que se podría alcanzar con la anterior rutina?. Qué hacer cuándo se requieren retardos
mayores?.
Como se puede observar, las rutinas de retardo consisten en segmentos de código que hacen que el
microprocesador gaste una cierta cantidad de ciclos de instrucción equivalentes al tiempo que se desea temporizar.
Debido a que durante este tiempo el procesador no realiza trabajo útil (procesar datos), este método solo se
recomienda para retrasos de corta duración.
Si lo que se desea es contar eventos externos se utilizan rutinas software que implementan el método de encuesta
para la detección de eventos. Este consiste en preguntar por el estado de uno de los terminales de los puertos del
microcontrolador y tan pronto se detecta la ocurrencia del evento se incrementa la variable que lleva el conteo total
de eventos.
Si los pulsos son de larga duración es necesario implementar una lógica de sincronización para evitar el
conteo de un mismo pulso por mas de una vez.
Si el número de instrucciones realizadas entre encuestas simultáneas de los eventos es muy larga, se corre
el riesgo de que se filtren pulsos de corta duración.
En el microcontrolador se cuenta con componentes hardware especializados para el conteo de eventos internos o
externos, tales componentes se denominan temporizadores-contadores. Estos básicamente son contadores
programables a los cuales se le configura, entre otros, la señal de reloj que recibe el contador.
• Configuración como contador: conteo de eventos externos. En este caso los eventos que cuenta el
temporizador-contador ingresan a través de los terminales Tn de los puertos, y estos pueden ser o no
periódicos.
• Configuración como temporizador: conteo de eventos internos. La idea básica de la temporización por
hardware consiste en el conteo de eventos periódicos. Por ejemplo, suponga que existe un bombillo que
prende y apaga periódicamente cada segundo, si se deseara conocer cuando ha transcurrido un minuto
bastaría con contar 60 eventos en el bombillo.
Se considera que la frecuencia de oscilación de los cristales de las computadoras es bastante estable,
aunque puede verse afectada por cambios ambientales, como por ejemplo cambios de temperatura, razón
por la cual en algunas ocasiones las computadoras se almacenan en cuartos donde el ambiente está
controlado. Si se desprecian pequeños cambios en la frecuencia del oscilador esta señal se puede
considerar periódica y por lo tanto en el caso de la configuración como temporizador el temporizador-
contador contará periodos del reloj del sistema.
La ventaja de generar bases de tiempo por medio de temporizadores-contadores es que al ser estos un
hardware independiente al microprocesador, este último puede realizar sus actividades en forma paralela
al temporizador-contador respectivo. Esto quiere decir que mientras el temporizador-contador cuenta
periodos de reloj, el microprocesador puede estar realizando otro tipo de actividades. Además, por medio
de este método es posible disminuir las derivas temporales.
http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-
2561_datasheet.pdf
Los temporizadores llevan el conteo en unos registros que pueden ser 8 o 16 bits dependiendo del
temporizador-contador seleccionado.
o En el segundo caso se inicializa el contador con un valor de tal forma que al contar el número de
periodos requeridos se genere un desbordamiento del contador y se active una bandera de
desbordamiento.
Estas banderas pueden ser encuestadas o también pueden ser configuradas para que generen
interrupciones al procesador.
o TCNT1: Es el registro donde se lleva el conteo y está compuesto por los registros TCNT1H y
TCNT1L (el temporizador-contador 1 es de 16 bits).
En este ejemplo se implementan dos interrupciones, por cada flanco en el pin INT0 se niega el estado
de los bits del puerto A y cada un segundo se niega el estado de los bits del puerto B.
;====================================================================
; DEFINICIONES INICIALES
;====================================================================
;====================================================================
; VECTORES DE INTERRUPCION
;====================================================================
.ORG 0x0000
JMP Inicio
.ORG 0x0002
JMP Int_Externa0
.ORG 0x0028
JMP InterrupcionT1 ; Desbordamiento del Timer 1
;====================================================================
; PROGRAMA
;====================================================================
Inicio:
;====================================================================
; CONFIGURACIÓN DE PERIFÉRICOS: PUERTOS A y B
;====================================================================
LDI TEMP,0xFF
OUT DDRB,TEMP ; Define el Puerto B como salida
OUT DDRA,TEMP ; Define el Puerto A como salida
;====================================================================
; CONFIGURACIÓN DE PERIFÉRICOS: TIMER 1
;====================================================================
;====================================================================
; HABILITAR INTERRUPCIONES INT0, TIMER 1 Y GLOBALES
;====================================================================
LDI TEMP,1<<TOIE1 ;Habilitación de INT_TIMER_1
STS TIMSK1,TEMP
;====================================================================
; BUCLE INFINITO: LOOP
;====================================================================
BUCLE: NOP
JMP BUCLE ; BUCLE INFINITO
;====================================================================
; Subrutina de Atención a la Interrupción del Timer 1
;====================================================================
InterrupcionT1:
RETI
;====================================================================
; Subrutina de Atención a la Interrupción Externa 0
;====================================================================
Int_Externa0:
RETI
;======================================================================
; FIN DEL PROGRAMA
;======================================================================