Você está na página 1de 20

Cuando lo analogo se vuelve digital.

Bien, en esta entrada vamos a usar el ADC del Atmega8. ADC es el acronimo en ingls para Conversor Analogo Digital. Existen muchos elementos analogos que podemos usar a travez del ADC: Fotoceldas, termopares(para medir temperatura), sensores de presin, sensores de distancia, etc. En este caso vamos a usar una LDR (Resistencia Dependiente de la Luz) para saber si nuestro dia esta nublado (ok es medio inutil, pero algun ejemplo hay que dar). Para hacerlo mas interesante, vamos a agrega un boton para establecer el umbral de cambio. Vamos a usar el mismo conexionado de Programus Interruptus. Con la excepcin de que vamos a icluir una LDR y una resistencia de, digamos, 1Mohms.

Ahora

vamos

elegir

las

opciones

para

nuestro

Atmega8.

Quedando

asi:

Notemos que he dejado el bit 3 del puerto D como entrada con resistencia pull-up, de este modo no tenemos que agregar la resistencia de 10kohms externa.

El

programa

se

encuentra aqui.

Incluye

las

explicaciones.

Algunos ya se habran dado cuenta de que copiar el programa tal cual se los entrego sobreescribe todas las opciones que elegimos al generar el proyecto con el CodeWizard. No obstante sigo haciendolo por cuestiones didacticas. En la siguiente entrada vamos a agregar una cosita mas. Algo llamado PWM.

Los quiero banda. Comenten. Publicado por Juanministrador 0 comentarios Etiquetas: asbasp, atmega8, avr, Avrdude, bricolage, code view, CodeVisionAvr, comunidad atmel,display, LCD PIN PORT M8, microcontroladores, protoboard, usbasp

02/08/2010

A manera de Repaso.
Esta entrada puede parecer aburrida, sin embargo puede que sea la mas enriquecedora que hayamos escrito. A travez del tiempo que hemos pasado juntos he ido experimentando formas para poder comunicar la experiencia que yo he adquirido, tratando de evitar las partes donde me he dado de topes en la pared. Como se habran dado cuenta los programas escritos en C (ANSI C en este caso) confunden al sistema HTML que se usa en estos blogs y por tanto no se pueden simplemente pegar. Para tratar de que los programas pasen integros a sus manos, me encontre un sitio que alberga documentos de texto preformateado, asi que ahora pueden simplemente copiar y pegar la totalidad del programa.

Recordemos que el programa vacio nos lo genera el CodeVisionAVR a partir de la Herramienta CodeWizard:

Esta herramienta nos muestra una serie de etiquetas que nos permiten configurar los dispositvos internos del Atmega8 (o cualquier AVR de 32bits que muestre en la lista). Hasta el momento hemos configurado lo siguiente.-

Chip: En este caso elegimos la velocidad a la que esta corriendo el Atmega8 (ver "Fusibles. Jefa! ya llego la luz"). Obiamente escogeriamos el Chip Atmega8 u Atmega8L (practicamente es indiferente).

Puertos: El Atmega8 tiene 3 puertos: B(8 bits) C(6bits) y D(8 bits).

Cada bit de cada puerto puede configurarse como salida, entrada (toogle) o entrada (con resistencia pull-up). Hasta este momento solo hemos usado salida y entrada (pull-up).

Interrupciones Externas: Aqui elegimos alguno de los 2 pines de interrupciones externas. stas, al ser activado el pin establecido interrumpen el programa principal y ejecutan una rutina, dejando al programa continuar despues. El Atmega8 puede configurarse para 2 interrupciones externas INT0 e INT1 (patitas 4 y 5 respectivamente). El metodo de deteccin puede ser:

Low Level.- Se activa mientras el estado del pin se mantenga en 0 (bajo). Any Change.- Se activa cada vez que el estado cambia de 0 a 1 o viceversa. Falling Edge.- Se activa cuando el estado pasa de Alto a Bajo (o a 1). Risin Edge.- Se activa cuando el estado pasa de Bajo a Alto (1 a 0).

LCD: Nuesto Atmega puede configurarse facilmente para escribir en un LCD de texto. En este caso se elige el puerto y el programa nos muestra que bit(patita en este caso) se conecta a que pin del LCD. Tambien se escoge la cantidad de caracteres del LCD.

Ariba Esas Ahora

se

muestra son

el las

paraesquematico que hemos

de

conexion. usado el programa

En

este hasta

caso el con

del

puerto

B.

hemos generado

momento. CodeWizard.

bien.

Ya

que

"vacio"

el

Me declaro ser incapaz de hacer un curso formal de ANSI C, asi que les dejo un vinculo con un curso muy amplio sobre ANSI C. Publicado por Juanministrador 0 comentarios Etiquetas: atmega48, atmega8, avr, Avrdude, CodeVisionAvr, comunidad atmel, LCD PIN PORT M8,usbasp

30/07/2010

Programus Interruptus.
Ok vamos a explorar una funcin muy interesante de los microcontroladores llamada Interrupciones Externas. Como lo indica su nombre, interrumpen la ejecucin del programa sin importar donde se encuentre y ejecutan una funcin o subrutina, dejando continuar el problema despues. Aprovechando que tenemos montado el LCD del post anterior (Lucy in the Chair with Diamonds) vamos a agregar un boton en la patita5 del Atmega8 (PORTD.3/PIND.3) y a su vez a tierra. En esta ocacin vamos a utilizar una resistencia de 10kohms externa (en configuracin pull-up). Paralelo al boton conectaremos un capacitor de 0.1uF (100 nF) para evitar los rebotes. El paraesquematico es mas o menos asi:

Ahora Generamos

vamos nuestro proyecto

al con

estas

CodeVisionAvr. caracteristicas:

Aqui se encuentra el programa completo.

Los

cambios

importantes

respecto

anteriores

programas

son:

La inlcusin de la libreria stdlib.h que incluye la funcin itoa(entero, cadena). Esta funcin nos permite convertir valores numericos en cadenas de texto para mostrarlas en el LCD con la funcin lcd_puts(cadena); La rutina que se ejecuta cada vez que se activa la interrupcin. // External Interrupt 1 service routine

interrupt [EXT_INT1] void ext_int1_isr(void) { while(PIND.3==0){} l++; if(l>65535)l=0; }

La definicin de la variable l que se tiene que realizar antes de la rutina de interrupcin.

Como habra notado re-hicimos nuestro contador, con un programa mas corto y con mejor presentacin gracias a nuestra pantalla de LCD. El manejo de interrupciones nos sera muy util cuando realicemos programas mas complicados. Aunque en programas simples y meramente lineales yo prefiero no emplearlos. En la siguiente entrada vamos a emplear el ADC (conversor Analogo-Digital) que incluye nuestro querido Atmega8. Recuerden exponer sus dudas y sus inquietudes en la seccin de comentarios. Es esa parte la que en realidad mantiene vivo un blog. Publicado por Juanministrador 0 comentarios

29/07/2010

Lucy in the Chair With Diamonds (LCD)


Ok. Ya hicimos hemos pasado de un 555 a un 4017 a un par de 4026, incluso hemos interactuado con nuestro microcontrolador. Ha sido duro, pero lo hemos superado. El asunto de la programada de una computadora es mas fcil que el de un microcontrolador por que tenemos una pantalla y podemos ver cdigos de error y valores de las variables, etc. Bueno, que tal si agregamos un pequeo Display de Cristal Liquido (LCD) a nuestro protoboard. Quiz la parte mas desafiante de este proceso sea Comprar el lcd. En AG Electronica el precio mas bajo es de $44 pesotes mexicanos mas iva por un LCD de 16 caracteres. Para algunas personas (yo incluido) ese precio puede detenernos un momento. La alternativa es ir a uno de esos deshuesaderos de partes electronicas. Asi me hice yo de un LCD de 40 caracteres x 2 lineas por solo $60.00 neto. Practicamente cualquier LCD de 16 pines nos es til. He encontrado algunos de 16 caracteres en $10.00 Pesos Mexicanotes. Asi que la primer tarea sera hacernos de un LCD. La siguiente parte ya es mas fcil. Conexionado del LCD:

Ok no fue tan fcil, de hecho creo que a partir de este punto va a ser mas fcil trabajar con esquemticos.

Tomese en cuenta que no estoy incluyendo las conexiones del programador. Bien.

Vamos al CodeVisionAVR Elegimos el Atmega8 a 8mhz y en la pestaa lcd seleccionamos el puerto D y el numero de caracteres que tenga nuestro display. Por default podemos poner 16, si es mas grande se puede modificar mas adelante.

Como veran las conexiones que ya hicimos son las mismas que aparecen en la pantalla. Configuramos D como salida, B como entrada con resistencias Pull-up y C como entrada toogle (sin resistencias Pull-up ) Aqui esta el codigo que vamos a programar. (Dar click para visualizar) La explicacin esta integrada en el archivo de texto. No obstante

while (1) { lcd_clear(); lcd_putsf("Atmega8 LCD"); delay_ms(1000); lcd_clear(); lcd_putsf("Otro texto"); delay_ms(1000); }; }

//borra la pantalla //Escribe un primer texto //Espera 1 segundo //borra la pantalla //Escribe un segundo texto //Espera 1 segundo

Como veran el programa muestra dos textos que se alternan a intervalos de 1 segundo.

Confieso que la primera vez que lo hice mande que dijera 2 grocerias... Pero astedes pongan lo que les agrade. De tarea, extiendan el programa para que se aviente al menos 4 versos del poema que les agrade. Cambien los valores de los tiempos y aadan una pausa mayor al final.

En la siguiente entrada vamos a hecharle candela muchachos. No desarmen su protoboard. (prometo que lo agrego en menos de 2 dias) Publicado por Juanministrador 0 comentarios

Los fusibles. "Jefa... ya llego la luz"


Me tropece con los atmega16 y atmega32, a causa de que AG Electronica por un momento se quedo sin atmega8, pense que podia simplemente llegar y programar igual que el m8 (abreviemos). Cuando ejecute mi programa la mitad del puerto C no funcionaba. Yo casi chillaba por que pense que por un descuido le habria dado alguna descarga y me lo habia cargado... Pero no, resulta que los m16 y m32 vienen configurados de fabrica con esas terminales activadas para JTAG, que no es mas que la conexin para otro tipo de programadores. Asi fue como descubri los fusibles. No se por que se les quedaria ese nombre (fusibles/fuses) a ese grupo de bits, sin embargo permiten ciertas configuraciones dentro del chip, como la velocidad del reloj y el umbral de desactivacin (brown-out). Es ahi donde esta lo interesante, ya que nuestro chip m8 esta programado de fabrica para trabajar a 1Mhz, pero cambiando estos fusibles, Facilmente podemos hacerlo trabajar a 8Mhz! Sin un cristal externo. Esta es la direccin de una pagina que nos genera una linea de comando de acuerdo a lo que necesitemos. Primero escogemos el microcontrolador (en este caso el Atmega8) Ahora cambiaremos la velocidad a Int R.C. osc 8 Mhz:

Hay que tener cuidado de no cambiar el control que dice [Reset Disable] puesto que el programador podria dejar de funcionar. Damos click en Apply Feature Settings y al final de la pagina nos genera algo asi:

Si agregamos esa linea a avrdude -p m8 -c usbasp (que define nuetro chip y programador), queda asi: avrdude -p m8 -c usbasp -U lfuse:w:0xe4:m -U hfuse:w:0xd9:m

lo ejecutamos desde la terminal de ms-dos:

Y listo, solo tenemos que configurar el chip a 8mhz cuando usemos el CodeVisionAVR:

Por cierto echenle un ojito a estos videitos: Clavetero Virtual Un robotito que se aprende el ritmo que le enseemos.

P.O.V. Un interesante efecto visual. (el desorden que se ve detras es mi desorden habitual y es la razn por la que no pongo fotografias. En algun punto vamos a realizar estos proyectos. Publicado por Juanministrador 0 comentarios

Conteos, los rebotes y el mundo real.


Saludos. Si me hicieron caso y no desarmaron su protoboard de la entrada anterior, genial. Si no aguantaron los 6 meses que me avente de vacaciones.... Pos perdon otra vez, habra que armarlo de nuevo. Suponiendo que ya estamos listos, vamos a consegir un boton pulsador normalmente abierto. Existen muchos modelos y tamaos, cualquiera nos sirve mientras puedan conectarle las patitas al protoboard.

Ahora vamos a colocarlo en el Protoboard y conectar una patita a tierra y la otra al pin 2 que es el bit0 del puerto D. (se leera como PIND.0 y se escribira como PORTD.0). Quedando mas o menos asi:

Notese que puse mas gruesos los cables del boton, pero es solo para facilitar su identificacin, puede usarse cualqier cablecito mientras no este encuerado. Ahora bien abrimos el codevision como de costumbre, pero esta vez vamos a definir los puertos C y B como Salidas (out) y al puerto D como entrada (in) con resistencias pull-up.

Asi mero: Eso de las resistencias Pull-up solo significa que el atmega8 va a conectarse por dentro de forma que las entradas sean consideradas positivas hasta que algun dispositivo las ponga a tierra. Esto es muy util por que de otro modo tendriamos que poner las resistencias nosotros por fuera. En este caso la entrada se leera como un 1 hasta que se presione el boton, en cullo momento se leera como un 0.

Dicho esto vamos a crear el programa Agregamos la libreria del retraso de tiempo con #include<delay.h> en la parte de las variables globales vamos a integrar: int l; // (l sera el numero a contar) char seg []={63,6,91,79,102,109,125,7,127,103}; // (seg son los valores para expresar cada numero)

Como ven es la misma mecanica del post anterior, con la excepcin de la configuracin de entrada del puerto D. El programa varia un poco: while (1)

{ if(l==100)l=0; //si el valor de l llega a 100, lo regresa a 0. if(PIND.0==0)l++; // si el PIND8 se encuentra en nivel bajo(tierra) incrementa el valor de l. PORTC=2; //Pone el PORTC.0 en bajo y el PORTC.1 en alto encendiendo asi el display unidades. PORTB=seg[l%10]; //presenta el numero en el display. (leer post anterior para explicacin) delay_ms(5); //espera 5 milisegundos PORTC=1; //Pone el PORTC.0 en alto y el PORTC.1 en bajo encendiendo asi el display decenas. PORTB=seg[l/10]; //presenta el numero en el display.(leer post anterior para explicacin) delay_ms(5); //espera 5 milisegundos PORTB=0; // Pone el puerto B en 0 apagando ambos displays (por un tiempo efimero) }; }

Hasta aqui vamos a compilar y montar del modo tradicional. Ahora podemos pulsar el boton y ver como el aparatito cuenta. Intentalo antes de seguir leyendo.

Asi es. Cuenta tan rapido que nos parece que esta generando numeros al azar. Esto ha sido por que la instruccin if(PIND.0==0)l++; solo detecta si el boton esta pulsado. De este modo como el ciclo se repite cada 10milisegundos aproximadamente, no nos da tiempo a soltar el boton. Asi que cambiamos el programa un poquitin. if(PIND.0==0){ // en caso de que el PIND.0 este en nivel bajo: l++; // incrementa el valor de l y... while(PIND.0==0){} //mientras esta en nivel bajo "hace nada" } // fin de la condicin Asi que el programa queda asi: while (1) { if(l==100)l=0; //si el valor de l llega a 100, lo regresa a 0. if(PIND.0==0){ // en caso de que el PIND.0 este en nivel bajo: l++; // incrementa el valor de l y... while(PIND.0==0){} //mientras esta en nivel bajo "hace nada" } // fin de la condicin PORTC=2; //Pone el PORTC.0 en bajo y el PORTC.1 en alto encendiendo asi el display unidades. PORTB=seg[l%10]; //presenta el numero en el display. (leer post anterior para explicacin)

delay_ms(5); //espera 5 milisegundos PORTC=1; //Pone el PORTC.0 en alto y el PORTC.1 en bajo encendiendo asi el display decenas. PORTB=seg[l/10]; //presenta el numero en el display.(leer post anterior para explicacin) delay_ms(5); //espera 5 milisegundos PORTB=0; // Pone el puerto B en 0 apagando ambos displays (por eso el tiempo efimero) }; }

Probemoslo ahora y veremos una gran mejoria. Si aun notamos que cuenta de mas, es por que los botones son perfectos, y al momento de hacer contacto hacen "falsos contactos" rapidisimos, que para nosotros son imperceptibles, pero que un microcontrolador serio como nuestro querido atmega si toma en cuenta. Esos falsos contactos son conocidos como "rebotes" o "bounces" y existen dispositivos que se encargan de anularlos llamados "debouncer". En nuestro caso para solucionarlo, simplemente vamos pedir a nuestro chip que espere 40 milisegundos. La instruccin es delay_ms(40); pero les dejo de tarea donde deben agregarla.Despues de while(PIND.0==0){}

Juego de luces /***************************************************** Project : Leds_T1 Author : Nestor ccencho Company : www.icabots.com Chip type : ATmega16 Clock frequency : 4.000000 MHz *****************************************************/ #include<mega16.h> #include<delay.h> #define xtal 4000000 int j; void main (void) { // declaramos el micro a usar atmega 16 // declaramso la libreria delay a usar // definimos el crystal a usar

// se declara variable // inicia el codigo

DDRD = 0xFF; // declara puertod como salida( ojo en atmel // 1 salida y 0 es entrada while(1) { for(j = 1; j <= 128; j = j*2) // bucle ascendente de leds { PORTD = j; // muestra en el puerto D delay_ms(50); // tiempo de retardo de 50 ms } for(j = 128; j > 1; j = j/2) // bucle desendente de leds { PORTD = j; // muestra en el puerto D delay_ms(50); // tiempo de retardo de 50 ms } } } // fin

Para manejar displays #include <mega16.h> char numeros[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D, 0x7D,0x07,0x7F,0x6F}; void main(void) { signed char i; DDRD=255; DDRC=0; i=0; while(1) { if(!PINC.0) { i++; if(i>=9) {i=9;} PORTD=numeros[i]; while(!PINC.0){}; } if(!PINC.1) { i--; if(i<=0) {i=0;} PORTD=numeros[i]; while(!PINC.1){}; } } } // declaro como salida el puertoD // asigno el numero cero al puertoD // declaro como entrada puertoC PORTD= numeros[0];

Você também pode gostar