Arduino Mega. Puertos I/O Digitales.
Click en la imagen para mayor detalle.
Me he decidido a hacer el robot hexápodo con un AVR para ver si
consigo aprender algo de estos micros, al ser un proyecto grande y
complejo se tocarán la mayoría de las posibilidades de
los micros por lo que es ideal para aprender. Para ello voy a usar la
placa de Arduino Mega que me parece lo mejor que se puede conseguir en
características/coste, esta placa me ha cambiado todos los
proyectos que tenía pensados para estos meses... Resumiré
todos los avances que haga aquí para mantenerlos ordenados y a
mano cuando los necesite recordar, si no suelo perderlos y olvidar. Voy desde cero por lo que será
largo y nada de lo que escriba tiene que estar bien.. lo único
que puedo hacer es verificar el correcto funcionamiento de los pasos
que vaya dando, si alguien quema su Arduino que no me eche la culpa x_x.
Lo primero es identificar los puertos que tenemos disponibles en los
conectores de la placa, y por tanto los puertos que podemos usar. Los
puertos con un punto en el dibujo son los que tienen conexión al
mundo exterior a través de los distintos conectores de la placa,
los puntos azules son los puertos que van conectados al
integrado FTDI, es decir el RX y TX para la comunicación en
serie, van conectados mediante una resistencia de 1K en serie por lo
que los podemos usar para nuestros fines, aunque teniendo la
conexión usb montada en la placa mejor dejarlos para lo que
están. Los puntos dobles tienen dos conectores distintos
en la placa del arduino (accesibles desde dos sitios).
Los pines de los puertos, su situación en la placa del Arduino y sus funciones alternativas:
En total tenemos unos 70 pines de entrada/salida accesibles desde el
mundo exterior, de los que16 los podemos usar como adc, 14 como salidas
pwm, tenemos 4 USART, un I2C o TWI, y un SPI,
conexión USB para el PC y el botón de Reset. Y más
funciones que todavía desconozco y no puedo evaluar, junto a
una buena cantidad de memoria hace que en principio parezca una
placa ideal para el proyecto del Hexápodo.
Puertos de entrada salida. Fuente Datasheet.
En los microcontroladores los puertos se pueden configurar
como entrada/salida digital, la mayoría de ellos además
llevan otras funciones alternativas multiplexadas que requieren de
hardware adicional integrado en el propio puerto, éste lo
iré viendo según vaya necesitando esas funciones. Los
puertos son capaces de suministrar o absorber una corriente
máxima de 40 mA @ 5V, que nunca se deberá sobrepasar ya
que podemos quemar el puerto o el microcontrolador, y este micro suelto
sale por unos 25 euros, además de las 100 patas que hay que
soldar para cambiarlo.
El esquema equivalente de entrada para el puerto digital es el siguiente:
Se pueden ver un par de diodos de protección, la capacitancia
del pin y una resistencia de pull-up que podemos activar o desactivar
cuando configuremos el puerto como entrada, lo que en algunos casos nos
ahorrará poner una resistencia externa.
Por cada puerto tenemos en la memoria tres registros de ocho bits para su uso y configuración, DDRx, PORTx, y PINx
PORTx: es usado para escribir datos en el puerto.
DDRx: sirve para configurar el puentro como entrada (0) o salida (1), al revés que en los pic.
PINx: es usado para leer datos en el puerto.
Poniendo 0 en el bit DDA7 del registro DDRA, configuraríamos el
pin 7 del puerto A como entrada, si en el registro PORTA, en su bit
PORTA7 ponemos un 0 desactivamos la resistencia de pull-up del pin7 del
puerto A (PA7), si ponemos un 1 en lugar del 0 activamos esta
resistencia. El bit PUD del registro MCUCR hábilita (0) o
deshábilita (1) todas las resistencias de pull-up
independientemente del valor de los bits en PORTx (x: designa el
puerto). Para leer el valor que tenemos en la entra del pin7 los
hacemos en el bit PINA7 del registro PINA.
Si queremos configurar este mismo pin como salida debemos de poner un 1
en el bit DDA7 del registro DDRA, y para poner a uno (suministra
corriente) o cero (absorbe corriente) la salida lo hacemos en el bit
PORTA7 del registro PORTA. Si el pin está configurado como
entrada PORTA activa o desactiva las resistencias de pull-up, y si
el puerto está configurado como salida PORTA asigna el
valor de los pines de salida.
x: designa el puerto.
n: designa el pin.
El esquema digital del puerto donde entran los bits de configuración anteriores es el siguiente: Hello World!
Un primer programa para comprobar el funcionamiengo dle Arduino
Mega desde el AVR Studio y la configuración y funcionamiento de
lo anterior. Para programar el Arduino se va a usar un programador
externo directamente conectado al conector que trae de ICSP y no el
Bootloader con el que podemos programar el micro a través de su
USB que viene grabado en la placa de Arduino. En lugar de usar el
entorno de programación de Arduino se usa el AVR Studio con el
WinAVR de compilador, aunque estoy planteandome usar uno comercial,
CodevisionAVR (160 euros) que por lo poco que he visto me gusta
más que el WinAVR.
Primer código para AVR..
/**************************************************************************************** *Configuración puertos digitales. *PORTA0: entrada, pulsador, pull-up off. *PORTA1: entrada, pulsador, pull-up on. *PORTA2: salida, diodos led. *PORTA3: salida, diodo led. *PORTA4: salida, osciloscopio *Funcionamiento: PA2=PA0, PA3=PA1, PA4 cambia valor en cada iteracción. * ******************************************************************************************/ #include <avr/io.h> void inicializar_puertos(void);
int main(void) { inicializar_puertos(); char leer_pin=0;
while(1) { PORTA ^= 0x10; //0001 0000. 0^1=1 no afecta el pull-up de PA1 //Si PA0=1 activamos la salida PA2, si no la desactivamos leer_pin= PINA & (1<<PINA0); if(leer_pin) PORTA |= (1<<PORTA2); //Rojo else PORTA &= ~(1<<PORTA2); //Verde
//Si PA1=1 activamos la salida PA3, si no la desactivamos leer_pin= PINA & (1<<PINA1); if(leer_pin) PORTA |= (1<<PORTA3); //Amarillo ON else PORTA &= ~(1<<PORTA3); //Amarillo OFF } }
// Funciones void inicializar_puertos(void) { DDRA=0x1C; //0001 1100 2,3,4 Salidas. PORTA=0x02; //0000 0010 Resistencia de pull-up activada en PA1 }
Tenemos dos pulsadores y 3 diodos led, un pulsador conectado mediante
la resistencia de Pull-up interna del micro activa y apaga un diodo
led, el otro pulsador enciende o apaga los otros dos diodos led, un
diodo led se enciende cuando el microcontrolador proporciona corriente
(salida a 5V) y el otro cuando absorbe corriente (salida a 0V). Una
tercera salida cambia su estado en cada iteracción del búcle, de
esta forma podemos ver a que frecuencia se ejecuta el programa en el
micro.
Lo primero y que no sé como se puede hacer, es acceder a los
pines de cada puerto de forma directa como se hace con otros
compiladores, aquí tenemos que usar operaciones OR o AND para
leer o escribir un sólo bit sin afectar a los demás, por
ejemplo leer_pin= PINA & (1<<PINA1);,
haría la operación AND del valor del puerto A con
(1<<PINA0). PINA0=0, PINA1=1, etc.. son valores que tenemos
definidos en las librerias del micro, por lo que haríamos una
operación de desplazamiento a la izquierda sobre el valor 1
(00000001) de 1 bit en este caso obteniendo (00000010). Lo que nos da
la siguiente operación: PINA (xxxxxxxx)&(00000010) =
(000000X0), sacando el 1 o el 0 del puerto que queremos leer, pasandolo
por el if(leer_pin) si éste es distinto de cero tenemos un 1 en
el pin que hemos leído. En fin, con lo fácil que
sería hacer if(PORTA.1) en lugar de todo eso. Y lo mismo para
asignar una salida, tenemos que hacer la operación de OR sobre
el puerto con los bits que queramos activar puestos a 1 en el Byte, y
si queremos poner a cero pues la operación de AND sobre el
puerto con los bits que queramos desactivar puestos a cero en el byte y
el resto a 1. Si queremos desactivar sólo un pin por ejemplo en:
~(1<<PORTA2); obtendríamos
el valor (11111011) el operador ~ invierte, lo que pondría a
cero ese pin al hacer la AND con el puerto dejando el resto como
estaban.
Con PORTA ^= 0x10;
hacemos que el bit4 del byte cambie en cada iterración, 0^0 = 0,
0^1=1, 1^0=1, 1^1=1, ya que hacemos la operación con 00010000,
dejando los demás bytes del bit sin afectar a hacer su
operación con un 0, 0^X=X.
Esquema electrónica conectada a Arduino. (Los nombres de las parejas están cambiado en la protoboard).
Video del funcionamiento:
El funcionamiento no ha sido del todo correcto, la resistencia de
Pull-up me hacía una cosa rara y no sé porque, tengo que
buscar de cuanto es el valor de esta R y sus detalles.. Los pulsadores
y los leds funcionan de la manera esperada como se puede ver en el
video, pero cuando pulsaba el pulsador del los leds rojo y verde,
metiendo un cero al pin del micro y por tanto poniendo un cero en su
correspondiente salida, en la otra salida (led amarillo) podía
apreciar como el brillo del led era menor encontrando la siguiente
salida:
La razón ni idea, no sé si el error está en el
código o donde, no veo que en ningún momento desactive la
resistencia de pull-up en PORTA, además tiene una frecuancia de
50Hz por lo no creo que sea el código. Poniendo una resistencia
externa en el pulsador se soluciona el problema.
En el pin 4 (el que cambia en cada paso por el búcle) aparece la siguiente señal:
La frecuencia del programa es de 148.1 KHz, el reloj de la placa es de
16MHz pero en los fuses a la hora de seleccionar el reloj sólo
me parece opciones de 8 MHz, por lo que no sé si lo tengo bien
configurado, y una Vpp de 8.72V.
Me queda mucho que leer y estudiar para empezar a manejar estos
micros, la primera impresión del WinAVR no ha
sido satisfactoria, he visto código del CodeVision AVR y me
parece
más amigable, sobretodo porque te permite hacer operaciones a
nivel de pin en los puertos de salida sin tener que estar usando ANDs y
ORs y demás operadores de bits, su precio es de 160 euros y
dadas las horas que voy a dedicar a este proyecto que van a ser muchas
puede que me merezca la pena la ineversión, así que voy a
ver si me informo bien. Si alguien tiene experiencia con estos micros,
conoce varios compiladores y me puede aconsejar se lo agradezco, porque
acabo de empezar con ellos y ando muy perdido. Cualquier
recomendación de libros o manuales también vienen bien
(de momento estoy empezando a leer todo lo que encuentro por internet).
Para cualquier comentario más abajo, gracias, saludos. blog comments powered by Disqus