• No se han encontrado resultados

Diseño Electrónico con Microcontroladores 02 - Estructura de un Programa

N/A
N/A
Protected

Academic year: 2022

Share "Diseño Electrónico con Microcontroladores 02 - Estructura de un Programa"

Copied!
37
0
0

Texto completo

(1)

Diseño Electrónico con Microcontroladores 02 - Estructura de un Programa

Responsable: Dr. Luis Arturo García Delgado

Colaboradores: Dr. Alejandro García Juárez y Dr. José Rafael Benito Noriega Luna

Universidad de Sonora [email protected]

31 de enero de 2019

(2)

Índice de la Presentación

1 Estructura Básica de un Programa

2 Variables

3 Constantes

4 Funciones para Puertos Digitales Entrada/Salida

(3)

Sección 1

Estructura Básica de un Programa

(4)

Estructura de un Programa

La estructura básica del lenguaje de programación de Arduino es bastante simple y se compone de al menos dos partes. Estas dos partes necesarias, o funciones, encierran bloques que contienen declaraciones o instrucciones.

setup() es la parte encargada de recoger la configuración y loop() es la que contiene el programa que se ejecutará cíclicamente (de ahí el término loop –bucle-). Ambas funciones son necesarias para que el programa trabaje.

Estructura básica de un sketch

void setup() { declaraciones;

}

void loop() { instrucciones;

}

(5)

Estructura Básica de un Programa

setup()

La función setup() se invoca una sola vez cuando el programa empieza. Se utiliza para inicializar los modos de trabajo de los pines, o el puerto serie. Debe ser incluida en un programa aunque no haya declaración qué ejecutar.

función setup() void setup() {

pinMode(pin, OUTPUT); // configura el 'pin' como salida }

(6)

Estructura Básica de un Programa

loop()

La función loop() hace precisamente lo que sugiere su nombre, se ejecuta de forma cíclica, lo que posibilita que el programa esté respondiendo continuamente ante los eventos que se produzcan en la tarjeta.

función loop() void loop() {

digitalWrite(pin, HIGH); // pone en uno (on, 5v) el 'pin' delay(1000); // espera un segundo (1000 ms) digitalWrite(pin, LOW); // pone en cero (off, 0v) el 'pin' delay(1000);

}

(7)

Operadores Básicos del Lenguaje C

Bloques de comentarios multilínea /* . . . */

Son áreas de texto ignoradas por el compilador y se usan para documentar o describir aspectos técnicos del código.

Empieza con los símbolos /* y termina con */.

Los comentarios pueden abarcar varias líneas y no ocupan memoria dentro del programa.

Comentarios de línea //

Los comentarios de una sola línea comienzan con doble diagonal // y terminan al dar enter en esa línea de código (no requieren un símbolo para terminarlos).

Llaves {. . .}

Las llaves definen el comienzo y el fin de bloques de función o bloques de declaración (como setup(), loop(), if, for...).

La llave { indica el comienzo de un bloque de instrucciones, finalizando con la llave de cierre }. Las llaves deben estar balanceadas.

(8)

Operadores Básicos del Lenguaje C

Operador punto y coma ;

El punto y coma “;” se utiliza para separar instrucciones en el lenguaje de programación de Arduino. También se utiliza para separar elementos en una instrucción de tipo “bucle for”. for( ; ; )

Olvidarse de poner fin a una línea con un punto y coma se traducirá en un error de compilación.

Operador coma ,

El operador coma sirve para separar variables o argumentos de entrada de una función o instrucción de programación.

Por ejemplo:

int i = 0, j = 100, k;

x = suma(a, b);

(9)

Sección 2

Variables

(10)

Variables

Una variable es una manera de nombrar y almacenar un valor numérico para su uso posterior por el programa. Como su nombre indica, las variables son números que se pueden variar continuamente a diferencia de lo que ocurre con las constantes cuyo valor nunca cambia. Una variable debe ser declarada y, opcionalmente, asignarle un valor. El siguiente código de ejemplo declara una variable llamada variableEntrada y luego le asigna el valor obtenido en la entrada analógica del PIN2:

int variableEntrada = 0; // declara una variable y le asigna // el valor 0

variableEntrada = analogRead(2); // la variable toma el valor // analogico del PIN2

Nota:Las variables deben tomar nombres descriptivos, para hacer el código más legible.

Nombres de variables pueden ser “contactoSensor” o “pulsador”, para ayudar al programador y a cualquier otra persona a leer el código y entender lo que representa la variable. Nombres de variables como “var” o “valor”, facilitan muy poco que el código sea inteligible. Una variable puede ser cualquier nombre o palabra que no sea una palabra reservada en el entorno de Arduino.

(11)

Variables

Tabla 1:Reglas para Identificadores. (Para nombrar variables, constantes, funciones, etiquetas....)

Correcto Incorrecto Descripción

robot9 9robot Los identificadores no pueden iniciar con un número, pueden ser confundidos con constantes y generan error de sintaxis.

sensor_23 sensor#23 Hay ciertos símbolos reservados para el lenguaje C como

# que se utiliza en la cabecera del programa para incluir archivos.

puerto_uno puerto.1 No se pueden poner puntos en el nombre de una variable ya que en lenguaje C, el punto en una variable se utiliza sólo en variables estructura y es para acceder a cada uno de sus campos internos.

Sin sin No se pueden utilizar identificadores con palabras clave o reservadas, en este caso, “sin” se utiliza para obte- ner la función matemática seno: sin(x). En Arduino las palabras clave aparecen en color naranja.

_99 -99 En general, los caracteres alfanuméricos @, !, #, $, +, -, *, /, =, %, (, ), [, ], ?, {, }, <, >, se emplean como operadores con funciones específicas.

(12)

Declaración de Variables

Todas las variables tienen que declararse antes de que puedan ser utilizadas. Para declarar una variable se comienza por definir su tipo como int (entero), long (largo), float (punto flotante), etc., asignándoles siempre un nombre, y, opcionalmente, un valor inicial. Esto sólo debe hacerse una vez en un programa, pero el valor se puede cambiar en cualquier momento usando aritmética y reasignaciones diversas. Esto se llama una asignación.

Ejemplos de declaraciones de variables:

int entradaVariable = 0;

byte b0, b1, b2;

int puerto[] = 0, 3, 5, 7, 9;

Una variable puede ser declarada en una serie de lugares del programa y en función del lugar en donde se lleve a cabo la definición esto determinará en qué partes del programa se podrá hacer uso de ella.

(13)

Tipos de datos

Tipo dato Ejemplo Tamaño Rango de valores

Boleano boolean bit1 = true; 1 bit true o false

Caracter char c = 'o'; 1 byte -128 a 127

Caracter sin unsigned char d = 123; 1 byte 0 a 255

signo unsigned char u[4] = {"hola"}; 4 bytes cada elemento 0 a 255

Byte byte val = 130; 1 byte 0 a 255

Entero int i = 0; 2 bytes -32768 a 32767

Entero sin unsigned int j = 15345; 2 bytes 0 a 65535

signo word w = 1890; 2 bytes 0 a 65535

Entero largo long lg = -34567; 4 bytes -2,147’483,648 a

2,147’483,647 Entero largo

sin signo

unsigned long ulg = 345689; 4 bytes 0 a 4,294’967,295

Punto flotante

float g = 9.81; 4 bytes ±3.4028235×1038

(14)

Sección 3

Constantes

(15)

Constantes Definidas por el Usuario

Las constantes en lenguaje C se refieren a valores que necesariamente se tienen que inicializar en su declaración o ya está predefinidos por el lenguaje, y posteriormente se manejan como valores fijos que no pueden ser alterados o cambiados en ninguna parte del programa.

Existen dos maneras en que el usuario puede definir constantes:

1 La primera es utilizar la palabra const seguida del tipo de dato y la declaración de la constante. Por ejemplo:

const float g = 9.81; // definir constante g .

2 La segunda forma sólo se puede utilizar en la cabecera del programa mediante el comando #define después el nombre de la constante y por último el valor a asignar. Ejemplo:

#define ledPIN 4 // definir constante ledPIN .

(16)

Constantes para Cadenas y Formato de Números

Tabla 2:Constantes para cadenas y formato de números

Constante Descripción

\0 Nulo o fin de un apuntador

\t Inserta tabulación horizontal

\ Barra invertida

\r Retorno de carro

\n Inserta una nueva línea

\b Espacio a atrás

\v Inserta tabulación vertical

\f Salto de página

\o, OCT Despliega números en formato octal (base 8)

\x, HEX Formato hexadecimal (base 16) BIN Despliega números en formato binario

(17)

Constantes para Cadenas y Formato de Números

Tabla 2:Constantes para cadenas y formato de números

Constante Descripción

\0 Nulo o fin de un apuntador

\t Inserta tabulación horizontal

\ Barra invertida

\r Retorno de carro

\n Inserta una nueva línea

\b Espacio a atrás

\v Inserta tabulación vertical

\f Salto de página

\o, OCT Despliega números en formato octal (base 8)

\x, HEX Formato hexadecimal (base 16) BIN Despliega números en formato binario

Nota: Las constantes de la tabla se utilizan cuando se despliega información en el monitor serial o en cualquier otro programa que permita desplegar texto en modo consola.

(18)

Constantes para Cadenas y Formato de Números

Para probar algunas de las constantes vistas, se podrá ejecutar el ejemplo ASCIITable.

Los pasos para hacerlo son:

Ejemplo 1 (Constantes de formato de cadenas).

1 Ir al menú Archivo

2 Seleccionar la opción Ejemplos/Communication/ASCIITable

3 Cargar el sketch en la placa Arduino.

4 Abrir el monitor serial para monitorear los datos que manda el Arduino a la computadora.

Identifique las partes de texto que se envían con formato.

(19)

Constantes Predefinidas en Arduino

Tabla 3:Constantes predefinidas en Arduino

Constante Descripción

true / false false se define como 0 (cero), mientras que true se asocia con 1, pero true también puede ser cualquier otra cosa excepto cero. Por lo tanto, en sentido booleano, -1, 2 y -200 son todos tomados como true.

HIGH / LOW Estas constantes definen los niveles de salida altos o bajos y se utilizan para la lectura o la escritura digital para las patillas. HIGH se define como en la lógica de nivel 1, ON, o 5 voltios, mientras que LOW es lógica nivel 0, OFF, o 0 voltios.

INPUT / OUTPUT Se utilizan al inicio del programa (en la función setup) para definir el modo de operación de los puertos digitales: INPUT (entrada) y OUTPUT (salida).

INPUT_PULLUP Las tarjetas Arduino tienen de manera interna resistencias que están conectadas a la fuente interna pull-up resistors, las cuales se pueden usar indicando en la función pinMode(INPUT_PULLUP) .

(20)

Constantes para Cadenas y Formato de Números

Tarea 1. Resistencias Pull-Up

Hacer una investigación sobre qué es una resistencia de pull-up, cómo se conecta, para qué se utiliza. Escribirlo a mano y entregar.

(21)

Sección 4

Funciones para Puertos Digitales Entrada/Salida

(22)

Configuración Entrada/Salida

pinMode(pin, mode)

Esta instrucción es utilizada en la parte de configuración setup () y sirve para configurar el modo de trabajo de un PIN pudiendo ser INPUT (entrada) u OUTPUT (salida).

pinMode(pin, OUTPUT); // configura 'pin' como salida

Nota: Las terminales de Arduino, por defecto, están configuradas como entradas, por lo tanto no es necesario definirlas en el caso de que vayan a trabajar como entradas. Los pines configurados como entrada quedan, bajo el punto de vista eléctrico, como entradas en estado de alta impedancia.

Es recomendable colocar una resistencia de pull-up a los pines de entrada. Estos pines tienen a nivel interno una resistencia de 20 KΩ a las que se puede acceder mediante software. Estas resistencias se acceden de la siguiente manera:

pinMode(pin, INPUT); // configura el 'pin' como entrada digitalWrite(pin, HIGH); // activa las resistencias internas

(23)

Configuración Entrada/Salida

Los pines configurados como OUTPUT (salida) se dice que están en un estado de baja impedancia y pueden proporcionar 40 mA (miliamperios) de corriente a otros dispositivos y circuitos. Esta corriente es suficiente para alimentar un diodo LED (no olvidando poner una resistencia en serie), pero no es lo suficiente grande como para alimentar cargas de mayor consumo como relés, solenoides, o motores.

Un cortocircuito en las patillas Arduino provocará una corriente elevada que puede dañar o destruir el chip Atmega. A menudo es una buena idea conectar en la OUTUPT (salida) una resistencia externa de 470 o de 1000 Ω.

(24)

Resistores de Pull Up y Pull Down

Los resistores de pull up se usan en circuitos electrónicos para asegurar que las entradas al Arduino se mantengan en niveles lógicos esperados aún si los aparatos externos se desconectan o están en alta impedancia. Sólo por el hecho de no tener nada conectado a una entrada no significa que ésta es un cero lógico.

Pull Up

Un resistor de pull-up “jala” debilmente el voltaje del alambre al que está conectado hacia el voltaje de la fuente cuando los otros componentes de la línea están inactivos.

(25)

Resistores de Pull Up y Pull Down

Pull Down

Un resistor de pull-down trabaja de la misma manera, pero está conectado a tierra. Mantiene la señal lógica cercana a cero volts mientras no esté conectado ningún otro elemento activo.

(26)

Instrucciones de Entrada/Salida Digital

digitalRead(pin)

Lee el valor de un pin (definido como digital) dando un resultado HIGH (alto) o LOW (bajo). El pin se puede especificar ya sea como una variable o una constante (0-13).

valor = digitalRead(Pin); // hace que "valor" sea igual al // estado leido en "Pin"

digitalWrite(pin, estado)

Envía al ’pin’ definido previamente como OUTPUT el valor HIGH o LOW (poniendo en 1 o 0 la salida). El pin se puede especificar ya sea como una variable o como una constante (0-13).

digitalWrite(pin, HIGH); // manda salida "pin" a un valor // logico HIGH

(27)

Instrucciones de Entrada/Salida Digital

El siguiente ejemplo lee el estado de un pulsador conectado a una entrada digital y lo escribe en el ´pin´ de salida LED:

Ejemplo 2.

Entrada/Salida digital Ejemplo_Led_PB.ino

int led = 13; // asigna a LED el valor 13 int boton = 7; // asigna a boton el valor 7

int valor = 0; // define el valor y le asigna el valor 0 void setup( ) {

pinMode(led, OUTPUT); // configura el led (pin13) como salida pinMode(boton, INPUT); // configura boton (pin7) como entrada }

void loop( ) {

valor = digitalRead(boton); // lee estado de la entrada boton digitalWrite(led, valor); // envia a la salida 'led' el

// valor leido }

(28)

Instrucciones de Entrada/Salida Digital

Este ejemplo es igual que el anterior, pero ahora se activa la resistencia interna de pull-up en la entrada de botón (¡con eso nos ahorramos conectar una resistencia extra!).

Ejemplo 3 (Entrada/Salida digital Pull-Up).

Ejemplo_Led_PB_pullup.ino

int led = 13; // asigna a LED el valor 13 int boton = 7; // asigna a boton el valor 7

int valor = 0; // define el valor y le asigna el valor 0 void setup( ) {

pinMode(led, OUTPUT); // configura el led (pin13) como salida pinMode(boton, INPUT); // configura boton (pin7) como entrada digitalWrite(boton, HIGH); // con esto activamos la resistencia

// interna de pull-up }

void loop( ) {

valor = digitalRead(boton); // lee estado de la entrada boton digitalWrite(led, valor); // envia a la salida 'led' el

// valor leido }

(29)

Manejo de Puertos Arduino UNO

Los registros de puertos permiten un manejo más rápido y a nivel interno de los pines de entrada y salida de la tarjetas Arduino.

Las tarjetas Arduino uno tienen tres puertos:

B (pines digitales 8 al 13) C (pines de entrada analógica) D (pines digitales 0 al 7)

Cada Puerto se controla mediante tres registros, que están definidos como variables en el lenguaje de Arduino. El registro DDR, determina si el pin es OUTPUT o INPUT. El registro PORT controla si el pin es HIGH o LOW, y el registro PIN lee el estado de los pines INPUT puestos mediante pinMode().

Los registros DDR y PORT pueden ser de lectura y escritura. Los registros PIN sólo ser de lectura.

(30)

Mapa de Puertos Arduino UNO

(31)

Manejo de Puertos Arduino UNO

PORTD mapea los pines digitales 0 al 7 de Arduino

DDRD – Dirección de datos en el registro Port D - lectura/escritura PORTD – Registro de datos de Port D - lectura/escritura

PIND – Registro de pines de entrada de Port D – sólo lectura

PORTB mapea los pines digitales 8 al 13 de Arduino. Los 2 bits más altos (6 & 7) mapean los pines del cristal así que no se pueden usar

DDRB - Dirección de datos en el registro Port B - lectura/escritura PORTB - Registro de datos de Port B - lectura/escritura

PINB - Registro de pines de entrada de Port B – sólo lectura PORTC mapea los pines analógicos 0 al 5

DDRC - Dirección de datos en el registro Port C - lectura/escritura PORTC - Registro de datos de Port C - lectura/escritura

PINC - Registro de pines de entrada de Port C – sólo lectura

(32)

Mapa de Puertos Arduino Mega

(33)

Manejo de Puertos

Ejemplo 4 (Manejo de Puertos).

El siguiente ejemplo configura un puerto con 7 pines de salida y uno de entrada.

Posteriormente envía un valor constante a las salidas del puerto, que se pueden desplegar con LEDs.

ManejoPuertos.ino

// Ejemplo ManejoPuertos.ino void setup( ) {

DDRD = B11111110; // configura el puerto D, pines del D1 al D7 // como salida y el pin D0 como entrada }

void loop( ) {

PORTD = B10101000; // enciende los pines digitales D7, D5 y D3 }

(34)

Operadores Lógicos a Nivel Bit

Los operadores lógicos realizan cálculos bit por bit en cada variable.

Operador Símb. Descripción Ejemplo

AND & Realiza la operación byte a = 92; // B01011100

lógica AND byte b = 101; // B01100101

byte c = a & b; // B01000100

OR | Realiza la operación byte a = 92; // B01011100

lógica OR byte b = 101; // B01100101

byte c = a | b; // B01111101

XOR ^ Realiza la operación byte a = 92; // B01011100

lógica XOR byte b = 101; // B01100101

byte c = a ^ b; // B00111001

NOT ~ Cambia cada bit a byte a = 92; // B01011100

su opuesto. byte b = ~a; // B10100011

Corrimien- >> Realiza un corrimien- byte a = 92; // B01011100 to o to de bits indicado byte b = a>>3; // B00001011

<< por el número de posi- byte c = a<<1; // B10111000 ciones especificado

(35)

Operadores Lógicos a Nivel Bit

Ejemplo 5 (Operador Lógico XOR).

En el siguiente ejemplo se utiliza el operador ^ (XOR) para conmutar (toggle) un bit en un dato de tipo entero.

Ejemplo_Blink_XOR.ino

// Ejemplo Blink_Pin_5 // Demo para OR Exclusiva void setup( ) {

DDRD = DDRD|B00100000; // configura el pin D5 como OUTPUT Serial.begin(9600);

}

void loop( ) {

PORTD = PORTD^B00100000; // invierte el bit 5.

Serial.print("Valor: ");

Serial.println(PORTD, BIN);

delay(1000);

}

¿Cómo interpreta la instrucción DDRD = DDRD|B00100000;?

(36)

Operadores Lógicos a Nivel Bit

Ejemplo 6 (Ejemplo de Operadores Lógicos a Nivel Bit).

Una variable de tipo entero contiene 16 bits:

int x = b0001011101010110;

Algunos ejemplos de operaciones lógicas a nivel bit y su interpretación se muestran a continuación:

y = (x >> n) & 1; // almacena el n-ésimo bit de x en y . y se cambia a 0 o 1.

x &= ~(1 << n); // fuerza el n-ésimo bit de x a ser 0. Los demás bits no se modifican.

x &= (1<<(n+1))-1; // deja intactos los n bits más bajos de x ; los demás bits más altos se ponen a 0.

x |= (1 << n); // fuerza el n-ésimo bit de x a ser 1. Los demás bits no se modifican.

x ^= (1 << n); // togglea el n-ésimo bit de x . Los demás bits no se modifican.

x = ~x; // togglea todos los bits en x .

(37)

Práctica 1

Práctica 1. Manejo de Puertos y Operaciones Lógicas a Nivel Bit

Para esta práctica se debe leer todo un puerto de entrada (p. e. puerto F en el arduino MEGA o puerto C en el Arduino UNO) conectando un arreglo de interruptores. Así mismo se selecciona otro puerto como salida (p. e. puerto K en el arduino MEGA o puerto B en el Arduino UNO), al que estarán conectados 8 LEDs.

a) Por el puerto de salida se envía el dato de entrada, sumándole el valor de una constante (p. e. binario 01100011). Es decir Pto. Sal. = Pto. Ent. + Cte.

b) El orden de los bits de más a menos significativos es b7 b6 b5 b4 b3 b2 b1 b0. Por el puerto de salida se obtiene la información del puerto de entrada pero los bits impares de la salida se fijan siempre a 1. Por ejemplo: Si la entrada es 00001101, la salida será 10101111.

c) Por el puerto de salida se obtiene el valor del puerto de entrada, pero

intercambiando los nibbles alto y bajo. (Un nible son 4 bits, es decir Nibble alto = b7 b6 b5 b4, y Nibble bajo = b3 b2 b1 b0). Por lo tanto, si se lee el dato 00001101, la salida que se obtendrá será 11010000.

Referencias

Documento similar

Through first-person soma design, an approach that draws upon the designer’s felt experience and puts the sentient body at the forefront, we outline a comprehensive work for

According to the IUS, the enablers ‘capture the main drivers of innovation perform- ance external to the firm’ (European Union 2014: 4) and cover three innovation dimensions:

La campaña ha consistido en la revisión del etiquetado e instrucciones de uso de todos los ter- mómetros digitales comunicados, así como de la documentación técnica adicional de

En cuanto a la relación entre los cambios de V sobre los componentes de Y, puede aplicarse el mismo tipo de análisis que el ahora descrito. Sin em- bargo, como no se trata

Además de esta correcta estimación de los efectos di- rectos e indirectos desde el lado de la producción, para el análisis completo del impacto económico es necesario in- cluir

The MIMO Analyzer E300, depicted in figure 1, is a second generation reverberation chamber with dimensions of 0.82m x 1.425m x 1.95m, eight wall-mounted antennas, different

The principle behind this meth- od shown in Figure 1 is to create the desired channel model by positioning an arbitrary number of probe antennas in arbitrary positions within

The method to emulate the chan- nel model consists of convolving the base band signal to be transmitted with the urban macro-cell or urban micro-cell channel model tap delay