ATmega16 – GPIO

GPIO: General Purpose Input Output, Entradas y Salidas de Propósito General, estos son los pines del uC que se usan para detectar o generar cambios lógicos.

Algo que se encuentra presente en muchos circuitos son elementos electrónicos de características mecánicas, un un claro ejemplo son los pulsadores, la desventaja de estos elementos mecánicos es su falta de precisión a la hora de realizar su trabajo y más aún cuando se tiene que combinar con elementos digitales de alta precisión.

Debido a que los pulsadores son comúnmente usados en los circuitos hay que estudiar uno de los principales defectos de estos “El efecto rebote” que consiste en que cada vez que se presiona un pulsador ocurren varios cambios de nivel alto a bajo (como en la imagen) o de bajo a alto durante milésimas de segundo, esto no lo percibimos nosotros pero puede ser percibido por el uC.

El uC al tener alta velocidad de lectura de datos puede entender esto como si se hubiera presionado el pulsador repetidas ocasiones y realice la operación programada múltiples veces, por eso que durante este tiempo de inestabilidad es necesario programar al uC para que no realice ninguna operación. Por lo general este solo dura aproximadamente 300 ms y se puede evitar realizando un retardo.

El ATmega16 cuenta con 4 puertos de entrada/salida (A,B,C,D), estos puertos se controlan mediante los siguientes registros:

DDRx: En este registro es el encargado de configurar al puerto como entrada (colocando un 0) o como salida (colocando un 1).
PORTx: Si el puerto fue configurado como salida es en este registro donde se colocan los valores a enviar.
PINx: Si el puerto fue configurado como entrada es por este registro que se lee el valor del puerto.

Ejemplo:

// * Author: Victor Dueñas Guardia
// * Info: www.netzek.com
// @Ejemplo:
// Al presionar un pulsador se enciende el LED correspondiente.
// Pseudocódigo:
// – Compruebo la activación del pulsador comprobando los pines de entrada.
// – Si se activa un pulsador inicio un retardo sino sigo comprobando.
// – Espero desactivacion del pulsador.
// – Envío el valor correspondiente por el puerto de salida.
.INCLUDE "M16DEF.INC //Incluye definición archivos ATmega16
.ORG 0
JMP PROGRAM //Interrupción Reset
PROGRAMA:
LDI R16,HIGH(RAMEND)
OUT SPH,R16
LDI R16,LOW(RAMEND)
OUT SPL,R1 //Coloco la Pila al final de la RAM
LDI R16,$00
OUT DDRB,R16 //Puerto B entrada
LDI R16,$0F
OUT DDRD,R16 //Puerto D salida
BUCLE: RCALL WAIT_ACTIVATION //Espero la activación del pulsador
OUT PORTD,R18 //Activo el LED correspondiente
RJMP BUCLE
//……PROCEDIMIENTOS
WAIT_ACTIVATION:
IN R18,PINB
CPI R18,0B10101010
BREQ WAIT_ACTIVATION
CPI R18,0B10101000 //Compruebo Pulsador 1
BRNE Noes0
LDI R18,0B00000001
RJMP Seguir
Noes0:
CPI R18,0B10100010 //Compruebo Pulsador 2
BRNE Noes1
LDI R18,0B00000010
RJMP Seguir
Noes1:
CPI R18,0B10001010 //Compruebo Pulsador 3
BRNE Noes2
LDI R18,0B00000100
RJMP Seguir
Noes2:
CPI R18,0B00101010 //Compruebo Pulsador 4
BRNE WAIT_ACTIVATION
LDI R18,0B00001000
Seguir:
RCALL RETARDO
WAIT_DEACTIVATION:
IN R19,PINB
CPI R19,0B10101010 //Compruebo desactivación de pulsador
BRNE WAIT_DEACTIVATION
RCALL RETARDO
RET
RETARDO: //Configurado Evitar Rebote
LDI R25,31
Bucle_Externo:
LDI R24,255
Bucle_Interno:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DEC R24
BRNE Bucle_Interno
DEC R25
BRNE Bucle_Externo
RET
view raw PuertosIO.asm hosted with ❤ by GitHub
/*
* PuertosIO.c
*
* Author: Victor Dueñas Guardia
* Info: www.netzek.com
@Ejemplo:
Al presionar un pulsador se enciende el LED correspondiente.
Pseudocódigo:
– Compruebo la activación del pulsador comprobando los pines de entrada.
– Si se activa un pulsador inicio un retardo sino sigo comprobando.
– Espero desactivacion del pulsador.
– Envío el valor correspondiente por el puerto de salida.
*/
#include <avr/io.h> //Incluyo las definiciones del ATmega16
#include "mdelay.h" //Incluyo las definiciones de retardo
int main(void)
{
DDRB &= ~(1<<PB1) | ~(1<<PB3) | ~(1<<PB5) | (1<<PB7);
//PB1, PB3, PB5, PB7 como entrada
DDRD |= (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3);
//PD0, PD1, PD2, PD3 como salida
PORTD=0x00;
//Apago todos los LED's inicialmente
while(1)
{
_delay_ms(300);
//Delay para evitar efecto rebote
switch(PINB)
{
case 0b10101000:
PORTD = 0b00000001;
break;
case 0b10100010:
PORTD = 0b00000010;
break;
case 0b10001010:
PORTD = 0b00000100;
break;
case 0b00101010:
PORTD = 0b00001000;
break;
default:
break;
}
}
}
view raw PuertosIO.c hosted with ❤ by GitHub