50664087 Programacion en C

20
PROGRAMACIÓN EN LENGUAJE C El WinAvr dispone de un compilador compatible con el ANSI C, adicionalmente dispone de librerías específicas para el manejo de los diferentes recursos. Se presenta una plantilla genérica para un programa escrito para el compilador C de WinAVR //***************************************************************************** // // Titulo : // Autor : // Fecha : 2007-03-29 // Version : 1.0 // Target MCU : Atmel AVR series // // //***************************************************************************** // ------------------------------------------------------------------------------------------------------------- //************************* Inclusión de Librerías ******************************* // ------------------------------------------------------------------------------------------------------------- #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <inttypes.h> #include "lcd_lib.h" // ------------------------------------------------------------------------------------------------------------- //*********************** Definiciones de Variables Globales ******************* // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ************************* Definiciones y Macros ***************************** // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ************************ Rutinas de Interrupción **************************** // -------------------------------------------------------------------------------------------------------------

Transcript of 50664087 Programacion en C

Page 1: 50664087 Programacion en C

PROGRAMACIÓN EN LENGUAJE C El WinAvr dispone de un compilador compatible con el ANSI C, adicionalmente dispone de librerías específicas para el manejo de los diferentes recursos. Se presenta una plantilla genérica para un programa escrito para el compilador C de WinAVR //***************************************************************************** // // Titulo : // Autor : // Fecha : 2007-03-29 // Version : 1.0 // Target MCU : Atmel AVR series // // //***************************************************************************** // ------------------------------------------------------------------------------------------------------------- //************************* Inclusión de Librerías ******************************* // ------------------------------------------------------------------------------------------------------------- #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <inttypes.h> #include "lcd_lib.h" // ------------------------------------------------------------------------------------------------------------- //*********************** Definiciones de Variables Globales ******************* // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ************************* Definiciones y Macros ***************************** // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ************************ Rutinas de Interrupción **************************** // -------------------------------------------------------------------------------------------------------------

Page 2: 50664087 Programacion en C

// ------------------------------------------------------------------------------------------------------------- // ************************* Declaración de Funciones ************************** // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // **************************** Cuerpo del Programa **************************** // ------------------------------------------------------------------------------------------------------------- int main( void ) { // ------------------------------------------------------------------------------------------------------------- // ********************** DECLARACIÓN DE VARIABLES ********************** // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ************** CONFIGURACIÓN DE LOS PUERTOS DE E/S ******************* // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ********************* INICIALIZACIÓN DE REGISTROS ********************** // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ****************** HABILITACIÓN DE INTERRUPCIONES ******************** // ------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------------- // ************** INICIALIZACIÓN DE FUNCIONES Y VARIABLES *************** // -------------------------------------------------------------------------------------------------------------

Page 3: 50664087 Programacion en C

// ------------------------------------------------------------------------------------------------------------- // ******************** CICLO PRINCIPAL DE EJECUCIÓN ********************** // ------------------------------------------------------------------------------------------------------------- while (1) { } //Fin while return 0; } // ------------------------------------------------------------------------------------------------------------- //********************* DEFINICIÓN DE FUNCIONES ************************** // ------------------------------------------------------------------------------------------------------------- // __________________________________________________________________________ WinAVR dispone de una serie de librerías que pueden incluirse dentro del programa de la cual se dispone la respectiva documentación, algunas son del estándar C y otras propias del WinAVR. Como ejemplo • <alloca.h>: Allocate space in the stack • <assert.h>: Diagnostics • <ctype.h>: Character Operations • <errno.h>: System Errors • <inttypes.h>: Integer Type conversions • <math.h>: Mathematics • <setjmp.h>: Non-local goto • <stdint.h>: Standard Integer Types • <stdio.h>: Standard IO facilities • <stdlib.h>: General utilities • <string.h>: Strings • <avr/boot.h>: Bootloader Support Utilities • <avr/eeprom.h>: EEPROM handling • <avr/fuse.h>: Fuse Support • <avr/interrupt.h>: Interrupts • <avr/io.h>: AVR device-specific IO definitions

Page 4: 50664087 Programacion en C

• <avr/lock.h>: Lockbit Support • <avr/pgmspace.h>: Program Space Utilities • <avr/power.h>: Power Reduction Management • <avr/sfr_defs.h>: Special function registers • <avr/sleep.h>: Power Management and Sleep Modes • <avr/version.h>: avr-libc version macros • <avr/wdt.h>: Watchdog timer handling

Variables Globales: Las variables comunes, sólo son accesibles desde la función donde se encuentra definida, si se requiere que la variable sea accesible desde cualquier parte del programa, es necesario declararla como global. Para esto simplemente se define antes de la función main(). Ej. Volatile int var_1, var_2; Es aconsejable aunque no obligatorio definir las variables globales como volactiles para indicarle al compilador que no sobreescriba sobre esta posición de memoria.

Definiciones y Macros: Mediante ciertas directivas se puede asignar a algún símbolo definido por el programador una determinada expresión. Ejemplos: #define s1 2 #define larger( x, y) ( (x)>(y) ? (x) : (y))

#define _BV(bit) (1 << (bit)) #define set_bit(value, bit) (value=((value) | _BV(bit)))

Rutinas de Interrupción: Son funciones cuyo cuerpo definen lo que se debe ejecutar en el momento que se presente una determinada interrupción.

Page 5: 50664087 Programacion en C

Ej. ISR(TIMER0_OVF_vect) { PORTA=PORTA ^ 0x02; } No es necesario hacer un salto explícito a esta función, ni ejecutar alguna instrucción de retorno. El nombre de los diferentes vectores de interrupción se definen en la librería <avr/io.h>. /* External Interrupt Request 0 */ INT0_vect /* External Interrupt Request 1 */ INT1_vect /* External Interrupt Request 2 */ INT2_vect /* Timer/Counter0 Overflow */ TIMER0_OVF_vect /* Timer/Counter0 Compare Match */ TIMER0_COMP_vect /* Timer/Counter1 Overflow */ TIMER1_OVF_vect /* Timer/Counter1 Capture Event */ TIMER1_CAPT_vect /* Timer/Counter1 Compare Match A */ TIMER1_COMPA_vect /* Timer/Counter1 Compare Match B */ TIMER1_COMPB_vect /* Timer/Counter2 Overflow */ TIMER2_OVF_vect /* Timer/Counter2 Compare Match */ TIMER2_COMP_vect

Page 6: 50664087 Programacion en C

/* Serial Transfer Complete */ SPI_STC_vect /* USART, Rx Complete */ USART_RXC_vect /* USART Data Register Empty */ USART_UDRE_vect /* USART, Tx Complete */ USART_TXC_vect /* ADC Conversion Complete */ ADC_vect /* EEPROM Ready */ EE_RDY_vect /* Analog Comparator */ ANA_COMP_vect /* 2-wire Serial Interface */ TWI_vect /* Store Program Memory Ready */ SPM_RDY_vect

Declaración de Funciones: En este campo debe colocarse la declaración de las funciones a emplear con el prototipo de la función. Ej. int mi_funcion(int var1, int var2, float var3);

Cuerpo del Programa: El cuerpo del programa siempre empieza con la función main() y desde donde el programa empieza su ejecución.

Page 7: 50664087 Programacion en C

Declaración de Variables: Las variables que se definan aquí tienen un ámbito local, no son accesibles desde las funciones.

Configuración de los puertos: // configura PORTA como salida PORTA=0; DDRA = 0xFF; // configura PORTB como salida PORTB=0; DDRB = 0xFF; // configura PORTC como entrada PORTC=0; DDRC = 0x00; // configura PORTD as entrada PORTD=0; DDRD = 0x00;

Inicialización de Registros: Se establecen los valores de los registros de propósito específico de acuerdo con las configuraciones de los diferentes recursos. TCNT1=0xA2B7; En el archivo cabecera de cada dispositivo se tienen asignados los nombres de los registros. #define TCNT1 _SFR_IO16(0x2C) #define TCNT1L _SFR_IO8(0x2C) #define TCNT1H _SFR_IO8(0x2D)

Habilitación de Interrupciones: Habilitación de los diferentes bits de interrupción

Page 8: 50664087 Programacion en C

Ej. TIMSK=(1<<TOIE0); sei(); //Habilitación del bit de interrupción global.

Inicialización de funciones y variables Se debe establecer el estado inicial de las distintas variables y ejecutar las funciones de inicialización requeridas. Ej. LCDinit();

INTRODUCCIÓN AL LENGUAJE C PARA EL COMPILADOR WINAVR

Tipos de datos básicos: char Define variables de 8 bits, empleado especialmente para representación de caracteres. Enteros: El Ansi C implementa los tipos int y long int, para datos enteros de 16 y 32 bits. Int (-32768 a 32767) Unsigned int (0 a 65535) La librería #include <inttypes.h> implementa otros tipos adicionales: Int8_t uint8_t Int16_t uint16_t Int32_t uint32_t Int64_t uint64_t float y double son punto flotante de 32 bits.

Page 9: 50664087 Programacion en C

Operadores

Page 10: 50664087 Programacion en C

Operador condicional expresson1 ? expression2 : expression3 Si expresión1 es verdadera entonces se usa la expresion2, de lo contrario la expresión3. (x)>(y) ? (x) : (y)

Page 11: 50664087 Programacion en C

Ejercicios 1. Evaluar las siguientes expresiones: (a) 5 / 2 + 20 % 6 (b) 4 * 6 / 2 - 15 / 2 (c) 5 * 15 / 2 / (4 - 2) (d) 8 = = 16 || 7 != 4 && 4 < 1 (e) (4 * 3 < 6 || 3 > 5 - 2) && 3 + 2 < 12 2. Escriba la línea de código en C que corresponda con las siguientes sentencias:

(a) Si el residuo de A dividido B es diferente de 0 y A es mayor o igual que B o B es menor de 100 (b) Y= (AB+(C+D)’)((AB)’+C’)

Estructuras de Control

If - Else if (expression1)

{

-------;

..-------;

} else if (expression2)

{

--------;

--------;

} else if (expression3)

{

---------;

---------;

}else

{

---------;

---------;

}

Page 12: 50664087 Programacion en C

Ejemplo: If (opcion= = 1) { Y=A+B; }else if (opcion= =2) { Y=A-B; } else if (opcion= =3) { Y= A*B; }else { Y=A/B; } Cuando se tiene una sóla sentecia entre un para de llaves, no es obligación colocar éstas. If (opcion= = 1) Y=A+B; else if (opcion= =2) Y=A-B; else if (opcion= =3) Y= A*B; else Y=A/B;

Switch

switch (expression) { case constant expression1: -----------;

-----------;

Break;

case constant expression2: -----------;

-----------;

Break;

default constant expression2: -----------;

-----------;

Break;

}

Page 13: 50664087 Programacion en C

Ejemplo: switch (opcion) { case 1: Y=A+B;

Break;

case 2: Y=A-B;

Break;

case 3: Y=A*B;

Break;

default 3: Y=A/B;

Break;

}

While while(expression)

{

---------;

---------;

}

do - While

do

{

------------;

..------------;

} while(expression);

Ejemplo; while ( i < 128) { PORTB = 2*i; i++; }

Page 14: 50664087 Programacion en C

Cual sería el resultado obtenido en cada grupo de instrucciones: (a) (b) x=100; x=100; y=0; y=0; while ( x < 50) do { { y= 2*x; y= 2*x; x++; x++; } } while ( x < 50); y= ¿? y= ¿?

For for(expresson1; expression2; expresson3)

{

--------------;

--------------;

} for(i=0;i<=10;i++)

{

Var=2*i-1;

}

Break y Continue Estas instrucciones permiten interrumpir una instrucción cíclica. En el caso de la instrucción break, ésta hace que el bucle más interno que la contenga finalice inmediatamente sin tener en cuenta la condición. La instrucción continue por su parte, finaliza la iteración actual sin salir del ciclo. Ejemplo:

Page 15: 50664087 Programacion en C

for (i=0; i<100;i++) { if(i==10) continue; sprintf(s_num,"%d\r",i); // Pasa al string s_num el valor numérico LCDclr(); LCDGotoXY(0,0); lcd_puts(s_num,16); _delay_ms(500); } En este caso no se visualiza el valor 10 sino que es saltado. for (i=0; i<100;i++) { if(i==10) break; sprintf(s_num,"%d\r",i); // Pasa al string s_num el valor numérico LCDclr(); LCDGotoXY(0,0); lcd_puts(s_num,16); _delay_ms(500); } En este caso sólo se visualizan los números del 0 al 9 y termina el ciclo.

PUERTOS DE E/S Cada Puerto tiene asociado tres registros DDRx Para configurar la dirección del puerto. 1 configura como salida 0 Configura como entrada PORTx Se emplea para enviar información por el puerto. En caso que un determinado pin se configure como entrada, y por medio del registro PORTx se coloque en 1, se habilita la correspondiente resistencia de pull-up.

Page 16: 50664087 Programacion en C

Se recomienda que los pines que no se utilicen se les habiliten esta resistencia. PINx Lee el estado del puerto x Ej. DDRB = 0x1F;

DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4);

PORTB = 0x04;

PORTB = PORTB | 0x04;

PORTB |= (1<<PB2); Equivalente a la instrucción anterior. PORTB |= (1<<PB4) | (1<<PB5); Pone los pines 4 y 5 en alto sin alterar los demás.

PORTB &= ~( (1<<PB4) | (1<<PB5) ); Pone los pines 4 y 5 en 0 sin alterar los demás. Formas de examinar un pin. if ( PINC & (1<<PINC1) ) { Será verdadero si el pin 1 está en alto.

/* action */

}

if ( !(PINB & (1<<PINB2)) ) { Será verdadero si el pin 1 está en bajo.

/* action */

} Para simplificar la escritura pueden definirse ciertas macros #define _BV( bit ) (1 << (bit)) #define E0 ((variable) & _BV(0)) Test sobre el bit 0 #define set_E0 (variable | = _BV(0)) #define clr_E0 (variable &= ~_BV(0))

Page 17: 50664087 Programacion en C

INICIALIZACIÓN DE REGISTROS PARA LOS DIFERENTES RECURSOS

Timer 0 como temporizador TCCR0=(1<<CS02)|(1<<CS00); //Escala 1024 TCNT0=T0_INI; //Inicializa el temporizador

Timer 0 como contador TCCR0=(1<<CS02)|(1<<CS01)|(1<<CS00); //Contador por flanco de subida

Timer 0 como comparador OCR0=128; TCCR0=(1<<WGM01)|(1<<COM00)|(1<<CS01);

//Salida cambia de estado

Timer 0 como PWM OCR0=128; TCCR0=(1<<WGM00)|(1<<COM01)|(1<<CS01);

Timer 1 como temporizador TCCR1B=(1<<CS11)|(1<<CS10); //Escala 64 TCNT1=T1_INI; //Inicializa el temporizador

Timer 1 como contador TCCR1B=(1<<CS12)|(1<<CS11)|(1<<CS10); //Contador por flanco de subida

Timer 1 como comparador OCR1A=256; TCCR1A=(1<<COM1A0); //Salida cambia de estado TCCR1B=(1<<WGM12)|(1<<CS11); //Escala 8 cambio cada 256us (OCR1A)

Page 18: 50664087 Programacion en C

Timer 1 como PWM fase correcta de 10 bits OCR1A=256; TCCR1A=(1<<WGM11)|(1<<WGM10)|(1<<COM1A1)|(1<<COM1B1); TCCR1B=(1<<CS11); //Escala 8 periodo 2048 ciclos con 8M = 2048us

Timer 2 como temporizador TCCR2=(1<<CS22)|(1<<CS21)|(1<<CS20); //Escala 1024 TCNT2=T2_INI; //Inicializa el temporizador

Timer 2 como comparador OCR2=128; TCCR2=(1<<WGM21)|(1<<COM20)|(1<<CS21); //Salida cambia de estado

Timer 2 como PWM OCR2=128; TCCR2=(1<<WGM20)|(1<<COM21)|(1<<CS21); //Salida cambia de estado

Timer 2 como contador con oscilador externo TCCR2=(1<<CS22)|(1<<CS20); ASSR=(1<<AS2);

Page 19: 50664087 Programacion en C

EJEMPLO DE INICIALIZACIÓN DE INTERRUPCIONES

Desbordamiento del TMR0 ISR(TIMER0_OVF_vect) { TCNT0=T0_INI; frac++; if(frac>=10) { segundos++; frac=0; PORTA=PORTA ^(1<<2); } } TIMSK= (1<<TOIE0); //Habilita interrupción por desbordamiento TMR0

Desbordamiento del TMR1 ISR(TIMER1_OVF_vect) { TCNT1=T1_INI; frac++; if(frac>=10) { segundos++; frac=0; PORTA=PORTA ^(1<<2); } } TIMSK= (1<<TOIE1); //Habilita interrupción por desbordamiento TMR1

Page 20: 50664087 Programacion en C

Desbordamiento del TMR2 ISR(TIMER2_OVF_vect) { TCNT2=T2_INI;

frac++; if(frac>=10) { segundos++; frac=0; PORTA=PORTA ^(1<<2); } } TIMSK= (1<<TOIE2); //Habilita interrupción por desbordamiento TMR2