You are on page 1of 58

INSTITUTO TECNOLGICO DE MORELIA

CURSO AVANZADO DE PROGRAMACIN EN C DE MICROCONTROLADORES AVR


POR DAVID INFANTE SNCHEZ

dinfante29@hotmail.com dinfante@itmorelia.edu.mx

Revisin 8.0 Septiembre del 2008


Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

CAPTULO III. TPICOS AVANZADOS


3.1 Manejo de las Interrupciones INT0 e INT1 Una interrupcin, como su nombre lo indica, interrumpe el programa principal y ejecuta una subrutina de interrupcin donde se ejecuta el cdigo que el programador desea, el ejemplo mas representativo es el RESET de una PC cuando se presiona ese botn se interrumpe el programa principal y vuelve a iniciar el programa. Existen dos tipos de interrupcin las internas o de software y las externas o de hardware, por ejemplo la de reset es una externa ya que est asociada a una terminal. Las de software son generadas por alguna condicin en los perifricos, por ejemplo podemos habilitar una interrupcin cuando el ADC termine de hacer la conversin, o cuando suceda overflow en el timer, etc. El programa CodeVision en la parte de la configuracin del chip se hace la configuracin de la interrupcin ah se habilita la interrupcin y se programa la forma en que funcionar la interrupcin, y el CodeVision generar una subrutina de interrupcin para esa interrupcin en particular. Por ejemplo hay interrupciones que son por flanco de bajada en un pin, entonces, suceder una interrupcin cuando haya un flanco de bajada en el pin. Las subrutinas de interrupcin son como las funciones que hemos realizado, con la excepcin de que las subrutinas de interrupcin SON LLAMADAS POR HARDWARE, es decir el microcontrolador llama a la subrutina de interrupcin cuando el evento sucede y que puede ser en cualquier momento, en cambio las funciones que define el usuario son llamadas por el software segn donde haya escrito el programador el llamado de la funcin.

Figura 3.1 Ubicacin de las interrupciones externas En la figura 3.1 apreciamos las interrupciones externas INT0 e INT1 que estn en los pines 4 y 5 del microcontrolador. Estas interrupciones las podemos configurar para que cuando exista un 0 (low level) se genere una interrupcin, si cuando salga de la interrupcin sigue
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

estando en 0 el pin volver a saltar a la interrupcin. Los otros modos de configurar esas interrupciones es por flanco de subida (rising edge) o por flanco de bajada (falling edge) o ambos flancos (any change). Si se habilita la interrupcin externa INT0 el codevision generar la siguiente subrutina, si se configura que la INT0 funcione en flanco de bajada, cada vez que en ese pin exista un cambio de 1 a 0 saltar a esta interrupcin donde el programador deber colocar el cdigo que deber ejecutarse en ese evento. //External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { // Place your code here } Si se habilita la interrupcin externa INT1 el codevision generar la siguiente subrutina. // External Interrupt 1 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { // Place your code here } Importante. Vimos que la INT0 e INT1 son los pines 4 y 5, y que a su vez son los puertos D2 y D3; as que si habilitamos las funciones de interrupcin INT0 y la INT1, debemos seleccionar esos pines para que sean de entrada; no debemos habilitarlos como salida porque ahora ya no funcionan como pines de entrada/salida sino como pines de entrada donde detectarn un evento (flanco de bajada, subido, ambos o nivel 0 lgico) y en ese momento saltar a la subrutina de interrupcin. Para probar las interrupciones de INT0 e INT1 se realizarn algunos programas para entender su funcionamiento.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Programa 11. Disee un programa que cada vez que haya un flanco de bajada en la INT0 (pin 4) incremente el valor de un display conectado al puerto B, el cual podr contar de 0 a 9. Configuracin: PORTB de salida, Pin D2 de entrada con resistencia de pull-up interna activada y la INT0 que est asociada a ese pin D2 activada y funcionando para generar interrupcin al detectar cambios de flanco de 1 a 0, es decir de bajada.

Figura 3.2 Conexin para el programa 11


/***************************************************** This program was produced by the CodeWizardAVR V2.03.6 Evaluation Automatic Program Generator Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 16/09/2008 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATmega48 Clock frequency : 1,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega48.h> const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f}; unsigned char var; // External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { var++; if (var>9) var=0; // Place your code here }

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

// Declare your global variables here void main(void) { // Declare your local variables here // Crystal Oscillator division factor: 8 #pragma optsizeCLKPR=0x80; CLKPR=0x03; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port B initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0xFF; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=P State1=T State0=T PORTD=0x04; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x00; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

// Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; OCR2A=0x00; OCR2B=0x00; // External Interrupt(s) initialization // INT0: On // INT0 Mode: Falling Edge // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=0x02; EIMSK=0x01; EIFR=0x01; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x00; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // Global enable interrupts #asm("sei") while (1) { PORTB=tabla7segmentos [var]; // Place your code here }; }

Cuando programe el microcontrolador y conecte el microcontrolador notar que cuando se presiona el interruptor el display se incrementa en varias unidades y es por la razn de los rebotes que se generan y que se explicaron en los primeros programas del curso. Programa 12. Disee un programa que cada vez que haya un flanco de subida o bajada en la INT1 (pin 5) incremente el valor de un display conectado al puerto B, el cual podr contar de 0 a 9. Configuracin: PORTB de salidas, PIN D3 de entrada con resistencia de pull-up interna activada y la INT1 que est asociada al pin D3 configurado est habilitada y funcionando para que genere interrupcin en cambio de flanco de 1 a 0 y de 0 a 1.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Figura 3.3 Conexiones para el programa 12


/***************************************************** This program was produced by the CodeWizardAVR V2.03.6 Evaluation Automatic Program Generator Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 16/09/2008 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATmega48 Clock frequency : 1,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega48.h> const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f}; unsigned char var; // External Interrupt 1 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { // Place your code here var++; if (var>9) var=0; } // Declare your global variables here void main(void) { // Declare your local variables here // Crystal Oscillator division factor: 8 #pragma optsizeCLKPR=0x80; CLKPR=0x03; #ifdef _OPTIMIZE_SIZE_ Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

#pragma optsize+ #endif // Input/Output Ports initialization // Port B initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0xFF; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=P State2=T State1=T State0=T PORTD=0x08; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x00; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; OCR2A=0x00; OCR2B=0x00;

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

// External Interrupt(s) initialization // INT0: Off // INT1: On // INT1 Mode: Any change // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=0x04; EIMSK=0x02; EIFR=0x02; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x00; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // Global enable interrupts #asm("sei") while (1) { PORTB=tabla7segmentos [var]; // Place your code here }; }

Programa 14. Disee un programa que cuando haya un flanco de subida en INT0 se incremente el conteo del display que podra contar de 0 a 9, y que cuando haya un nivel lgico de 0 en INT1 se decremente el valor del display.

3.2 Interrupciones externas PCINT0-PCINT23 Adems de las interrupciones INT0 e INT1 existen otras interrupciones externas denominadas PCINTX (Pin Change Interrupt) que son 24 interrupciones desde PCINT0 a PCINT23, pero existen dos diferencias con respecto a las de INT0 e INT1 que son: 1. Las interrupciones PCINTX se activan unicamente en cambios de nivel, es decir cuando el pin cambia de 1 a 0 y de 0 a 1. No pueden configurarse en ninguna otra opcin como las INT0 e INT1 que pueden configurarse para funcionar en flanco de subida, bajada, en ambos o nivel lgico 0. 2. Las interrupciones PCINTX solo tienen tres subrutinas de interrupcin. Cualquier interrupcin generada de PCINT0 a PCINT7 ejecutar la siguiente subrutina de interrupcin. // Pin change 0-7 interrupt service routine
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

interrupt [PCINT0] void pin_change_isr0(void) { // Place your code here } Cualquier interrupcin generada de PCINT8 a PCINT14 ejecutar la siguiente subrutina de interrupcin. // Pin change 8-14 interrupt service routine interrupt [PCINT1] void pin_change_isr1(void) { // Place your code here } Cualquier interrupcin generada de PCINT16 a PCINT23 ejecutar la siguiente subrutina de interrupcin. // Pin change 16-23 interrupt service routine interrupt [PCINT2] void pin_change_isr2(void) { // Place your code here } Tomando como ejemplo esta ltima subrutina de interrupcin indica que cualquier interrupcin generada de PCINT16 a PCINT23 ejecutar esa subrutina, pero no necesariamente cuanda haya un cambio de nivel de 0 a 1 y de 1 a 0 en esos pines ejecutar esa subrutina ya que podemos por el codevision habilitar solamente, por dar un ejemplo, que se habiliten las interrupciones en PCINT16 y PCINT20. En este caso solamente cuando haya cambio de nivel en esos pines se ejecutar la subrutina de interrupcin, es decir, que podemos habilitar de manera individual cada pin. En la figura 3.2 vemos que habilitamos la interrupcin de PCINT0-PCINT7, pero de todas ellas indicamos que slo la PCINT1 y la PCINT5 generar la interrupcin.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Figura 3.2 Habilitacin de las interrupciones PCINT1 y PCINT5 Para probar estas interrupciones realizaremos el siguiente programa Programa 14. Cuando exista cambio de nivel en PCINT0 o en PCINT7 que se incremente el valor de un contador de 0 a 9 que se mostrar en un display conectado al puerto B, cuando exista un cambio de nivel en PCINT8, PCINT9 o PCINT10 se decrementar el valor del conteo y cuando exista Por ejemplo, veamos un programa en el cual se desea detectar cada vez que haya un flanco de bajada en el PIN 18 que es INT1 se incremente un contador BCD que estar conectado al puerto B. El pin 18 que es el pin A2 tiene como funcin alterna la de interrupcin externa INT1, lo vamos a configurar como fuente de interrupcin para detectar flancos de bajada en el pin y que se contabilice en un display conectado al puerto B. Configuracin: Activacin de la Interrupcin externa INT1 (y por lo tanto el pin A2 de entrada), pines B0 a B6 de salida que es donde se conectar el display. Vea el video_P9 donde se muestra la forma de configurar el microcontrolador.
/***************************************************** This program was produced by the CodeWizardAVR V1.25.7a Evaluation Automatic Program Generator Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 04/05/2008 Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATtiny461 Clock frequency : 1,000000 MHz Memory model : Tiny External SRAM size : 0 Data Stack size : 64 *****************************************************/ #include <tiny461.h> unsigned char conteo; const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f}; #define tra_u PINA.1 #define tra_d PINA.0 // External Interrupt 1 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { //Esta es la subrutina de interrupcin INT1 conteo++; //Note que no hay ninguna funcin que la llame if (conteo==10) //Es porque la llama el hardware al detectar un flanco conteo=0; //de bajada // Place your code here } // Declare your global variables here void main(void) { // Declare your local variables here // Crystal Oscillator division factor: 1 #pragma optsizeCLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00; // Port B initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0xFF; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: 8bit top=FFh TCCR0A=0x00; TCCR0B=0x00; TCNT0H=0x00; TCNT0L=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

// Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=OCR1C // OC1A output: Discon. // OC1B output: Discon. // OC1C output: Discon. // Fault Protection Mode: Off // Fault Protection Noise Canceler: Off // Fault Protection triggered on Falling Edge // Fault Protection triggered by the Analog Comparator: Off // Timer 1 Overflow Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off // Compare D Match Interrupt: Off // Fault Protection Interrupt: Off PLLCSR=0x00; TCCR1A=0x00; TCCR1B=0x00; TCCR1C=0x00; TCCR1D=0x00; TCCR1E=0x00; TC1H=0x00; TCNT1=0x00; OCR1A=0x00; OCR1B=0x00; OCR1C=0x00; OCR1D=0x00; DT1=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: On // INT1 Mode: Falling Edge // Interrupt on any change on pins PCINT0-7, 12-15: Off // Interrupt on any change on pins PCINT8-11: Off MCUCR=0x02; PCMSK0=0x00; GIMSK=0x80; GIFR=0x80; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; // Universal Serial Interface initialization // Mode: Disabled // Clock source: Register & Counter=no clk. // USI Counter Overflow Interrupt: Off USICR=0x00; // Analog Comparator initialization // Analog Comparator: Off ACSRA=0x80; // Hysterezis level: 0 mV ACSRB=0x00; // Global enable interrupts #asm("sei") while (1) { // Place your code here PORTB=tabla7segmentos [conteo]; }; }

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Explicacin Dentro del programa principal vemos que se queda de manera infinita ciclado PORTB=tabla7segmentos [conteo]; while (1) { // Place your code here PORTB=tabla7segmentos [conteo]; }; Pero dnde o cmo se incrementa la variable conteo? Recuerde que en la inicializacin habilitamos la interrupcin INT1 y que iba ser por flancos de bajada, esto significa que cada vez que se genere un flanco de bajada en la terminal INT1 el hardware va a llamar a la subrutina de interrupcin de INT1, es decir, el programador no la puede llamar, sino es cuando suceda el evento que genera la interrupcin. La subrutina de interrupcin de INT1 es la siguiente: interrupt [EXT_INT1] void ext_int1_isr(void) { //Esta es la subrutina de interrupcin INT1 conteo++; //Note que no hay ninguna funcin que la llame if (conteo==10) //Es porque la llama el hardware al detectar un flanco conteo=0; //de bajada // Place your code here } Tenga en cuenta que el codewizard genera la subrutina de interrupcin esperando que el programador llene la funcin de interrupcin dependiendo de qu es lo que se desea que se haga cuando sucede el evento de flanco de bajada. En nuestro caso queremos que cada vez que se genera un flanco de bajada se incremente un contador es por ello que colocamos esas instrucciones. La interrupcines INT0 e INT1 tienen sus propias funciones de interrupcin y pueden programarse para que genere una interrupcin por flanco de bajada, subida, ambos o por nivel bajo; cuando se configura por nivel bajo significa que mientras est en nivel bajo se generar la interrupcin, y si cuando sale de la subrutina de interrupcin sigue en nivel bajo volver a saltar a la subrutina de interrupcin. Tambin hay que hacer notar que la INT0 e INT1 son pines distintos, pero si habilita las dos interrupciones y una la habilita por flanco de bajada la otra quedar habilitada con la misma condicin, esto es que no se puede habilitar una por flanco de bajada y otra por flanco de subida ya que es la misma condicin para las dos. Importante. En el diagrama mostrado vemos que le pusimos una resistencia de pull-up externo en el pin de la INT1 y esto es porque ya no le podemos activar la resistencia de pull-up interna debido a que el pin ya no es de entrada/salida digital sino que funciona
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

como una interrupcin externa, cuando pruebe en el circuito puede que se incremente el conteo 1,2 o 3 veces cuando se presione el botn y es porque los interruptores mecnicos generan rebotes, por lo que detectar varios flancos de subida y bajada cuando nosotros lo presionemos una sla vez. Si en vez de conectar un botn conecta un generador de funciones ya no se generaran rebotes y tampoco se necesitara la resistencia de pull-up debido a que el generador no deja flotado el pin, ya que entrega 0 y 1 lgico. Otra diferencia que podemos hacer con respecto a los PICs es que los PICs slo tienen un vector de interrupcin y por tanto saltan a la misma subrutina donde el programador debe checar cul interrupcin se gener, en cambio los AVR tienen vectores de interrupcin distintos por lo que el manejo de interrupciones es decenas de veces ms rpido que los PICs porque estos saltan al mismo vector que los manda a una sola subrutina donde debe probar cada interrupcin para saber cul fue la que la gener. Programa 20. Realizar un programa que cuando haya una interrupcin por flanco de subida en la INT0 se prender un led, y cuando detecte un flanco de subida en INT1 se apagar. El Led se conectar en el pin B0.

Interrupcin por cambio de estado en un pin (PIN Change Interrupt) En el siguiente diagrama vemos que la terminal 20 tiene marcado PCINT0 hasta la terminal 10 que tiene PCINT15. Esto significa PIN CHANGE INTERRUPT X, es decir que se puede generar una interrupcin cuando cambia de nivel lgico esos pines. Si conectaramos a esos pines un interruptor se generara una interrupcin tanto cunado se presiona el interruptor como cuando se suelta, ya que se generara un cambio de nivel en ambos casos. A diferencia de las interrupciones INT0 e INT1 (pines 9 y18) los PCINTX slo funcionan por cambio de nivel lgico es decir en flanco de subida y bajada; y los INT0 e INT1 si los
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

podemos configurar para que funcionen por flanco de subida, bajada, ambos o por nivel lgico 0. La otra diferencia es que las INT0 e INT1 tienen una subrutina de interrupcin distinta. En cambio e la interrupcin PCINT tiene una sla que es la siguiente : // Pin change 0-15 interrupt service routine interrupt [PCINT] void pin_change_isr(void) { // Place your code here }

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Captulo 4. Programacin del TIMER del ATMEGA48


El microcontrolador ATMEGA48 tiene 3 timers. El timer0 es de 8 bits, el timer1 es de 16 bits y el timer3 es de 8 bits. El timer0 est asociado a los pines D5 y D6 (11 y 12), el timer1 est asociado a los pines B1 y B2 (15 y 16) y el Timer2 est asociado a los pines D3 y B3 (5 y 17).

Indico que determinados pines estn asociados a un timer es por la razn de que cuando sucede algn evento en el timer se pueden modificar esos pines ponindose a 1 a 0 o cambiando de valor. Esto es que el Timer puede modificar directamente dos pines asociados a l.

4.1 Partes del TIMER0


TCNT0. El corazn del timer0 es el contador TCNT0 (Counter of Timer 0) de 8 bits que puede contar desde 0 hasta 255, el cual se va incrementando a la frecuencia interna del microcontrolador dividido entre el preescalamiento de 1, 8, 64, 256 o 1024 seleccionado. Es importante sealar que el preescalador divide nicamente la frecuencia de operacin del timer y no la frecuencia del microcontrolador. Vea la siguiente figura, en ella se aprecia que la frecuencia del oscilador interno es de 8 Mhz, el cual es dividido por 8, por lo que la frecuencia de trabajo es de 1MHz. Esa frecuencia es para el CPU y los perifricos, pero a su vez se puede dividir la frecuencia del timer por 1,8 64, 256 o 1024 pero esa divisin slo afecta al timer y no a la frecuencia de operacin del CPU u otros perifricos del microcontrolador. Esa frecuencia preescalada es la que determina cada cundo se va a modificar el timer que es el TCNT0, el valor del TCNT0 se va comparando automticamente con el OCR0A (Registro de Comparacin del Timer 0 salida A que es el pin D6) y con el OCR0B (Registro de comparacin del Timer 0 salida B que es el pin D5), cuando el TCNT0 es igual a uno de esos registros pueden programarse las acciones de: no
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

hacer nada sobre el pin, poner a 1 o a 0 el pin o intercambiar su valor, esto con la finalidad de generar seales.

Figura Estructura del timer 0 OCROA. Este registro de comparacin del Timer0 salida A, es un registro de 8 bits accesible para el programador que continuamente se compara de manera automtica con el TCNT0 y cuando son idnticos se puede generar una accin al Pin D6 que es el pin asociado a la salida A del timer0. OCROB. Este registro de comparacin del Timer0 Salida B es un registro de 8 bits que puede modificar el programador y que continuamente se compara de manera automtica con el TCNT0 y cuando son idnticos se puede generar una accin al Pin D5 que es el pin asociado a la salida B del timer0. FRECUENCIA DE OPERACIN DEL TIMER. El timer se incrementa en una unidad cada determinada cantidad de tiempo. Por ejemplo si la frecuencia del timer es de 1 MHz entonces el periodo es de 1S, esto es que cada 1S se incrementar en 1 el contador. Como el timer es de 8 bits puede contar desde 0 hasta 255 que son 256 cuentas por lo tanto le tomar al TCNT0 256*1S=256S llegar desde 0 hasta 255. El timer puede ser preescalado por 1, 8, 64, 256 o 1024 esto significa que si la frecuencia de operacin del microcontrolador es de 1MHz, puede operar el timer a 1MHz, 125KHz, 15.625KHz, 3906.25 Hz y 976.5625Hz. Suponga que el microcontrolador est operando a 1MHz, entonces el timer trabajar a 1MHz (si est preescalado por 1), pero si se preescala por 1024 entonces trabajar la frecuencia del timer ser 976.5625Hz. Pero recuerde que esa frecuencia es la velocidad con la que se incrementar en una unidad el timer, y que el timer cuenta 256 pulsos. Lo primero que debe hacer el programador es identificar la velocidad de operacin del microcontrolador para determinar las frecuencias del timer. Estos valores descritos son
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

considerando que el microcontrolador opera a 1MHz como es el caso de un microcontrolador nuevo que viene de fbrica a 8MHz pero dividida la frecuencia de operacin entre 8, por ello opera a 1MHz el microcontrolador, y a su vez puede preescalarse la frecuencia del timer entre 1, 8, 64, 256 y 1024. Si configuramos el timer para que se preescale entre 1024 entonces la frecuencia del timer ser de 976.5625 Hz, y el periodo ser de 1.024 mS as que el timer se incrementar en 1 unidad cada 1.024mS. El tiempo que le llevar al timer ir desde 0 hasta 255 sern 256 cuentas*1.024mS=0.262144 Segundos. Las siguientes tablas deber tenerlas en mente para los clculos usados para programar el timer, y tambin tenga en cuenta que estas tablas son vlidas son para una frecuencia interna de 1MHz, as que si coloca un cristal externo entonces deber recalcular estas tablas a esa frecuencia usada. Frecuencia Interna 1 MHz 1 MHz 1 MHz 1 MHz 1 MHz Tabla de frecuencia y periodos del timer 0 Tiempo que tarda en incrementarse en una Preescalamiento Frecuencia unidad el timer (1/Frecuencia Timer) del timer 1 1 MHz 1 S 8 125KHz 8 S 64 15.625KHz 64 S 256 3906.25 Hz 256 S 1024 976.5625Hz 1.024 mS

Con los tiempos anteriores podemos calcular el tiempo que le tomar al timer ir de 0 hasta 255 (256 cuentas) Tabla de conteo mximo del timer (256 Cuentas) Periodo de una cuenta Tiempo que le llevar contar 256 cuentas 1 S (1 MHz) 256 S 8 S (125 KHz) 2.048 mS 64 S (15.625KHz) 16.284 mS 256 S (3906.25 Hz) 65.536 mS 1.024 mS (976.565 Hz) 0.262144 S Importante. Recuerde que estas tablas son para una frecuencia de operacin del microcontrolador de 1 Mhz y que si conecta otro cristal deber calcular los tiempos y frecuencias. Importante. El oscilador interno del microcontrolador es del tipo RC por lo que la frecuencia NO ES EXACTA y VARA CON LA TEMPERATURA pero es cercana a 1 MHz. Para control de tiempos exactos deber conectarse un oscilador o cristal externo.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

ACCIONES SOBRE EL PIN D5 Y PIN D6. Cuando el TCNT0 se iguala al valor del OCR0A o el OCR0B se puede hacer que en el pin se ponga a 1 o 0, o que cambie de valor en el pin D5 o D6. OVERFLOW o SOBREFLUJO. El timer va incrementndose en una unidad cada determinada cantidad de tiempo, segn la frecuencia y el preescalamiento, pero el timer tiene un determinado ancho en bits por lo que el nmero mximo que puede almacenar est limitado. Por ejemplo el timer0 es de 8 bits por lo que puede tener un nmero desde 0 hasta 255 (0 a FFh) pero cuando tiene 254 y cuenta una unidad ms, el timer se incrementa a 255, y si cuenta un nmero ms ya no cabe el 256 en 8 bits, por lo que el timer se regresa a 0 esto se conoce como overflow, es decir llegar al valor mximo y contar un pulso ms que hace que el timer regrese a cero. SEALES PWM. Una seal PWM (Pulse Width Modulation) o modulacin por ancho de pulso tiene las siguientes caractersticas: El periodo de la seal es fijo, lo que cambia es el ancho de pulso. PWM no invertida, en esta figura se aprecia que el periodo de la seal es fijo y lo que se modifica es el ancho de pulso, en el primer ciclo la modulacin est al 50%, esto es que durante todo el periodo de la seal estar en 1 el pulso, en el siguiente ciclo se encuentra la modulacin es del 75%, as que estar en 1 durante partes del periodo de la seal, y en el ltimo ciclo est al 100% la modulacin, as que est en 1 todo el tiempo que dura el periodo de la seal.

Las seales PWM son muy utilizadas en control de energa de CA y CD. Si conectramos un LED con un PWM al 50% veramos que est ligeramente encendido, si subimos el ancho de pulso el LED prendera con mayor intensidad, y si la modulacin est al 100% el LED prendera al mximo de intensidad lumnica. PWM invertida. En una seal PWM invertida la modulacin es cunto tiempo estar en 0 la seal. Cuando est al 75% significa que partes del periodo de la seal estar en 0. Vea la siguiente figura de una seal PWM invertida al 50%, 75% y 100%.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

PWM con Modulacin no invertida al centro. En determinados tipos de control de motores la modulacin no se hace con respecto al inicio del periodo, sino con respecto al centro. En la siguiente figura se aprecia PWM con modulacin no invertida al centro con modulacin al 50%, 75% y 100%.

En la figura anterior se nota que el pulso va creciendo con respecto al centro, y que si la modulacin es del 50% entonces durante 50% del tiempo del ciclo estar en 1 pero centrado con respecto al periodo de la seal. PWM con Modulacin invertida al centro. En este tipo de modulacin la modulacin es el tiempo que est en 0 con respecto al centro del periodo, y en la siguiente figura se tienen este tipo de modulacin al 50%, 75% y 100%.

Estos modos de modulacin del PWM se ilustraron y explicaron debido a que con el TIMER del ATMEGA es posible generarlos con su timer. En los siguientes subtemas se pondr el modo de funcionamiento del timer en ingls que es como lo pone el wizard del codevision y en espaol no ser propiamente su traduccin, sino ser una traduccin basada en su funcionamiento.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

4.2 Modo Normal top=FFH (Modo Normal del Timer contando desde 0 hasta 255d)
Modo Normal top=FFh En este modo el timer cuenta desde 0 hasta 255 cuando llega a 255 y se detecta un conteo ms se regresa a 0. Esta accin se le conoce como sobreflujo (overflow) porque despus de 255 el valor correcto debera ser 256, pero como no cabe el 256 en 8 bits sucede el sobreflujo por lo que se regresa a 0 y sigue acumulando pulsos el timer hasta llegar a 255 repitindose el 0 al siguiente pulso, esto es que cuenta de manera cclica de 0 a 255. Registros de comparacin OCROA y OCROB, estos dos registros significan que dar una salida a la comparacin con el timer (Output A Compare Register of Timer 0 y Output B Compare Register of Timer 0), estos registros son accesibles para que el programador les escriba un nmero y se comparan continuamente y de manera automtica con el timer (TCNT0) y cuando se hacen iguales se genera una accin.

Por ejemplo si se les escribe lo siguiente: OCR0A=100; OCR0B=200; Significa que cuando el timer (TCNT0) tenga el valor de 100 se generar una accin, y cuando el timer (TCNT0) valga 200 se generar otra accin. Tabla Acciones que se pueden programar a la comparacin Las acciones que se pueden generar Descripcin Disconnected No hay ningn efecto Toggle on Compare match Conmuta el valor del pin Clear on Compare match Se pone en 0 el pin
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Set on compare match

Se pone a 1 el pin

Note que el OCR0A est asociado al pin D6 y el OCR0B est asociado al pin D5. Las acciones que se generarn a la comparacin con el OC0A y OC0B se configuran con el wizard del codevision. Suponga que el OCR0A=100; y el OCR0B=200; y se selecciona Set on Compare Match en la salida A y se selecciona Toggle on Compare Match en la salida B, entonces cuando el timer (TCNT0) sea igual al OCR0A, es decir 100, entonces el pin se pondr en 1, es por eso que est en 0 el pin D6 (lnea roja) antes de 100 y despus de 100 se mantiene en 1. Si la salida B se configura en Toggle on Compare Match, significa que al hacerse el TCNT0 igual al OCR0B que es 200, entonces cambiar el estado del pin, as que la primera vez cambia de 0 a 1, cuando se hace el TCNT0 igual al OCR0B que es igual a 200, entonces cambia de 1 a 0 (lnea azul) y as sucesivamente como se ve en la figura siguiente.

Resumen del timer 0 en el modo de Normal Top = FFh El timer0 usa el TCNT0 y se va incrementando este registro en cada pulso de reloj. El timer0 puede preescalarse para que el conteo se haga ms lento y el preescalamiento es de 1, 8, 64, 256 y 1024. El timer0 es de 8 bits y cuenta desde 0 hasta 255 y regresa a 0 y as sucesivamente. El timer0 tiene dos registros de comparacin OCR0A y OCR0B cuando esos registros tienen el mismo valor que el TCNT0 se hace una accin que afecta al pin D6 y D5 respectivamente Las acciones que se pueden generar son: nada, ponerse a 1 el pin, ponerse a 0 el pin o que conmute el estado del pin.

Note que si se selecciona la accin de que se ponga a 1 el pin, el pin se quedar en 1. Si se selecciona que se ponga a 0 el pin se quedar en 0. El efecto que podemos ver es el conmutacin (Toggle on Compare Match) porque el pin estar cambiando de estado continuamente. Programa timer1. Configure el timer0 de tal manera que en la salida B (pin D5) se genere una seal cuadrada que dur 2.048 mS en bajo y 2.048 mS en alto. En este modo de
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

operacin el periodo de la seal no se puede modificar porque el timer siempre cuenta desde 0 hasta FF, y de los clculos antes vistos tenemos: Frecuencia Interna 1 MHz 1 MHz 1 MHz 1 MHz 1 MHz Tabla de frecuencia y periodos del timer 0 Tiempo que tarda en incrementarse en una Preescalamiento Frecuencia unidad el timer (1/Frecuencia Timer) del timer 1 1 MHz 1 S 8 125KHz 8 S 64 15.625KHz 64 S 256 3906.25 Hz 256 S 1024 976.5625Hz 1.024 mS

Con los tiempos anteriores podemos calcular el tiempo que le tomar al timer ir de 0 hasta 255 (256 cuentas) Tabla de conteo mximo del timer (256 Cuentas) Periodo de una cuenta Tiempo que le llevar contar 256 cuentas 1 S (1 MHz) 256 S 8 S (125 KHz) 2.048 mS 64 S (15.625KHz) 16.284 mS 256 S (3906.25 Hz) 65.536 mS 1.024 mS (976.565 Hz) 0.262144 S Entonces debemos escoger el preescalamiento de 8 que es la frecuencia de 125KHz para que nos d el periodo de 2.048mS. Luego debemos configurara para que la accin a generar en la comparacin del TCNT0 con el OCR0B sea Toggle on Compare Match para que cuando sean iguales el estado del pin D5 se invierta de valor. Qu valor debemos poner en OCR0B? No importa el valor que se ponga porque sin importar el valor que tenga sucedern 256 pulsos ms para que cambie de valor. Vea la siguiente figura:

Si en OCR0B coloca un 10, transcurrirn 256 cuentas para que suceda otro 10 e invierta el estado del pin, si coloca un 20 sucedern 256 cuentas para que ocurar otro 20, as que no importa el valor que le ponga al OCR0B. Para este ejemplo pondremos un 100d.
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

La configuracin debe ser as: Chip ATMEGA48 dividido por 8, luego en Timer0 deber dar click en los siguientes puntos del timer0, cuando le indique que se va a guardar el proyecto saldr la ventana de la derecha donde le dice que si activa el pin D5 como salida ah deber decir que s porque el Pin debe ser configurado como salida para que muestre las seales, note tambin que en la parte ms baja del Timero se coloc un 64h que es un 100 decimal.

Figura. Seleccin del timer 0 para el programa Vea el vdeo timer1 donde se explica el programa y la inicializacin del timer para el siguiente programa. Grabe el programa en el microcontrolador y no deber agregar nada extra al programa porque el asistente inicializ completamente el Timer0, alimente el microcontrolador y conecte un osciloscopio en el pin D5 y ver la siguiente forma de onda:

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

En el programa anterior expliqu que no podemos modificar el periodo de la seal, pero podemos actualizar continuamente los registros de comparacin para generar cualquier periodo en la seal, primero veremos la tabla que ya se haba calculado: Tabla de conteo mximo del timer (256 Cuentas) con una frecuencia de 1MHZ Periodo de una cuenta Tiempo que le llevar contar 256 cuentas 1 S (1MHz) 256 S 8 S (125KHz) 2.048 mS 64 S (15.625KHz) 16.284 mS 256 S (3906.25 Hz) 65.536 mS 1.024 mS (976.565 Hz) 0.262144 S Si quisiramos generar seales cuadradas con una frecuencia digamos de 2Khz, debemos hacer lo siguiente: El periodo de una seal de 2KHz es 0.5mS, con 0.25mS en alto y 0.25mS en bajo, por lo que debemos escoger un preescalamiento que d ms de 0.5mS para que quepa la seal que queremos generar, de esa forma vemos que podemos seleccionar cualquier preescalamiento del segundo en adelante, porque en el primero el tiempo mximo que podemos medir son 256S y ocupamos que sea mayor a 0.5 mS, pero cul de todos es el ms adecuado? Para ello pondr el siguiente ejemplo: Cuando va a medir 1.5 Volts Cul escala selecciona 2, 20 o 200 Volts? Selecciona el ms cercano es decir 2 Volts para una mayor resolucin; para el timer razonamos de la misma forma, cul se encuentra ms cercano a 0.5mS la opcin sera la frecuencia de 125 Khz que est resaltada en verde porque el periodo del timer a las 256 cuentas da 2.048 mS.
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Es importante sealar que la frecuencia de 125 KHz es la velocidad con la que se incrementa el timer en una unidad, que en tiempo corresponde a 8 S. Pero el ciclo del timer se cumple cuando cuenta desde 0 hasta 255 (256 cuentas) que en tiempo corresponde a 8 S *256=2.048 mS. Una cuenta con la frecuencia de 125 Khz tarda 8uS, entonces queremos que la seal cambie cada 0.25mS, as que traducido en cuentas sera 0.25mS/8uS=31.25 cuentas, pero no podemos 31.25 as que lo redondeamos a 31. El contador TCNT0 se comparar continuamente con el OCR0A y el OCR0B, si vamos a utilizar la salida A (pin D6) en modo de toggle on compare match (conmutacin del pin a la comparacin) entonces en el OCR0A le escribimos el 31 para que cambie el pin a los 0.25mS, pero los otros 0.25mS ocurrirn a las 62 cuentas, y los siguientes 0.25 mS sucedern a las 93 cuentas y as sucesivamente. As que en este programa debemos actualizar continuamente el OCR0A. El timer tiene la posibilidad de generar una interrupcin a la comparacin del TCNT0 con el OCR0A y OCR0B. Cuando el TCNT0 sea igual al OCR0A se generar una interrupcin y en la interrupcin lo que haremos es leer el OCR0A para sumarle 31 para que la siguiente comparacin sea 31 cuentas despus o 0.25mS despus, cuando sea TCNT0 igual al OCR0A se generar otra interrupcin y sumaremos otros 31 al OCR0A para que el siguiente cambio del pin sea 0.25mS despus. Vea la grfica siguiente:

A las 31 cuentas conmutar el pin y se generar una interrupcin donde instrucciones para actualizar el registro OCR0A a 62, cuando el TCNT0 sea igual a 62 cambiar el pin y se generar una interrupcin para actualizar el OCR0A a 93 y as sucesivamente. Ve el vdeo timer2 donde se explica la inicializacin del timer para el siguiente programa. Programa timer2. Configure el timer para generar una seal cuadrada con una frecuencia de 2KHz que se generar en el pin D6 (salida A del timer0). Seleccione Chip ATMEGA48, 8 Mhz dividido por 8 y en el timer seleccione lo que se muestra en la siguiente figura:

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Note que estamos habilitando interrupcin por comparacin en el OCR0B con el TCNT0 (Compare Match B Interrupt) y el codewizard generar la siguiente subrutina de interrupcin: // Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { // Place your code here } Note que cuando nos genera la subrutina de interrupcin coloca como comentario en la parte superior: // Timer 0 output compare A interrupt service routine Esto es til para que el programador sepa de cul subrutina de interrupcin se trata. Ese comentario traducido es: Subrutina de Interrupcin por Comparacin de la salida B del timer0. Recuerde que las subrutinas de interrupcin no las llama el programador, sino el evento, que en este caso es cuando el TCNT0=OCR0A si son iguales salta a esa subrutina de interrupcin. Entonces cuando el OCR0A con el TCNT0 qu debemos hacer: leer el valor del OCR0A y sumarle 31 para que se compare 31 cuentas despus que son 0.25mS.Es decir que el cdigo que colocaremos en esa subrutina de interrupcin es: OCR0A=CR0A+31; Note tambin en la imagen anterior que se seleccion en el wizard Out:A Toggle on Compare Match para que cada vez que el TCNT0 sea igual al OCR0A cambie de estado el pin D6.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

De acuerdo a lo que seleccionamos con el wizard del codevision se configur para que el pin D6 (salida A del timer 0) cambie de estado cuando el TCNT0=OCR0A, y adems que se genere una interrupcin, en esa subrutina de interrupcin actualizamos el valor del OCR0A en 31 cuentas (0.25 ms) para que el siguiente cambio del pin suceda precisamente a los 0.25 mS. Recuerde que es importante indicar en la parte de chip que es el ATMEGA48 y que se est trabajando a 8 MHz y dividido entre 8 como en todos los programas que hemos realizado. El listado del programa genereado por el wizard es el siguiente, lo que deber agregar a su programa es lo que est en azul.
/***************************************************** This program was produced by the CodeWizardAVR V2.03.6 Evaluation Automatic Program Generator Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 02/11/2008 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATmega48 Clock frequency : 1,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega48.h> // Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { OCR0A=OCR0A+31; // Place your code here } // Declare your global variables here void main(void) { // Declare your local variables here // Crystal Oscillator division factor: 8 #pragma optsizeCLKPR=0x80; CLKPR=0x03; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=0 State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x40; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 125,000 kHz // Mode: Normal top=FFh // OC0A output: Toggle on compare match // OC0B output: Disconnected TCCR0A=0x40; TCCR0B=0x02; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; OCR2A=0x00; OCR2B=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=0x00; EIMSK=0x00; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

TIMSK0=0x02; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // Global enable interrupts #asm("sei") while (1) { // Place your code here }; }

Lo nico que se agreg al programa generado por el codewizard es lo que se encuentra en azul y esto fue: OCR0B=OCR0B+31; // Place your code here Cuando el TCNT0 se iguala al OCR0A cambia de estado el pin y se genera una interrupcin para actualizar el OCR0A sumndole 31 cuentas que son equivalentes 0.25mS. En la siguiente imagen se muestra una fotografa de la seal generada de este programa en un osciloscopio.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

4.3 Modo Phase Correct PWM top=FFh (Modo PWM con modulacin al centro y con periodo fijo de 510 cuentas)
En este modo de funcionamiento el timer (TCNT0) cuenta de 0 hasta 255 y luego decrementa su valor hasta llegar a 0 y despus vuelve a incrementarse hasta llegar a 255, y as sucesivamente. Es decir, en este modo de operacin el timer es ascendente hasta llegar al mximo y despus se hace descendente. El periodo del timer es 510 ya que cuenta de manera ascendente y luego de manera descendente. La traduccin de este modo sera PWM con correccin de fase y quizs no le d una idea clara, pero en otras palabras y segn su funcionamiento es: PWM centrado con periodo de 510. La razn de este periodo doble es que un ciclo del timer es cuando va de 0 hasta 255 y de ah regresa a 0, es por ello que el periodo se hace de 510 pulsos (2*255) de reloj. Aqu tambin se utilizan los registros de 8 bits del timer 0 que son OCR0A y OCR0B, estos dos registros se comparan de manera automtica con el timer (TCNT0) y cuando se hacen iguales pueden suceder las siguientes acciones en los pines D6 y D5 que es donde estn asociados los registros respectivamente: 1. Disconnected. No hay efecto sobre el pin 2. Non-inverted PWM. En esta configuracin al iniciar el timer comienza el pin en 0 al hacerse igual al OCR0X el pin se pone a 1, despus el timer (TCNT0) llega al mximo y comienza a decrementarse cuando son iguales el TCNT0 y el OCR0X el pin se pone en 0. 3. Inverted PWM. En esta configuracin al iniciar el timer en 0 comienza el pin en 1 cuando se iguale el TCNT0 con el OCR0X el pin se pone a 0, al llegar el TCNT0 al mximo regresa en un conteo descendente y al hacerse igual al OCR0X el pin se pone nuevamente a 1, esto es que la seal generada es exactamente la inversin de la seal del punto 2. Las acciones 2 y 3 corresponden al PWM con Modulacin no invertida e invertida al centro que se explic en la seccin 4.1 Ejemplo. Suponga que se configura el timer en el modo de Phase Correct PWM top=FFh y se selecciona la salida A en Non Inverted PWM y se carga en OCR0A=100; y la salida B en Inverted PWM y se carga en OCR0B en 200; en la siguiente figura se ilustra la forma de la seal en el PIND6 que es la asociada a la salida A (OCR0A) y el PIND5 que es la asociada a la salida B (OCR0B). En la figura vea que el contador inicia en 0 y llega hasta 255 despus al siguiente pulso el timer comienza a decrementarse por eso el siguiente conteo es 254 hasta llegar a 0 (el periodo es 510 cuentas porque va de 0 al mximo y de ah se decrementa). En la salida A se seleccion Non Inverted PWM, y se carg en el OCR0A un 100, entonces cuando el TCNT se iguala al OCR0A se pone a 1 el pin D6 y cuando se vuelve hacer el TCNT igual al OCR0A se pone en 0.
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

La lnea azul ilustra la seal en el PIN D5 que est asociada a la salida B del timer0, aqu se ejemplifica el funcionamiento Inverted PWM, note que el pin inicia en 1, al igualarse el OCR0B con el TCNT0 se pone a 0 y al volverse a igualar se pone nuevamente en 1.

Si ha cursado materias de control y de potencia notar que estas seales ilustradas son tiles en control de motores. Programa para ejemplificar el funcionamiento del PWM con modulacin al centro no invertida. Si la frecuencia interna de operacin es de 1MHz y los preescalamientos son 1, 8, 64, 256 y 1024. Tenemos las frecuencias de operacin del timer de: Frecuencia Interna 1 MHz 1 MHz 1 MHz 1 MHz 1 MHz Tabla de frecuencia y periodos del timer 0 Tiempo que tarda en incrementarse en una Preescalamiento Frecuencia unidad el timer (1/Frecuencia Timer) del timer 1 1 MHz 1 S 8 125KHz 8 S 64 15.625KHz 64 S 256 3906.25 Hz 256 S 1024 976.5625Hz 1.024 mS

Con los tiempos anteriores podemos calcular el tiempo que le tomar al timer ir de 0 hasta 255 y regresar a 0 (510 cuentas), esta tabla cambia con respecto a las antes vistas debido a que el timer cuenta 510 pulsos. Tabla de conteo mximo del timer (510 Cuentas) Periodo de una cuenta Tiempo que le llevar contar 510 cuentas 1 S (1 Mhz) 510 S 8 S (125 KHz) 4.08 mS 64 S (15.625KHz) 32.64 mS 256 S (3906.25 Hz) 130.56 mS 1.024 mS (976.5625Hz) 0.52224 S
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Programa timer3. Escriba un programa con PWM no invertido con un ancho de pulso del 50%. Con un periodo de la seal de 32.64mS. La seal se generar en la salida B del timer0. Vea la inicializacin del timer para este programa en el video timer3. Note que no podemos modificar el periodo de la seal, ya que el nmero de cuentas es fijo y es de 510 adems de que las frecuencias preescaladas es limitada 5 opciones. Si queremos un ancho de pulso del 50% tenemos que cargar en el OCR0B un 127, porque 127 es la mitad del 255. Vea el siguiente diagrama para que vea el periodo de 510 pulsos y que con 127 en el OCR0B se tiene el 50% del ancho de pulso.

Cuando el TCNT0 va incrementndose y se hace igual al 127 del OCR0B se pone a 1 el pin D5 y se mantiene as hasta que el TCNT0 va decrementndose y se vuelve hacer igual a 127. Seleccione el timer0 como se muestra en la siguiente figura

Configuracin del timero

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Note que en la parte de abajo se escribi Compare B: 7fh que corresponde al 127 y este 127 es el valor que se cargar en el OCR0B. El programa que genera el codewizard es el programa completo y no hay que agregar ninguna instruccin.

Foto de la seal generada en el programa timer3

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

4.4 Modo Fast PWM top=FFh (PWM con periodo fijo de FFh cuentas)
En este modo el timer (TCNT0) cuenta desde 0 hasta 255, al siguiente pulso inicia en 0 hasta llegar a 255 cuentas y as sucesivamente. En este caso el periodo de la seal es de 256 cuentas. La salida A del timer0 (TCNT0) se iguala al valor del OCR0A o al OCR0B pueden suceder las siguientes acciones sobre el pin D6 y D5 respectivamente: 1. Disconnected. No hay efecto sobre el pin 2. Non-inverted PWM. En esta configuracin al iniciar el timer comienza el pin en 0 al hacerse igual al OCR0X el pin se pone a 1 y se mantiene as hasta que el TCNT0 llega a 255, en el siguiente conteo el TCNT0 regresa 0 y el pin se pone a 0 nuevamente. 3. Inverted PWM. En esta configuracin al iniciar el timer en 0 comienza el pin en 1 cuando se iguale el TCNT0 con el OCR0X el pin se pone a 0 y se mantiene as hasta que el TCNT0 llega a 255, en el siguiente conteo el TCNT0 regresa a 0 y el pin se pone a 1 nuevamente. En la siguiente figura vemos que el periodo es de 256 cuentas, ya que el timer0 (TCNT0 va desde 0 hasta 255), el siguiente conteo a 255 es el 0 para iniciar nuevamente el conteo. Suponga que la salida A del timer0 asociada al pin D6 se configura como Non-Inverted PWM y se carga en el OCR0A un 100, entonces al inicio del conteo del timer el pin D6 (lnea roja) el pin est en 0, cuando el TCNT0 se hace igual al OCR0A se pone a 1 el pin, y se mantiene en 1 hasta que el timer llega a 255, al siguiente pulso el timer regresa a 0 repitindose el ciclo del timer0 e iniciando el pin en 0. Considere que la salida B del timer0 (asociada al pin D5) se configura como Inverted PWM y que se carga en el OCR0B un 200, entonces al inciio del conteo del timer el pin D5 (lnea azul) se pone en 1 y cuando el TCNT0=OCR0B que es 200 el pin se pone en 0 y se mantiene en ese estado hasta que llega a 255, luego el timer inicia su ciclo en 0 y tambin el pin se pone en 1 y se coloca en 0 hasta que nuevamente el TCNT0 se hace igual al OCR0B.

En materias de control y potencia se utilizan este tipo de seales para el control de la energa en CD y AC, para el control de ngulos de disparo de tiristores.
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Programa Timer4. Controlar la energa lumnica de un LED mediante una seal PWM que se generar en la salida B del timer0 (pin D5). EL ancho de pulso se controlar mediante un potencimetro conectado al canal 0 del ADC (Pin C0) Este potencimetro variar el voltaje desde 0 hasta 5 Volts. Vea el video timer4 donde se muestra la configuracin del microcontrolador. En el circuito recuerde ponerle una resistencia de 330 Ohms al Led para limitar la corriente en el pin. Importante. Recuerde que si va a utilizar un pin como entrada analgica del ADC deber configurarlo como entrada y sin resistencia de pull-up ese pin. En caso de que lo configure como salida el pin y le aplique un voltaje puede daar el pin. Si la frecuencia del PWM es menor a 60Hz se ver parpadeando el LED, pero si la frecuencia es mayor o igual a 60 Hz (periodo de 16.6 mS) no se ver el parpadeo del LED, sino el promedio de voltaje aplicado a ste. Entonces se seleccionar un periodo de 16.284mS para 256 cuentas, que corresponde a una frecuencia de conteo de 15.625 KHz. Tabla de conteo mximo del timer (256 Cuentas) Periodo de una cuenta Tiempo que le llevar contar 256 cuentas 1 S (1 Mhz) 256 S 8 S (125 KHz) 2.048 mS 64 S (15.625KHz) 16.284 mS 256 S (3906.25 Hz) 65.536 mS 1.024 mS (976.5625Hz) 0.262144 S La configuracin del timer y del ADC deber hacerla de la siguiente manera:

Figura. Inicializacin del timer y del ADC


Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Note que se est habilitando la interrupcin por sobreflujo (Ovreflow Interrupt) del timer, entonces cuando el timer llegue al valor mximo de conteo que es FFh y se d un pulso ms el timer se har cero y se generar la interrupcin por sobreflujo, y en esta interrupcin lo que haremos es leer el canal 0 del ADC y ese valor se cargar en el OCR0B. Entonces a mayor voltaje en el canal 0 del ADC se generar un ancho de pulso ms grande y por lo tanto el LED emitir una mayor intensidad lumnica. Vea que en la subrutina de interrupcin por sobreflujo del timer0 leemos el canal 0 del ADC y lo cargamos en el OCR0B que es el registro que determina el ancho de pulso del PWM. Esto se muestra en el siguiente cdigo: // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { OCR0B=read_adc(0); // Place your code here } Coloque el cdigo en azul en la subrutina de interrupcin como se muestra en el siguiente listado y complelo y ver que marca un error. Ese error es porque la subrutina del ADC est abajo de la subrutina de interrupcin de sobreflujo, entonces al llamar la funcin de read_adc(0) no la encuentra porque la subrutina est abajo. Entonces debe invertir esa dos subrutinas: copie el cdigo del ADC en la parte superior y la del timer en la parte de abajo. (son los bloques de cdigo verde y rosa) y debern quedar como se muestra en este listado.
/***************************************************** This program was produced by the CodeWizardAVR V2.03.6 Evaluation Automatic Program Generator Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 27/10/2008 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATmega48 Clock frequency : 1,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega48.h> #include <delay.h> Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

#define ADC_VREF_TYPE 0x60 // Read the 8 most significant bits // of the AD conversion result unsigned char read_adc(unsigned char adc_input) { ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); // Delay needed for the stabilization of the ADC input voltage delay_us(10); // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; return ADCH; } // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { OCR0B=read_adc(0); // Place your code here } // Declare your global variables here void main(void) { // Declare your local variables here // Crystal Oscillator division factor: 8 #pragma optsizeCLKPR=0x80; CLKPR=0x03; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=0 State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x20; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 15,625 kHz // Mode: Fast PWM top=FFh // OC0A output: Disconnected // OC0B output: Non-Inverted PWM TCCR0A=0x23; TCCR0B=0x03; TCNT0=0x00; Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; OCR2A=0x00; OCR2B=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=0x00; EIMSK=0x00; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x01; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // ADC initialization // ADC Clock frequency: 500,000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: None // Only the 8 most significant bits of // the AD conversion result are used // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On // ADC4: On, ADC5: On Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

DIDR0=0x00; ADMUX=ADC_VREF_TYPE & 0xff; ADCSRA=0x81; // Global enable interrupts #asm("sei") while (1) { // Place your code here }; }

Foto a) Modulacin con un ancho de pulso muy pequeo, note que el voltaje medio es de 64.2mV por lo que el led tendr una intensidad muy baja.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

El ancho de pulso se incrementa y el voltaje promedio tambin sube, el led obtiene mayor intensidad.

En la foto anterior el ancho de pulso es ms grande y por lo tanto el voltaje promedio sube.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

En los modos vistos el periodo est fijo, ya que el TCNT0 cuenta desde 0 hasta 255 en los modos Normal top=FFh y en el FAST PWM top=FFh; o de 0 hasta 255 y despus se decrementa hasta llegar a 0 (510 cuentas) en el modo Phase correct PWM top=FFh. Pero existen otros tres modos en los cuales el programador puede configurar el periodo de la seal, recuerde que el periodo se fija en nmero de cuentas. Estos modos los veremos a continuacin. 4.5 Modo CTC top =OCR0A (Timer contando desde 0 y con tope el valor de OCR0A) Este modo Clear Timer on Compare with OCR0A o traducido segn su funcionamiento es: reinicializacin del timer cuando se haga igual al OCR0A, es decir que si seleccionamos este modo de operacin el OCR0A es el tope del timer0, entonces si OCR0A=100 entonces el timer contar de 0 hasta 100 y al siguiente conteo regresar a 0 el timer para continuar su conteo. Vemos que en este modo el programador fija el periodo de la seal a travs del registro OCR0A. El funcionamiento de este modo es exactamente igual al de Modo Normal top=FFh pero con la diferencia de que el timer no cuenta hasta FFh sino hasta el valor del OCR0A, las acciones que se pueden generar en los pines D5 y D6 son las definidas en el Modo Normal top=FFh Programa Timer5. Disear un programa que cada 10mS cambie de estado el pin B0. Para ello se utilizar la interrupcin por comparacin con el OCR0A. Aqu notamos que el pin B0 no est asociado a ningn timer, pero aqu usaremos el timer como un temporizador, no como un generador de seales, as que cada 10mS se generar una interrupcin en la cual se cambiar de estado el pin B0. Para empezar necesitamos seleccionar una frecuencia del timer que multiplicada por 256 cuentas sea la ms cercana y mayor a 10mS. Los 10 mS caben en una frecuencia de conteo de 15.625KHz. Cuntas cuentas debe tener el timer para que genere una interrupcin cada 10mS? 10mS/64uS=156.25 pero como deben ser enteros sera un 156. El timer contar desde 0 hasta 156 y luego regresar a 0 hasta llegar a 156 y as continuamente. Cuando el timer llegue a 156 sucedern dos cosas: el timer regresa a 0 al siguiente conteo y el timer ser igual al OCR0A. En este programa activaremos la interrupcin por comparacin con el OCR0A y en esa interrupcin cambiaremos de estado el pin B0. Note que la interrupcin se generar cada 156 cuentas que corresponden a 10mS. Quien define el valor mximo al que contar el timer en este modo es el OCR0A. Entonces hacemos OCR0A=156d que en hexadecimal es 9Ch.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Figura Inicializacin del timer0 para el programa5

El wizard del codevision generar la siguiente subrutina de interrupcin por comparacin el OCR0A con el timer0 (TCNT0). // Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { // Place your code here
}

Esta subrutina de interrupcin ser llamada cada vez que el TCNT0 sea igual al OCR0A, y esto suceder cada 156 cuentas, que en tiempo corresponde a 10mS, y en esa subrutina deberemos colocar: PORTB.0=~PORTB.0; Y eso hace que el pin B0 cambie de valor, y esto suceder cada 10mS,

/***************************************************** This program was produced by the CodeWizardAVR V2.03.6 Evaluation Automatic Program Generator Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 03/11/2008 Author : Freeware, for evaluation and non-commercial use only Company : Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Comments: Chip type : ATmega48 Clock frequency : 1,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega48.h> // Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { PORTB.0=~PORTB.0; // Place your code here } // Declare your global variables here void main(void) { // Declare your local variables here // Crystal Oscillator division factor: 8 #pragma optsizeCLKPR=0x80; CLKPR=0x03; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=0 PORTB=0x00; DDRB=0x01; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 15,625 kHz // Mode: CTC top=OCR0A // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x02; TCCR0B=0x03; TCNT0=0x00; OCR0A=0x9C; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

// OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; OCR2A=0x00; OCR2B=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=0x00; EIMSK=0x00; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x02; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // Global enable interrupts #asm("sei") while (1) { // Place your code here }; }

La imagen de la seal generada se muestra en la siguiente fotografa:

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Tabla de conteo mximo del timer (256 Cuentas) Periodo de una cuenta Tiempo que le llevar contar 256 cuentas 1 S (1 MHz) 256 S 8 S (125 KHz) 2.048 mS 64 S (15.625KHz) 16.284 mS 256 S (3906.25 Hz) 65.536 mS 1.024 mS (976.565 Hz) 0.262144 S

4.6 Modo Fast PWM Top=OCR0A (PWM con ajuste de periodo dado por OCR0A) En este modo el periodo de la seal PWM se ajusta con el registro OCR0A, por ejemplo si OCR0A=100 significa que el timer contar desde 0 hasta 100 y despus regresar a 0. Entonces el registro OCR0B se utiliza para ajustar el ancho de pulso del PWM. Programa Timer6. Se desea una seal PWM con un periodo de 100S, con un ancho de pulso del 75%, entonces en este modo si podemos ajustar el periodo del timer, para ello vemos la siguiente tabla y con un preescalamiento de 1 el timer se incrementa cada 1S y el timer puede contar hasta 256, por lo que si queremos 100S se escoge ese preescalamiento y se coloca en OCR0A=100; y el ancho de pulso de 75% corresponde a un 75 que se cargar en el OCR0B. Entonces la seal PWM se mostrar sobre la salida B. Note que en este modo el OCR0A fija el periodo en cuentas del PWM y el OCR0B es para establecer el ancho de pulso del PWM. Tabla de frecuencia y periodos del timer 0 Tiempo que tarda en incrementarse en una Preescalamiento Frecuencia unidad el timer (1/Frecuencia Timer) del timer 1 1 MHz 1 S 8 125KHz 8 S 64 15.625KHz 64 S 256 3906.25 Hz 256 S 1024 976.5625Hz 1.024 mS

Frecuencia Interna 1 MHz 1 MHz 1 MHz 1 MHz 1 MHz

El wizard deber ajustarse de la siguiente manera:

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Note que en la parte de abajo en Compare A se coloc 65h que es un 100d que corresponde al periodo en cuentas, y en Compare B se coloc un 4b que coresponde a un 75d para fijar el ancho de pulso en 75%. El wizard generar el siguiente cdigo y no ser necesario agregar ms cdigo para que el programa genere la seal deseada.
/***************************************************** This program was produced by the CodeWizardAVR V2.03.6 Evaluation Automatic Program Generator Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 03/11/2008 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATmega48 Clock frequency : 1,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega48.h> // Declare your global variables here void main(void) { // Declare your local variables here // Crystal Oscillator division factor: 8 #pragma optsizeProgramacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

CLKPR=0x80; CLKPR=0x03; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=0 State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x20; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 1000,000 kHz // Mode: Fast PWM top=OCR0A // OC0A output: Disconnected // OC0B output: Non-Inverted PWM TCCR0A=0x23; TCCR0B=0x09; TCNT0=0x00; OCR0A=0x64; OCR0B=0x4b; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

OCR2A=0x00; OCR2B=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=0x00; EIMSK=0x00; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x00; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; while (1) { // Place your code here }; }

4.7 Modo Phase Correct PWM top=OCR0A Este modo es idntico al modo Phase Correct PWM top=FFh pero la diferencia radica que el timer no contar hasta FFh sino hasta el valor del OCR0A y cuando se iguala el TCNT0 al valor del OCR0A el timer se reinicializa a 0. Las acciones que pueden generarse en los pines D5 y D6 son las descritas en el modo Phase Correct PWM top=FFh.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

4.8 Programacin del timer 2


El timer 2 es idntico al timer 0 en el tipo de seales que genera, adems de que el contador es de 8 bits, pero con las siguiente diferencias: El contador del timer0 es el TCNT0 El contador del timer2 es el TCNT2 La salida A asociada al TIMER0 se llama OC0A y es el pin D6 La salida A asociada al TIMER2 se llama OC2A y es el pin B3 La salida B asociada al TIMER0 se llama OC0B y es el pin D5 La salida B asociada al TIMER2 se llama OC2B y es el pin D3

El timer0 puede preescalar la frecuencia entre 1,8,64,256 y 1024 por lo que para una frecuencia interna de 1MHz se tienen las siguientes frecuencias del timer0. Frecuencia Interna 1 MHz 1 MHz 1 MHz 1 MHz 1 MHz Tabla de frecuencia y periodos del timer 0 Tiempo que tarda en incrementarse en una Preescalamiento Frecuencia unidad el timer (1/Frecuencia Timer) del timer 1 1 MHz 1 S 8 125KHz 8 S 64 15.625KHz 64 S 256 3906.25 Hz 256 S 1024 976.5625Hz 1.024 mS

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

El timer2 puede preescalar la frecuencia interna entre ms valores y stos son: 1, 8, 32, 64, 128, 256 y 1024. Tabla de frecuencias y periodos del timer 2 Tiempo que tarda en incrementarse en una Frecuencia Preescalamiento Frecuencia unidad el timer (1/Frecuencia Timer) Interna del timer 1 MHz 1 1 MHz 1 S 1 MHz 8 125KHz 8 S 1 MHz 32 31.250KHz 32 S 1 MHz 64 15.625KHz 64 S 1 MHz 128 7.813KHz 128 S 1 MHz 256 3906.25 Hz 256 S 1 MHz 1024 976.5625Hz 1.024 mS Importante. cuando maneje el timer2 deber usar los registros de comparacin asociados a l que son OCR2A y OCR2B que son los registros de comparacin del timer 2. Importante. Los valores de frecuencias y periodos que se muestran en la Tabla del timer 2 son calculados considerando una frecuencia de operacin interna de 1MHz, pero si va usar otro frecuencia de cristal distinta deber calcular esos datos.

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

4.9 Programacin de timer1


El timer1 es de 16 bits (TCNT1) por lo que puede contar desde 0 hasta 65535 (0 hasta FFFFh), as que los registros asociados a l son de 16 bits. Puede preescalarse la frecuencia del timer entre 1,8,64,256 y 1024 por lo que para una frecuencia interna de 1MHz se tienen las siguientes frecuencias de operacin del timer1. Frecuencia Interna 1 MHz 1 MHz 1 MHz 1 MHz 1 MHz Tabla de frecuencia y periodos del timer 1 Tiempo que tarda en incrementarse en una Preescalamiento Frecuencia unidad el timer (1/Frecuencia Timer) del timer 1 1 MHz 1 S 8 125KHz 8 S 64 15.625KHz 64 S 256 3906.25 Hz 256 S 1024 976.5625Hz 1.024 mS

Pero la diferencia del timer0 y timer2 es que el timer1 es de 16 bits por lo que calculamos la siguiente tabla para cuando el timer cuenta hasta FFFFh pulsos: Tabla de conteo mximo del timer2 (65536 Cuentas) Periodo de una cuenta Tiempo que le llevar contar 65536 cuentas 1 S (1 MHz) 65.536mS 8 S (125 KHz) 524.288 mS 64 S (15.625KHz) 4.194304 S 256 S (3906.25 Hz) 16.7772 S 1.024 mS (976.565 Hz) 67.108864 S El timer1 tiene asociada la salida A al pin B3 y la salida B al pin B2

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Los registros de comparacin son OCR1A y OCR1B los que tambin son de 16 bits, el programador les escribe un dato y ese nmero se compara continua y automticamente con el valor del timer1 (TCNT1) y cuando son iguales se puede generar las siguientes acciones sobre esos pines: Ponerse a 1 a 0 o cambiar de estado. 4.9.1 Modo Normal top FFFFh (Modo de conteo desde 0 hasta FFFFh) En este modo el timer va desde 0 hasta FFFF cuando el timer1 llega a FFFF el siguiente conteo es cero (esto se conoce como sobreflujo y se puede programar una interrupcin cada vez que llega al valor mximo). Programa Timer7. Haga un programa que cada segundo cambie de estado el pin B1 donde se conectar un LED, el led se prender y apagar una vez por segundo. Se va a configurar la salida A del timer1 (pin B1) en el modo de toggle o de conmutacin, as que cada vez que ocurra un segundo el pin cambiara de estado. Primero vemos el preescalamiento que permita medir tiempos de 1 segundo y que est lo mas cercano a l, as encontramos que se debe preescalar entre 64 la frecuencia del timer para que opere a 15.625KHz la velocidad de incremento del timer1 y que le llevar 4.194304 Segundos contar desde 0 hasta FFFFh al timer1. Tabla de conteo mximo del timer2 (65536 Cuentas) Periodo de una cuenta Tiempo que le llevar contar 65536 cuentas 1 S (1 MHz) 65.536mS 8 S (125 KHz) 524.288 mS 64 S (15.625KHz) 4.194304 S 256 S (3906.25 Hz) 16.7772 S 1.024 mS (976.565 Hz) 67.108864 S
Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com Autor: David Infante Snchez www.comunidadatmel.com

Cuntas cuentas corresponden a 1 segundo? Se resuelve as cuentas=1 Segundo/64S Cuentas=15625. Entonces ese nmero debemos cargarlo en el OCR1A para que cuando el TCNT1 se haga igual al OCR1A cambie de estado el pin, pero el siguiente segundo ocurrir cuando OCR1A valga 15625+15625; as que debemos generar una interrupcin por comparacin con el registro A para leer el valor del OCR1A sumarle 15625 y genere el siguiente cambio de pin al segundo nmero dos y as sucesivamente. La inicializacin del timer1 se muestra en la siguiente figura, note que en la parte de abajo donde est COMP. A escribimos 3d09h que corresponde 15625d y que eso en tiempo es 1 segundo. Y tambin se dio click en Interrupcin por Compare Match A que significa que se va a generar una interrupcin cuando el timer1 sea igual al registro A.

PENDIENTE DE COMPLETAR EL TIMER1

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

INSTITUTO TECNOLGICO DE MORELIA

TPICOS SELECTOS DE PROGRAMACIN DE MICROCONTROLADORES AVR


POR DAVID INFANTE SNCHEZ

dinfante29@hotmail.com dinfante@itmorelia.edu.mx

Revisin 2.0 Abril del 2008

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

Objetivos
Disear instrumentos virtuales como medidores y controladores de temperatura, presin, nivel, voltaje, corriente, etc. Usando LABVIEW y los microcontroladores de ATMEL. Control y medicin de variables a travs de mdulos de radio frecuencia Diseo de filtros digitales IIR usando MATLAB y su implementacin en microcontroladores ATMEL usando matemtica de punto flotante.

Debido a la complejidad de esta parte es presencial y se incluyen los siguientes temas:

Instrumentacin Virtual
Con el software de LabView se hacen instrumentos virtuales para manipular, alamacenas y desplegar datos en la PC usando una conexin con el puerto serie del microcontrolador. (8 horas) Programas 1. Osciloscopio digital con despliegue en PC 2. Medidor de temperatura y despliegue en instrumentos virtuales 3. Medidor de nivel a travs de sensores de ultrasonido y despliegue en instrumentos virtuales

Telemetra
Control de puertos de entrada/salida del micrcontrolador a travs de mdulos de RF (2 horas) Adquisicin de datos y despliegue de informacin en la pantalla de la PC a travs de instrumentos virtuales usando mdulos de radio frecuencia (2 horas). Programas 1. Control de puertos de E/S a travs de radio frecuencia, manipulados a travs de instrumentos virtuales diseados con LABVIEW 2. Control de la intensidad luminosa de un foco por radio frecuencia y LABVIEW

Procesamiento digital de seales


Diseo de filtros digitales tipo IIR y su implementacin en microcontroladores de ATMEL usando matemtica de punto flotante. El diseo de los filtros se hace a travs del sofware de MATLAB (4 horas)
Autor: David Infante Snchez www.comunidadatmel.com

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Programas 1. Diseo de un filtro digital Butterworth e implementacin en un microcontroladore ATMEL 2. Diseo de un filtro digital Chebyshev e implementacin en un microcontroladore ATMEL Para este curso es necesario contar con el sofware de MATLAB, LABVIEW y CodeVision, y el curso consta de una introduccin a LABVIEW y teora de procesamiento de seales, as como su programacin en MATLAB para el diseo de los filtros. Es necesario haber cubierto los temas y prcticas de los cursos anteriores

Programacin en C de los microcontroladores ATMEL e-mail: dinfante29@hotmail.com

Autor: David Infante Snchez www.comunidadatmel.com

You might also like