Tuesday, August 19, 2014

Introducción a C/C++ (Embedded C)








Conceptos básicos


Para la programación de microcontroladores se utiliza una “extensión” del lenguaje C, conocido como Embedded C (término en inglés). Se puede distinguir a Embedded C como un lenguaje orientado a hardware, ya que la forma de programar, aunque es similar que a un programa para un ordenador personal, está orientado al manejo de los pines I/O (Entradas y Salidas) de sistemas digitales como lo son los microcontroladores. Este lenguaje no está ligado en especial a ningún tipo de hardware ni software, y ésta es una de las características principales que lo distinguen; aunque está catalogado como un lenguaje de nivel-medio, también combina elementos de lenguajes de alto-nivel con la funcionalidad del lenguaje ensamblador.

Un programa en embedded C es un conjunto de instrucciones, que a la vez forman funciones; dichas funciones se combinan para juntas formar un programa que puede ser ejecutado en el sistema digital o hardware que se está programando. En todo código en C siempre debe de incluirse la función main() que es, la que por simple traducción, se ejecuta al inicio del programa (o es la que inicia dicho programa). Todas las funciones creadas en el programa son invocadas por la función main() , ya sea directa o indirectamente. La función main() es considerada como la función de más bajo nivel, debido a que es a primera en ejecutarse al iniciar un programa; esta función también puede ser la más corta en cuanto a código, ya que puede llamar a otras funciones que se encarguen de todo el proceso que se necesita para el fin propuesto del programa.
Como ejemplo de la forma base de un programa en embedded C:




int main(void)
{
    while(1); //Do forever
}


Aunque el código del programa de arriba está estructurado de una manera correcta, jamás nos daremos cuenta si está funcionando o no, ya que simplemente no hará nada. Ahora agregando algunas líneas de código veremos que nuestro programa de alguna forma u otra está funcionando.


#include <stdio.h>
int main(void)
{ // main() function starts here
 printf("Hello world!"); // Prints Hello world!
 while(1) //  Do forever
 {
 }
} // main() function finish here


El código del programa anterior imprime la cadena de caracteres Hello world! una vez que sería a la salida estándar, que puede ser alguna salida por un puerto serial y entrara al ciclo infinito; aprovechando también comenzaremos a introducir algunos conceptos básicos de un programa en C (Embedded C en su caso).

El código while(1) es conocido como ciclo infinito, esto por el parámetro 1 que esta entre paréntesis, esto debido a que en lógica digital, 1 es verdadero y 0 es falso. Siempre que while() tome como parámetro algo que sea verdadero (1, 5>2, 0==0) ejecutara el código que esté entre sus llaves de apertura y cierre.

La línea int main(void), indica el inicio del código en C y es encerrado entre sus llaves de apertura y cierre. Esta es la función que simplemente da inicio al programa y mantiene el código ejecutándose con la ayuda de while(1).

Las directivas del preprocesador siempre están marcadas con el símbolo gato” (#) y por lo general van en la parte superior del código, esta directiva nos ayuda a incluir librerías de código (código reusable), definir palabras confusas con algunas mas familiares, entre otras. En este caso, estamos introduciendo el uso de la directiva #include que nos sirve para la importación de código reusable a nuestro programa actual, la librería stdio.h que esta incluida en nuestro anterior ejemplo (#include <stdio.h>) contiene la función printf() que utilizamos en nuestro código para imprimir la cadena de palabras Hello world!. Sin esta librería incluida, al momento de compilar nos generaría error en la línea donde se encuentra printf() ya que la definición de esta función no estaría disponible debido a la falta de dicha librería.


A continuación definiremos algunos elementos clave del código y que nos servirá como base para los futuros programas:

;
Punto y coma: siempre al final de cada línea de código se debe de terminar con un  punto  y coma, ya que sin él, el compilador generaría error en todas las líneas (no incluye funciones). Ejemplo:

printf("Hello world!");

{…}
Llaves de apertura y cierre: Estas llaves son indispensables para que el compilador reconozca el inicio y fin de cada función o ciclo (en caso de requerirlas). Para las funciones es necesario incluirlas ya que sin ellas el compilador generaría error; para el caso de los ciclos, en caso de que sean de más de una línea de código dentro de ellos también es necesario incluirlas; si sólo tendrán una línea para ejecutar, no son necesarias incluirlas (tenga en cuenta que un código bien estructurado, es también un código fácil de leer y comprender). Ejemplo:

while(1)
{
}

“Algún texto”
Por lo general, para representar cualquier cadena de texto, es necesario encerrarlo entre comillas, ya que será la única forma que el compilador reconocerá que se trata de un texto y evitara la generación de errores. Ejemplo:

printf("Hello world!");

//
O
 /*…*/
Doble diagonal o diagonal-asterisco-asterisco-diagonal: Esto nos ayuda a poner comentarios en nuestros programas, ayudara a que cuando después de algún tiempo regreses a revisar el mismo código sepas para que servía cada línea. La doble diagonal (//) sirve para comentar por línea, es decir, al dar ENTER o pasar a otra línea, ya dejara de ser comentario. Diagonal-asterisco-asterisco-diagonal (/*…*/) sirve para comentarios multi-lineas, es decir, Diagonal-asterisco (/*) marcara el inicio del comentario mientras que Asterisco-diagonal (*/) nos servirá para terminar dicho comentario. Estos comentarios son ignorados por el compilador y nunca generaran error usándolos adecuadamente. Ejemplos:

// Este es un comentario que terminará al terminar esta línea

/* Este es un comentario multi-linea
y puede servir para dar definiciones largas,
describir la forma de usar el programa, etc */


Nota: Los comentarios nos ayudan a entender bien nuestro propio código y cuando lo generamos para terceras personas, siempre se toma como buenas prácticas de programación el usarlos en las líneas que más confusas se vean o en funciones que hagan alguna actividad especial que no se puede distinguir con solo leer el código. En el lenguaje embedded C debemos de tener en cuenta que no todos los microcontroladores tendrán los mismos nombres de puertos, ni el mismo número de pines; por lo tanto es recomendable ser directo y conciso con los comentarios.

Friday, August 8, 2014

Conversión entre Sistemas Numéricos

Conversión entre Sistemas Numéricos
 

Los sistemas numéricos nos sirven para tener un manejo pleno de los puertos de control de los microcontroladores, a lo largo de todo el curso se verá la importancia de saber pasar de un sistema numérico a otro.

En el siguiente vídeo que tengo subido en mi canal de Youtube, les explico algo sobre las conversiones de la manera mas sencilla entre los tres principales sistemas (Binario, decimal y hexadecimal).



Enlace de mi canal de Youtube: https://www.youtube.com/user/TutorialAtmelUC/




_________________________
Conversión Decimal-›Binario

Para la conversión de un número decimal a binario se puede utilizar el método de divisiones sucesivas entre 2, el residuo es el valor del bit que se agregara al resultado final. A continuación veremos un ejemplo con el cual podemos entender la facilidad de la conversión entre estos dos sistemas.

Ejemplo: Convertir el número 124510 a binario2.



Entendiendo el dibujo de la parte de arriba tenemos que:

124510 = 100110111012         o    124510 = 0b10011011101

NOTA: Un número binario se puede expresar con el subíndice 2 (Sistema base 2) o con el índice 0b. Al expresar un número como 0b en alguna IDE, inmediatamente el compilador comprenderá que se trata de un número binario.




____________________________
Conversión Decimal-›Hexadecimal

Para convertir un número decimal (base 10) a un número hexadecimal (base 16), se utiliza el mismo método que para la conversión Decimal‹-›Binario, pero para este caso el divisor será 16. Recordemos que un número hexadecimal consta de 16 símbolos, números (0-9) y letras (A-F); para dicho fin y para no confundirse a la hora de convertirse el número se puede hacer una tabla de referencia como la siguiente Fig. 2 y al igual puede ser auxiliar una tabla de resultados:


Ejemplo: Convertir el número 124510 a hexadecimal:


NOTA: Un número hexadecimal se puede expresar con el subíndice 16 (Sistema base 16) o con el índice 0x. Al expresar un número como 0x en alguna IDE, inmediatamente el compilador comprenderá que se trata de un número hexadecimal

_____________________________
Conversión Binario‹-›Hexadecimal

Para la conversión de un número binario a un número hexadecimal, primeramente el binario tiene que separarse en grupos de 4 bits y hacer una tabla de referencia para encontrar el valor hexadecimal de cada conjunto de bits, el número de ejemplo será el mismo de los anteriores ejemplos; servirá de comprobación de la efectividad de los métodos y la facilidad de manejos de estos mismos:
Ejemplo: Convertir el número 0b10011011101 a hexadecimal:
*Primeramente haremos la tabla comparativa como la de la Fig. 3 y gráficamente veremos la separación de bits y la asignación del valor hexadecimal.
.



Para la conversión de hexadecimal a binario, simplemente se hace la forma inversa, cada valor hexadecimal se sustituye por su equivalente binario de la tabla.


Ejemplo: Convertir 0xAA a binario:


Como cada A en hexadecimal tiene el valor de 1010 en binario, el resultado será:

0xAA = 0b10101010


_______________________________________
Conversión (Binario & Hexadecimal)-›Decimal



Por último, nos queda mencionar el tema de la conversión de números hexadecimales y binarios a decimales. La conversión de Binario y Hexadecimal a Decimal consiste en que del bit menos significativo al más significativo, mediante potencias del valor del bit (20, 21, 22, 23, 24, 25, etc., 16 en el caso de hexadecimal) se vayan sumando dichos resultados, multiplicando por el valor de dicho bit. Resulta confuso la manera explicada del procedimiento a realizar, pero gráficamente se puede observar que es muy sencillo.

Ejemplo: Convertir 0b10011011101 y 0x4DD a decimal:





NOTA: En todos los ejemplos de conversión de sistemas se utilizó a propósito el mismo número, esto para ver la concordancia entre estos sistemas y verificar que los estamos trabajando bien.

Sistemas Numéricos

Sistemas Numéricos
______
Definición
Un sistema de numeración es un conjunto de símbolos a los cuales se les denominan dígitos,  y con la ayuda de estos podemos representar datos numéricos. En este tutorial nos centraremos en los tres sistemas de numeración principales en el ámbito de los sistemas embebidos: binario, decimal y hexadecimal.
_________
Sistema Decimal
Es el sistema representado por diez símbolos, los cuales constan de los números del 0 al 9. Este es el sistema numérico más utilizado a nivel mundial y con el que las operaciones aritméticas ya son familiares en cualquier entorno. El sistema decimal es también conocido como “Sistema de base 10”.
________
Sistema Binario
El sistema binario es uno de los más caracterizados para representar un sistema digital. Es conocido como Binario por el hecho de que cuenta solo con dos estados, puede ser: verdadero o falso, circuito abierto o circuito cerrado, negativo o positivo. A diferencia del sistema decimal que cuenta con los 9 símbolos que son los números del 0 al 9; este sistema solamente consta de dos símbolos, el 0 y 1. En este sistema las columnas no representan unidades, decenas, centenas, etc., como en el sistema decimal, sino la unidad (20), el doble (21), el doble (22), etc. De modo tal que aunque las sumas sean semejantes el límite seguirá siendo 1 (Máximo valor para números binarios).
Un número binario se representa como en la siguiente Fig.1, donde a la izquierda siempre será el más significativo y a la derecha el menos significativo.


Representacion binaria

Fig. 1. Tabla de referencia de representación binaria.

_________
Sistema Hexadecimal
El sistema hexadecimal tiene algo especial en su estructura, ya que es representado mediante números y algunas letras. Este sistema a diferencia del binario y del decimal es que éste consta de quince símbolos, son diez números (0-9) y de cinco letras (A-F). Lo que tiene de especial este sistema es que puede ser convertido a binario de manera fácil tomando en conjunto 4 bits o cuatro números binarios.