Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
PROGRAMACIN EN C DE LOS
MICROCONTROLADORES ATMEL
He sido:
Asesor en ms de 70 temas de titulacin de licenciatura y 1 de Maestra.
Sinodal en ms de 70 exmenes de titulacin de licenciatura y 6 de maestra.
17 Artculos publicados en congresos y simposios nacionales de electrnica y
computacin.
18 Ponencias en congresos y simposios nacionales de electrnica.
Participacin como asesor con proyectos en 19 eventos de creatividad en sus
distintas fases.
Asistencia en calidad de participante en 15 cursos de robtica,
instrumentacin, redes de PLCs, Paneles de Operador, termografa y
microcontroladores COP, HC08, MSP430, AVR.
Imparticin de 12 cursos de microcontroladores PIC, HC08, AVR, DSPs de
Texas Instruments, procesamiento de seales y de PLCs en eventos nacionales
7 veces jurado en eventos acadmicos de electrnica
Como estudiante particip en los concursos de Ciencias Bsicas durante 3
aos en sus distintas etapas.
Obtencin de una de las 10 becas nacionales para telecomunicaciones en
CINVESTAV Guadalajara
Experiencia profesional
Motivacin
El motivo de este curso es para dar a conocer las nuevas tecnologas en microcontroladores,
ya que es lamentable que en las universidades e institutos de educacin superior de Mxico
y en Latinoamrica en general, se estn haciendo proyectos y programas demasiados
sencillos en las materias de microcontroladores y peor an que estn usando los
microcontroladores PIC, ya que universidades europeas y de EUA no los usen desde hace
aos por su pobre desempeo, adems de que son microcontroladores que no tiene ninguna
aplicacin industrial o comercial, sino slo para efectos didcticos.
Desde que cursaba la carrera de ingeniera electrnica a la fecha he usado los siguientes
microprocesadores, microcontroladores y DSPs:
Los microcontroladores PIC son los peores microcontroladores que existen, son muy lentos
que trabajan a baja velocidad, tiene un set de instrucciones muy pequeo que obliga a
programas muy extensos y lentos, tiene nicamente un work register cuando un procesador
RISC debe tener al menos 16 registros, de todos los microcontroladores que existen en el
mercado son los peores en el desempeo, algunas empresas comenzaron a hacer sus
equipos con estos procesadores y despus al detectrseles fallas como bloqueos o
reinicializacin por ruido sacaron del mercado sus productos. En pases desarrollados no se
usan ya que no tienen aplicacin industrial o comercial, nicamente en escuelas de pases
de latinoamrica. Estos procesadores nicamente los us por un ao y los dej de usar hace
una dcada por ser procesadores obsoletos y de mal desempeo.
Los Microcontroladores AVR de Atmel tiene 4 veces ms instrucciones que los PICs, tiene
32 registros de trabajo, el pic slo 1, el ADC es ms potente, el TIMER es mucho ms
complejo que el del PIC, y son ms econmicos. Los AVR de Atmel se usan en telfonos
celulares, en receptores satelitales, en robtica, etc. Son microcontroladores muy rpidos y
de alto desempeo y son de bajo costo, existen muchos proyectos, tutoriales y herramientas
gratuitas en la red.
A manera de conclusin dira que en orden de desempeo y calidad colocara los
procesadores as: AVR de Atmel, MSP de Texas Instruments, los 08 de Motorola el 8051
de Intel, COP de Nacional Semiconductor. Un procesador AVR o MSP puede tener un
desempeo de entre 10 y 50 veces al de un PIC con el mismo cristal externo, o en otras
palabras un PIC es entre 10 y 50 veces ms lento que un AVR o que un MSP.
CAPTULO I. PROGRAMACIN EN C
1.1 Tipos de Variables
En esta parte nicamente se ver como se manejan las instrucciones de C, quizs al
terminar este captulo algunas instrucciones no las entienda del todo bien, sin embargo
cuando programemos el microcontrolador usaremos estas instrucciones y las ir
comprendiendo de una mejor manera.
En un programa en C puede colocar comentarios usando //
unsigned char x; // x es una variable
O puede utilizar /*
Tamao en bits
1
8
8
8
16
16
16
16
32
32
32
32
Rango
0o1
-128 a 127
0 a 255
-128 a 127
-32768 a 32767
-32768 a 32767
0 a 65535
-32768 a 32767
-2147483648 a 2147483647
0 a 4294967295
-2147483648 a 2147483647
1.75 e -38 a 3.402 e 38
Double
32
Formato
Nmero
0x nmero hexadecimal
0b nmero binario
0 nmero octal
Ejemplos:
x=20;
x=0x14;
x=0b00010100;
x=024;
// x es 20 decimal
//x es 14 hexadecimal que convertido a decimal es 20 decimal
//x se manejado en binario que es equivalente a 20 decimal
//x se maneja en octal que es 20 decimal
Las variables deben ser ubicadas en RAM. Solamente se hace declarndolas como unsigned
o signed luego el tipo y finalmente el nombre de las variables;
unsigned long variable3;
signed char x,y,z;
De la manera anterior las variables se guardarn en RAM
Las constantes deben ser guardadas en FLASH o memoria de programa, ya que stas no
van a ser modificadas, para ello se inicia colocando la palabra const o flash ejemplo:
const int k1=60000;
Que es equivalente a:
flash int k1=60000;
Con lo anterior la constante K1 es inicializada a 60000 y se guarda en flash.
Se puede guardar un carcter en flash para ello ponemos el carcter entre comillas simples
()
const char x=a
1.4 Arreglos
Un arreglo es un conjunto de datos que pueden ser accesado a travs de un ndice. Su
declaracin se hace as:
flash o const nombre del arreglo [nmero de elementos]={elemento1, elemento2,..
elemento n }
Ejemplo
flash char arreglo1 [3]={0x0a,0x38,0x23};
Es equivalente a la siguiente declaracin:
const char arreglo1 [3]={0x0a,0x38,0x23};
flash y const son lo mismo ya que guardan los datos en flash, pero por compatibilidad con
el lenguaje C usar dentro de este manual la palabra const.
Se guardan de manera individual esos bits en los registros R2 al R14 del procesador del
AVR. Recuerde que el microcontrolador AVR tiene 32 registros desde R0 hasta R31.
Operacin
Suma
Resta
Multiplicacin
Divisin
Divisin Mdulo, y el resultado es el
residuo
Var1=Var2/12;
Var1=Var2%12;
Descripcin
And Bit a Bit
OR bit a Bit
Or exclusivo Bit a Bit
Corrimiento a la Izquierda
Corrimiento a la derecha
Complemento
a
unos
(inversin de bits)
Ejemplos:
Var3=Var1&Var2;
Var3=Var1<<(2);
Var3=Var1<<(Var2);
Var3=~Var1;
Descripcin
Mayor que
Mayor o igual que
Menor que
Menor Igual que
Igual que
Distinto de
Y tambin si
O si
Ejemplos
if ((Var2==1)||(Var2>10))
{
Var1--;
}
Var1++;
If (((Var2>12)&&(Var3>=-125)) ||(Var4!=0)) //Var1 se multiplica por -1 si se cumple la
Var1=-Var1;
//Parte de (Var2 y Var3) o (Var4) o ambas
La estructura if else es: si se cumple el if se hace lo que est abajo del if y sino se cumple se
hace lo que est debajo del else
if (Var1==10)
{
Var1=0;
Var2=20;
x=14;
}
else
{
Var1=++;
x=20;
}
Cuando se tiene una variable que dentro del programa va, digamos, desde 0 hasta 100
decimal, podemos declararla como unsigned char var1, pero si ponemos unsigned int var1,
tambin funcionar el programa, pero en el ltimo caso estamos apartando dos bytes (int)
cuando solo ocupamos uno slo, por lo que el programa quedar mas grande y ms lento
porque el microcontrolador deber manipular dos bytes en lugar de uno slo. Es importante
que vea cul es el rango de la variable y aparte el tamao adecuado.
Cuando una variable que ocupa un tamao grande le apartamos uno ms pequeo se puede
crear condiciones que no se cumplen, vea el siguiente ejemplo:
Note el siguiente ejemplo:
signed char var1; // var1 es signada con lo que rango va de -128 a 127
var1++;
If (var1==200)
var2=0;
La condicin del if nunca se cumplir porque var1 es tipo char unsigned, esto es que su
rango es de -128 a 127 decimal y nunca llega a ser mayor a 127.
Si se declara como tipo unsigned char o tipo int si habr un punto en el que la condicin es
vlida.
Este programa realiza por lo menos un incremento del portb, sin importar la condicin, si la
condicin del while se cumple continua en el ciclo incrementando el portb, hasta que no sea
vlida la condicin en el while.
for (i=0;i<=10000,i++)
Programacin en C de los microcontroladores ATMEL
{
var1++;
if (var2==0) //Si var2=0 se rompe ciclo, quedando el i en donde se haya cumplido el var2
break;
}
var3=i;
//Si var2 nunca es verdadera en el ciclo, var3=10000
//Si Var2 se hizo verdadera en i=25 se rompe ciclo y var3=25
b6
0
0
0
b5
0
0
0
b4
0
0
0
b3
0
1
1
b2
1
0
1
b1
1
0
1
b0
1
0
1
Variable
~0x01
Resultado
De la AND
b7
1
1
1
b6
1
1
1
b5
0
1
0
b4
0
1
0
b3
1
1
1
b2
0
1
0
b1
1
1
1
b0
1
0
0
Vemos en el ejemplo anterior que apaga el b0 de la variable y los dems bits no los
modifica.
Con lo anterior estamos poniendo a 1 el pin 6 del puerto sin modificar los otros pines, y
esta manera de manejar bits de manera individual lo podemos usar con los primeros 32
registros, cualquier registro mapeado arriba de la direccin 0x1F se hace con las tcnicas
mostradas en los subtemas 1.12 y 1.12.1.
La instruccin if (pina.0==0); Prueba que el pin0 del porta est en 0 (si es que lo
configuramos como entrada).
La parte anterior slo es la definicin de las funciones que utilizar el programa. El llamado
de las funciones dentro del programa se hace as:
ejemplofuncion1 ();
ejemplofuncion2 (variable1,variable2);
En el llamado de la funcin1 no se coloc nada entre los parntesis porque la funcin
dentro de la definicin le indicamos que no se le iba a enviar ningn parmetro.
En el llamado de la funcin 2 le colocamos entre parntesis dos variables que llamamos
variable1 y 2, que previamente debimos definir. Estas dos variables las recibir la funcin
para que realice operaciones entre ellas.
variablex=ejemplofuncion3 ();
En el llamado de esta funcin colocamos variablex=funcin porque en la definicin del
prototipo le indicamos que iba a retornar la funcin una variable tipo int, entre los
parntesis no se le coloca nada porque se indic que no iba a enviar ningn parmetro.
En la funcin 4 se retorna un valor tipo char y se enva un parmetro tipo int, y su llamado
se hara as:
variabley=elemplofuncion4(variable1);
Hasta este punto se ha visto cmo se declaran las funciones y cmo se llaman, falta
nicamente cmo se estructura la funcin.
En el caso de la primer funcin:
void ejemplofuncion1(void)
{
//Cdigo de usuario
}
La funcin lleva void al inicio y entre parntesis porque esa funcin no recibe parmetros
ni retorna ningn parmetro o valor.
La segunda funcin debera colocarse as:
void ejemplofuncion2(char a, char b)
{
//Cdigo de usuario
}
Aqu lleva void al inicio indicando que no retorna parmetro y entre parntesis se coloca a
y b que indica que son los parmetros que se reciben, cuando se hizo el llamado se hizo as:
ejemplofuncion2 (variable1,variable2); entonces la funcin enva dos parmetros variable1
Programacin en C de los microcontroladores ATMEL
Llamado de la funcin
ejemplofuncion1 ();
ejemplofuncion2 (variable1,variable2);
variablex=ejemplofuncion3 ();
variabley=elemplofuncion4(variable1);
Estructura de la funcin
void ejemplofuncion1(void)
{
//Cdigo de usuario
}
void ejemplofuncion2(char a, char b)
{
//Cdigo de usuario
}
int ejemplofuncion3(void)
{
//Cdigo de usuario
return variable
}
char ejemplofuncion4(int a)
{
//Cdigo de usuario
return variable
}
En los ejemplos que coloqu enve como parmetros variables, pero tambin pueden
ser constantes. ejemplofuncion2(char a, 200); En este ejemplo se enva el valor de
la variable a y se enva la constante 200.
El retorno del valor de la funcin que puse como ejemplo fue el retorno de una
variable, pero tambin puede retornarse una constante como return 100;
microcontroladores como los PICs, los HC08 de motorola, etc. la velocidad interna es el del
cristal dividido entre 4. As que de entrada tenemos que el ATMEL es 4 veces ms rpido
que cualquier otro microcontrolador trabajando con el mismo cristal.
Chip type
: ATmega48
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=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)
{
PORTD=PINB;
//Se lee el valor del Puerto A y se escribe en PORTB
//El Puerto B es de entrada por lo que se accesa usando el registro PINB
//El puerto D es de salida por lo que se accesa usando el registro PORTD
// Place your code here
};
}
Company :
Comments:
Chip type
: ATmega48
Clock frequency : 1,000000 MHz
Memory model
: Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
#include <delay.h> //Esta libreria hay que colocarla para poder utilizar las funciones de retardo
0 1 1 0
1 1 1
0x6f
Para este programa deberemos configurar todo el Puerto B como salida, y los pines C0, C1,
C2 y C3 como entradas con sus resistencias de pull-up, ya que cuando no se cierre el
interruptor quedar a 1 lgico el pin por la resistencia de pull-up interna, y cuando se cierre
el interruptor leer 0 el pin.
En los cursos que he dado normalmente los participantes dicen que una forma de hacer el
programa es con if para probar todas las combinaciones y quizs es la forma que se le ha
ocurrido para hacerlo. Es decir algo de esta forma:
if (PINC==0)
PORTB=0x3f;
if (PINC==0)
PORTB=0x06;
Etc...
if (PINC==9)
PORTB=0x6f;
Chip type
: ATmega48
Clock frequency : 1,000000 MHz
Memory model
: Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
unsigned char variable;
const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f};
// 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=P State2=P State1=P State0=P
PORTC=0x0F;
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: 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;
// 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)
{
variable=PINC&0x0f;
if (variable<10)
PORTB=tabla7segmentos[variable];
if (variable>=10)
PORTB=0x3f;
// Place your code here
};
Chip type
: ATmega48
Clock frequency : 1,000000 MHz
Memory model
: Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
#define boton PINC.0
const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f};
unsigned char var1;
// Declare your global variables here
void main(void)
{
// Declare your local variables here
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=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)
{
if (boton==0)
var1++;
if (var1==10)
var1=0;
PORTB=tabla7segmentos [var1];
// Place your code here
};
}
Project :
Version :
Date : 14/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 SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Declare your global variables here
#define boton PINC.0
bit botonp;
bit botona;
unsigned char var;
const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f};
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=P
PORTC=0x01;
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: 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
PORTB=tabla7segmentos [var];
botonp=botona;
};
}
Chip type
: ATmega48
Clock frequency : 1,000000 MHz
Memory model
: Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
#include <delay.h>
// Declare your global variables here
#define boton PINC.0
bit botonp;
bit botona;
unsigned char var;
const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f};
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=P
PORTC=0x01;
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: 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;
// 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;
if ((botonp==0)&&(botona==1))
//hubo cambio de flanco de 0 a 1
delay_ms(40); //Se coloca retardo de 40mS para eliminar rebotes
PORTB=tabla7segmentos [var];
botonp=botona;
};
}
retardo de 40mS para que se quede ah ciclado el programa y cuando salga de ah, ya los
rebotes no existirn porque ya pasaron 40 mS.
Teclado Matricial
Si deseara manejar digamos 16 botones y lo hiciera poniendo un botn en cada pin gastara
16 pines del microcontrolador, en vez de esto se puede hacer un teclado matricial, el cual
ahorra pines. Por ejemplo una matriz de 4*4 puede manejar 16 teclas, una matriz de 5*5
puede manejar 25 teclas. En el primer caso se ocuparan 4 pines de salida y 4 de entrada, en
el segundo se ocupan 5 pines de salida y 5 de entrada. Aqu vemos el ahorro, para 16 teclas
se ocupan 8 pines en lugar de 16 pines si se hiciera el teclado conectando cada pin a un
botn, y el ahorro es mayor cuando se ocupan 25 teclas, ya que se ocupan 10 pines en total
en lugar de 25 pines si se conecta cada botn con cada pin.
Diagrama de un teclado matricial
el pin, que recordando cuando un pin queda flotado comienza a oscilar leyendo 0 y 1 de
manera aleatoria debido al ruido.
Las resistencias de 100 ohms a la salida de los pines que son los que envan el cdigo son
para proteger contra corto circuitos, por ejemplo si se enviara en la primera columna un 0 y
en la segunda un 1 y se presionar el botn 1 y 4 habra un corto ya que en una lnea hay 5
volts y en el otro 0, as que al tener la resistencia de 100 Ohms la corriente se ve limitada y
no sucede nada al presionar dos teclas al mismo tiempo.
Como son botones los que estn conmutando a tierra hay que quitarle los rebotes, tal y
como lo hicimos en el programa 6. Aunque en este programa que se har no se quitarn los
rebotes.
Este ejemplo de 3*3 se puede usar como base para disear cualquier teclado matricial 5*5,
6*6, etc.
Programa 7. Diseo de un teclado matricial de 3*3, con despliegue a display a 7
segmentos. Los pines C0, C1 y C2 sern los pines de salida por donde se enviarn los
cdigos de saceneo, los pines C3, C4 y C5 sern los pines de entrada donde se leern
los botones presionados.
Configuracin: C0, C1 y C2 de salida, C3, C4 y C5 de entrada con resistencia de pull-up
interna activada. B0 a B7 de salida que es donde se conectar el display.
Project :
Version :
Date : 14/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 SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
/*****************************************************
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 : 14/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 SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
#include <delay.h>
#define boton PINC.0
#define boton_guarda PINC.1
bit botonp;
bit botona;
unsigned char var; //Ahora la variable se guarda en eeprom
const char tabla7segmentos [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f};
eeprom char datoaguardar;
void checa_boton (void); // Aqu se declaran todas las funciones que se van usar
// 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;
// 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;
if (datoaguardar>10)
datoaguardar=0;
var=datoaguardar;
while (1)
{
checa_boton();
PORTB=tabla7segmentos [var];
if (boton_guarda==0) //Si se presiona el botn de guardar
datoaguardar=var; //se grabara la eeprom con el valor de var
// Place your code here
};
}
void checa_boton (void)
{
if (boton==0)
botona=0;
else
botona=1;
if ((botonp==1)&&(botona==0))
//hubo cambio de flanco de 1 a 0
{
var++;
//Se incrementa la variable
if (var>=10)
var=0;
delay_ms(40); //Se coloca retardo de 40mS para eliminar rebotes
}
if ((botonp==0)&&(botona==1))
//hubo cambio de flanco de 0 a 1
delay_ms(40); //Se coloca retardo de 40mS para eliminar rebotes
botonp=botona;
}
datoaguardar=0;
La razn de ello es que si el datoaguardar que es una variable eeprom tiene un valor inicial
mayor a 10 la hacemos 0, y esto sucedera una sola vez, ya que cuando se guarde un dato el
dato estar entre 0 y 9. Pero un microcontrolador nuevo tiene en la memoria eeprom puros
0xff en todas las localidades, entonces la primera vez har que ese dato de 0xff se haga 0.
Importante. Si dentro de un programa utiliza una variable eeprom como una variable RAM
pude suceder que dae esa localidad de memoria eeprom, ya que una eeprom tiene una vida
til de 100,000 ciclos de escritura y lectura, pero si usa esa variable eeprom como una
variable RAM puede suceder que en custin de segundos sucedan esos 100,000 ciclos de
escritura y lectura porque un programa en el microcontrolador ejecuta el cdigo miles de
veces en un segundo, entonces al reescribir esa variable en el programa miles de veces en
un segundo se va a cabar la vida til de la localidad de memoria. En el programa vemos que
la eeprom slo se escribe cuando se presiona un botn.
conversin=(Vin*1024)/Vref .....................................................................................ec(2.1)
Donde Vin es el voltaje que se aplica, vref es el voltaje de referencia y conversin es el
valor digital.
Por ejemplo si Vref=5 y el vin que va a medir es de 2.5 dar como salida 512 segn la
ecuacin 2.1; si ahora el vin es de 1 volt la conversin que dar ser de 204.
En el caso de que se seleccione una conversin de 8 bits, la frmula a utilizar es:
conversin=(Vin*256)/Vref ......................................................................................ec(2.2)
Sustituyendo en la ec 2.2 los valores de vin=2.5 el resultado de la conversin es 128, si el
vin=1el resultado de la conversin ser 51
cuenta que si los va alimentar por separado el voltaje del perifrico del ADC no debe ser
mayor al del microcontrolador, por ejemplo si el microcontrolador lo va alimentar con dos
pilas y el voltaje es de 3 Volts, el ADC debe ser alimentado con 3 volts como mximo
tambin.
El vref que se encuentra en las ecuaciones 2.1 y 2.2 puede ser de tres tipos:
1. Vref=Vcc del microcontrolador, en este caso Aref no se conecta (pin 21)
2. Vref=Aref (pin 21). En este caso se tiene una referencia externa y puede ser
cualquier voltaje, siempre y cuando no sea superior al Vcc del microcontrolador.
3. Vref=1.1 Volts interno
Todos los casos anteriores se configuran con el codevision con clicks.
En las ecuaciones 2.1 y 2.2 se tiene un trmino llamado Vin que es el voltaje de entrada, es
decir, el voltaje que ser convertido a una combinacin digital, segn su proporcin con
Vref. Este Vin se aplica en los canales del ADC que se numeran desde ADC0 hasta ADC5
(pines del 23 al 28), entonces tenemos que esos pines tienen varias funciones ya sean como
pines de entrada o salida, o como entradas del ADC. Entonces si el pin se configura como
entrada del ADC ya no puede funcionar como entrada/salida digital, esto es que las
funciones son excluyentes.
configurado el pin como salida, ya que de ser as se podra daar el pin. Por ejemplo si va
utilizar el canal 0 del adc que es el pin A0 deber configurar ese pin como entrada.
Importante El Avcc no puede ser mayor al Vcc, por eso conctelos juntos
Importante El Aref no puede ser mayor al Vcc del microcontrolador.
Importante No aplique Vin mayores a Aref o a Vcc para evitar daos en el pin del ADC.
Programa 9. Haga una conversin en 8 bits sobre el canal 0 del ADC y muestre el resultado
en leds que se conectarn en el Puerto B. Configure como Vrfe el Vcc del microcontrolador.
Tabla 2.1 Canal y pin del ADC
Canal
Pin
0 ADC0
23 C0
1 ADC1
24 C1
2 ADC2
25 C2
3 ADC3
26 C3
4 ADC4
27 C4
5 ADC5
28 C5
Con el codewizard se hace la configuracin del ADC a travs de simples clicks, lo nico
que deberemos hacer en el programa es leer el valor de la conversin del canal que estemos
usando a travs de la siguiente funcin:
variable=read_adc (nmero_de_canal);
Por ejemplo si desear utilizar el canal 3, que es el pin 26 deber colocar
variable=read_adc(3);
Recuerde tambin que el ADC puede entregar la conversin en 8 o 10 bits, si selecciona
conversin en 8 bits, entonces la variable deber definirse como unsigned char variable; es
decir tipo char de 8 bits, pero si se selecciona una conversin en 10 bits deber declarar la
variable como unsigned int variable, ya que el valor de la conversin ocupa 10 bits.
El nombre que le di a la variable donde se guardar el resultado fue variable, pero puede
darle cualquier nombre.
Importante. La funcin read_adc() slo puede utilizarse si dentro del codevision se habilit
el ADC, ya que si lo usa en cualquiera de los otros programas que se han realizado y que no
han unicializado el ADC marcar error.
Programa 7. Inicialice el ADC del microcontrolador, considerando que el Vref es el Vcc,
que se va utilizar el canal 1 (Pin A1 donde deber inicializar ese pin como entrada), y que
el microcontrolador est alimentado a 5 volts, por lo que el Vrfe=5 Volts. Se utilizar el
ADC con 8 bits de resolucin y el voltaje medido se desplegar en dos displays.
Vea el video_p9 donde se muestra la forma de inicializar el ADC.
/*****************************************************
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 : 15/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 SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
#include <delay.h>
unsigned char x;
#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;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
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=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;
// 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
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x81;
while (1)
{
x=read_adc(0); //Se hace la conversin sobre el canal 0 del ADC
PORTB=x;
//Se despliega en el puerto B el valor digital
// Place your code here
};
}
El programa 9 hace una conversin sobre el canal 0, pero el resultado que da, no es en
voltaje sino en un cdigo binario. Si Vin=0 volts la conversin dio 0b0000,0000; si vin=2.5
volts la conversin da 0b1000,0000 (128 decimal); si es 5 Volts=0b1111,1111 (255
decimal). Es decir nos convierte a una proporcin binaria que luego debemos interpretar,
pero ese resultado lo podemos convertir a voltaje a travs de una regla de 3.
Si Vin=5 da como resultado 0xff, es decir 255, Pero deseamos que muestre un cdigo
nuevo que sea 50 (que sera 5.0 Volts). Entonces se resuleve as:
x*50/255 da como resultado un char, ya que no sobrepasa a 255, pero lo obliga a que en las
operaciones intermedias (sobre todo en la multiplicacin) se guarde el resultado en algn
lugar ya que ocupa ms de 8 bits. El casting se hace codigonuevo=(char)x*50/255
while (1)
{
var=read_adc(2); //Se leer el valor del Canal 1 pin A1
ajusta=50*255/var;
decenas=ajusta/10;
unidades=ajusta%10;
despliega();
// Place your code here
};
}
void despliega(void)
{
PORTB=tabla7segmentos [unidades];
PINA.1=1;
delay_ms(4);
PINA.1=0;
PORTB=tabla7segmentos[decenas];
PINA.0=1;
delay_ms(4);
PINA.0=0;
}
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
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 sofware y las externas o de hardware, por
ejemplo la de reset es una externa ya que est asociada a un pin. Las de sofware son
generadas por alguna condicin en los perifricos, por ejemplo podemos habilitar una
Programacin en C de los microcontroladores ATMEL
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
}
// 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
// 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
};
}
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.
/*****************************************************
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;
Programa 13. 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.
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.
Chip type
: ATtiny461
Clock frequency : 1,000000 MHz
Memory model
: Tiny
External SRAM size : 0
Data Stack size : 64
*****************************************************/
#include <tiny461.h>
// 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
// 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];
};
}
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];
};
TPICOS SELECTOS DE
PROGRAMACIN DE
MICROCONTROLADORES AVR
POR DAVID INFANTE SNCHEZ
dinfante29@hotmail.com
dinfante@itmorelia.edu.mx
Revisin 2.0
Abril del 2008
Objetivos
Instrumentacin Virtual
Telemetra
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