✅ Programacion de Sistemas Embebidos
✅ Uso de lenguaje C en sistemas embebidos
✅ Compiladores, depuradores y ambientes de desarrollo
para sistemas embebidos
✅ Gestión de memoria en ambientes con pocos recursos
computacionales
✅ Patrón de diseño máquina de estado
2. 2
Objetivos:
En este Capítulo veremos:
• Uso de lenguaje C en sistemas embebidos
• Compiladores, depuradores y ambientes de desarrollo
para sistemas embebidos
• Gestión de memoria en ambientes con pocos recursos
computacionales
• Patrón de diseño: máquina de estado
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
5. 2.1.- Uso de lenguaje C en
sistemas embebidos
5
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
6. 6
C Program Structure
http://tpcg.io/3Ty4QPSistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• Los comentarios de una sola línea comienzan con // y se detienen al final de la línea.
Para más de una línea se comienza con / * y termina con * /.
• int main () es la función principal donde comienza la ejecución del programa.
• Retrun 0; Termina la función main () y hace que devuelva el valor 0 al proceso de
llamada.
• stdio.h es "standard input-output header" (cabecera estándar E/S), es el archivo de
cabecera que contiene las definiciones de la biblioteca estándar del lenguaje.
11. 11
Tipos de variables de C
http://tpcg.io/73XWiVSistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
Una declaración de variable proporciona seguridad al compilador de que existe una
variable con el tipo y nombre dados para que el compilador proceda a una compilación
adicional sin necesidad de detalles completos sobre la variable.
12. 12
Tipos de variables de C
https://www.tutorialspoint.com/cprogramming/c_variables.htm
El mismo concepto se aplica a la declaración de función en la que se proporciona un
nombre de función en el momento de su declaración y su definición real se puede dar en
cualquier otro lugar.
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
15. 15
C Constants
http://tpcg.io/p8YVAu http://tpcg.io/PnBPfK
The #define Preprocessor The const Keyword
Note that it is a good programming practice to define constants in CAPITALS.
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
16. 16
Storage Classes in C
http://tpcg.io/kZFxpW
The static Storage Class
La clase de almacenamiento estático le indica al compilador que mantenga una variable
local en existencia durante la vida útil del programa en lugar de crearla y destruirla cada
vez que entra y sale del alcance.
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
31. 31
C Infinite Loop
https://www.tutorialspoint.com/cprogramming/c_loops.htmSistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
//Arduino
int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
//pinMode(led_green, OUTPUT);
}
void loop() {
//instrucciones
}
33. 33
C while loop
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
}
void loop() {
int i=0;
while (i < 200) {
// do something repetitive 200 times
digitalWrite(led_red, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_green, HIGH);
delay(100);//ms
digitalWrite(led_red, LOW);
digitalWrite(led_yellow, LOW);
digitalWrite(led_green, LOW);
delay(100);//ms
i++;
}
}
https://www.arduino.cc/reference/en/language/structure/control-structure/while/
35. 35
C for loop
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
https://www.arduino.cc/reference/en/language/structure/control-structure/for/
int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
}
void loop() {
int x = 1;
for (int i = 0; i > -1; i = i + x) {
analogWrite(led_green, i);
if (i == 255) {
x = -1; // switch direction at peak
}
delay(2);
}
}
37. 37
C do...while loop
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
}
void loop() {
int x = 0;
do {
analogWrite(led_green, x);
delay(5); // wait for sensors to stabilize
x+=1;
} while (x < 255);
}
https://www.arduino.cc/reference/en/language/structure/control-structure/while/
40. int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
// variables will change:
int buttonState = 0;
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
}
void loop() {
// read the state of the pushbutton value:
VOID:
buttonState = digitalRead(push);
int x = 1;
if (buttonState == HIGH){
digitalWrite(led_red, HIGH);
goto FOR;
}else{
digitalWrite(led_red, LOW);
}
goto VOID;
FOR: for (int i = 0; i > -1; i = i + x) {
analogWrite(led_green, i);
if (i == 255) {
x = -1; // switch direction at peak
}
delay(2);
}
}
40
Loop Control Statements
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
goto statement
https://www.arduino.cc/en/tutorial/button
42. 42
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
// variables will change:
int buttonState = 0;
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
}
void loop() {
buttonState = digitalRead(push);
if (buttonState == HIGH){
digitalWrite(led_red, HIGH);
}else{
digitalWrite(led_red, LOW);
}
}
https://www.arduino.cc/reference/en/language/structure/control-structure/else/
C if statement
44. int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
// variables will change:
int buttonState = 0;
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
}
void loop() {
// read the state of the pushbutton value:
VOID:
buttonState = digitalRead(push);
int x = 1;
if (buttonState == HIGH){
digitalWrite(led_red, HIGH);
goto FOR;
}else{
digitalWrite(led_red, LOW);
}
goto VOID;
FOR: for (int i = 0; i > -1; i = i + x) {
analogWrite(led_green, i);
if (i == 255) {
x = -1; // switch direction at peak
}
delay(2);
}
}
44
C if...else statement
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
https://www.arduino.cc/en/tutorial/button
46. 46
C switch statement
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
// variables will change:
int buttonState = 0;
int incomingByte = 0; // for incoming serial data
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
switch (incomingByte) {
case 49:
// statements
digitalWrite(led_green, HIGH);
break;
case 50:
// statements
digitalWrite(led_green, LOW);
break;
default:
// statements
break;
}
}
}
https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/
https://www.arduino.cc/reference/en/language/functions/communication/serial/read
50. 50
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
// variables will change:
int buttonState = 0; int incomingByte = 0; // for incoming serial data
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
int i = 6; int j = 3; int k;
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
switch (incomingByte) {
case 49:
// statements
digitalWrite(led_green, HIGH);
k = myMultiplyFunction(i, j); // k now contains 6
Serial.println(k); break;
case 50:
// statements
digitalWrite(led_green, LOW);
k = myDivisionFunction(i, j); // k now contains 6
Serial.println(k); break;
default:
// statements
break;
}
}
}
int myMultiplyFunction(int x, int y){
int result; result = x * y;
return result;
}
int myDivisionFunction(int x, int y){
int result; result = x / y;
return result;
}
https://www.arduino.cc/en/Reference/FunctionDeclaration
C Functions
53. 53
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
// variables will change:
void incrementa(byte &);
// Declaramos que existe la función "incrementa" que tiene un parámetro de
tipo "referencia a byte".
//Como sólo la estamos declarando no es necesario indicar el nombre del
parámetro.
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
/////
Serial.begin(9600);
}
void loop() {
byte b = 1;
Serial.print(F("Valor de b antes de incrementar: "));
Serial.println(b);
incrementa(b); // Invocamos a la función que hemos declarado al principio.
Serial.print(F("Valor de b despues de incrementar: "));
Serial.println(b);
delay(1000);
}
// A continuación implementamos la función "incrementa" que habíamos
declarado al principio.
void incrementa(byte &b) {
b++;
}
https://forum.arduino.cc/index.php?topic=560223.0
C Pointers
55. 55
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
int myArray[10];
// variables will change:
int buttonState = 0; int incomingByte = 0; // for incoming serial data
int i = 0;
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
myArray[i]=incomingByte;
i=i+1;
}
if (i>9){
for(int j = 0; j < sizeof(myArray); j++)
{
Serial.print(myArray[j]);
}
i=0;
}
}
https://www.arduino.cc/reference/en/language/variables/data-types/array/
C Arrays
57. 57
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_green = 3; // the green LED is connected to Pin 2
int push =4;//input
int myArray[10][2];
// variables will change:
int buttonState = 0; int incomingByte = 0; // for incoming serial data
int i = 0;
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_green, OUTPUT);
pinMode(push, INPUT);
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
myArray[i][0]=i;
myArray[i][1]=incomingByte;
i=i+1;
}
if (i>9){
for(int j = 0; j < 10; j++)
{
Serial.print(myArray[j][0]);
Serial.println(myArray[j][1]);
}
i=0;
}
}
https://www.arduino.cc/reference/en/language/variables/data-types/array/
Multi-dimensional arrays
58. 2.2.- Compiladores, depuradores
y ambientes de desarrollo para
sistemas embebidos
58
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
64. 64
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
Ejemplo while loop
int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
}
void loop() {
int x = 0;
do {
analogWrite(led_green, x);
delay(5); // wait for sensors to stabilize
x+=1;
} while (x < 255);
}
65. 65
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
Ejemplo for loop
int led_red = 0; // the red LED is connected to Pin 0
int led_yellow = 1; // the yellow LED is connected to Pin 1
int led_green = 3; // the green LED is connected to Pin 2
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
}
void loop() {
int x = 1;
for (int i = 0; i > -1; i = i + x) {
analogWrite(led_green, i);
if (i == 255) {
x = -1; // switch direction at peak
}
delay(2);
}
}
73. 73
ATmega32U4 – PWM:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• RISC - Conjunto Reducido de Instrucciones para computador.
• AVR es una familia de Microcontroladores desarrollado desde 1996 por Atmel, adquirido por Microchip
Technology in 2016.
PWM
74. 74
Código PWM:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int boton = 6;
int led = 8;
int PWMout=3;
int AnalogOUT=2;
void setup() {
pinMode(boton, INPUT);
pinMode(led,OUTPUT);
pinMode(PWMout,OUTPUT);
pinMode(AnalogOUT,OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(led, 1);
Serial.println("encendidion");
delay(500);
digitalWrite(led, 0);
Serial.println("apagadon");
delay(500);
for (int i = 0; i <= 255; i++) {
analogWrite(PWMout, i);
analogWrite(AnalogOUT, i);
delay(10);
}
}
https://www.tinkercad.com/things/aXc9Yn8tVyr-glorious-habbi-
migelo/editel?sharecode=EzUd90gvwd18uOZrJr51vVLm9Ty87kE41-
Tr3CE5H9Q
75. 75
Proteus vs TinkerCad (PWM):
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
76. 76
Código ADC:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int boton = 6;
int led = 8;
int PWMout=3;
int AnalogOUT=2;
int analogPin = A3;
int val = 0;
void setup() {
pinMode(boton, INPUT);
pinMode(led,OUTPUT);
pinMode(PWMout,OUTPUT);
pinMode(AnalogOUT,OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(led, 0);
if (digitalRead(boton)==HIGH){
digitalWrite(led, 1);
Serial.print("Valor ADC: ");
val = analogRead(analogPin); //
read the input pin
Serial.println(val); // debug
value
delay(500);
}
}
https://www.tinkercad.com/things/aXc9Yn8tVyr-glorious-habbi-
migelo/editel?sharecode=EzUd90gvwd18uOZrJr51vVLm9Ty87kE41-
Tr3CE5H9Q
77. 77
Trama Comunicación Serial:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• Sensor networks for agriculture based on Cyber-Physical System
• Health Monitoring System Using ECG Signal based on Cyber-Physical System
• structural health monitoring using inertial sensors based on Cyber-Physical System
78. 78
Trama Comunicación Serial:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• Tsunami early warning using inertial sensors based on Cyber-Physical System
81. 81
End Device
Serial Communication:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int boton = 6;int led = 8;int analogPin = A3;
int val = 0;int myArray[10];int incomingByte = 0;
int band = 0;int i=0;int checksum=0;
int ID=49;// ID 0X31
void setup() {
pinMode(led, OUTPUT);
pinMode(boton, INPUT);
pinMode(analogPin, INPUT);
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
if (Serial.available() > 0) {
incomingByte = Serial.read();
if(incomingByte==36 and band==0){
band=1;
}else if(band==1){
myArray[i]=incomingByte; i+=1;
if(i>3){
band =2;i=0;
checksum=(((0x24 xor myArray[0])xor myArray[1])xor myArray[2]);
if (myArray[3]==checksum){//Checksum
Serial.println("Trama OK");
}else{
Serial.println("Trama Error");
}
}
}
// validar ID y Tarea
if (myArray[0]==ID and band==2){
band=0;
if(myArray[1]==65){//Read
Serial.print("$");//36 Start
Serial.print("5");//5 ID-C
Serial.print("A");//ID Task
val=analogRead(analogPin)>>2;//10 a 8 bits
//Serial.print(val);//sensor
Serial.print( (char) val);
Serial.println("@");//
}
}
}
}
https://www.tinkercad.com/things/aXc9Yn8tVyr-glorious-habbi-
migelo/editel?sharecode=EzUd90gvwd18uOZrJr51vVLm9Ty87kE41-
Tr3CE5H9Q
82. 82
AVR-GCC:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• Pasos para quemar el AVR desde IDE Arduino
• El IDE verifica el código y comprueba que la sintaxis del código es correcta en C y C++
• Luego pasa al compilador avr-gcc, que convierte el código en C++ en instrucciones que
entiende el microcontrolador.
• Después el código es combinado con las librerías estándar de Arduino, que son las que
ofrecen las funciones básicas como digitalWrite() o Serial.println().
• El resultado es un fichero hex que contiene los bytes que van a ser grabado en la memoria
flash de Arduino.
• Finalmente el fichero es cargado en la placa Arduino transmitiéndolo sobre el USB o la
conexión serie si hay un bootloader cargado o sino con un hardware externo (programador).
• Qué es el AVR - GNU Compiler Collection (AVR-GCC) ?
• Versión de GCC solo para arquitecturas AVR
• Compilador que usa el IDE de Arduino para convertir el sketch en C++ a un fichero binario
(.hex) que es el que se carga en la flash del MCU.
• Para entornos de bajos recursos computacionales
• Aplicaciones en tiempo real
• Restricciones temporales estrictas
• NO directamente desde el entorno Arduino
• AVR Studio 4 o bien un editor de texto + toolchain
• Contar los ciclos de reloj en cada instrucción
https://aprendiendoarduino.wordpress.com/tag/avr-
libc/#:~:text=avr%2Dgcc%20es%20el%20compilador,del%20MCU%20y%20que%20ejecuta.
83. 83
VGCC vs IDE ARDUINO:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
int led_red = 8;
int led_yellow = 9;
int led_green = 10;
void setup() {
// set up all the LEDs as OUTPUT
pinMode(led_red, OUTPUT);
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
}
void loop() {
digitalWrite(led_red, HIGH);
digitalWrite(led_yellow, LOW);
digitalWrite(led_green, LOW);
delay(1000);//ms
digitalWrite(led_red, LOW);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_green, LOW);
delay(1000);//ms
digitalWrite(led_red, LOW);
digitalWrite(led_yellow, LOW);
digitalWrite(led_green, HIGH);
delay(1000);//ms
}
91. 91
FLASH MEMORY:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "String
cero123456789012345678";
const char string_1[] PROGMEM = "String uno";
const char string_2[] PROGMEM = "String dos";
const char string_3[] PROGMEM = "String tres";
const char string_4[] PROGMEM = "String cuatro";
const char string_5[] PROGMEM = "String cinco";
const char *const string_table[] PROGMEM = {string_0, string_1,
string_2, string_3, string_4, string_5};
char buffer[30];
// make sure this is large enough for the largest string it must hold
void setup() {
Serial.begin(9600);
while (!Serial);
// wait for serial port to connect. Needed for native USB
Serial.println("OK");
}
void loop() {
for (int i = 0; i < 6; i++) {
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[i])));
// Necessary casts and dereferencing, just copy.
Serial.println(buffer);
delay(500);
}
}
const dataType variableName[] PROGMEM = {data0,
data1, data3…};
const PROGMEM dataType variableName[] = {};
// or this one
https://www.arduino.cc/reference/en/language/variables/utilities/progmem/
• Usar la tabla de cadenas en la memoria
del programa requiere de funciones
especiales para recuperar los datos.
• La función strcpy_P copia una cadena
desde el espacio del programa a una
cadena en RAM ("buffer").
• Asegúrese de que su cadena de
recepción en RAM sea lo
suficientemente grande como para
contener lo que se está recuperando del
espacio del programa.
97. 97
.hex & Programmer:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• Pasos para usar AVR-GCC
• Conectar el Arduino y quemarlo
• sudo make FNAME=codigo1
Cuando hay
problemas en
programar en
microcontrolador.
98. 98
.hex & Programmer:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• Pasos para usar AVR-GCC
• Conectar el Arduino y quemarlo
• sudo make FNAME=codigo1
100. 100
pwm1:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main(void)
{
DDRD |= (1 << 6); //pin 6 del Arduino como salida
DDRB |= (1 << 3); //pin 11 del Arduino como salida
TCCR2A |= 0b10000001; //bit 7 y 6 para determinar si pwm es invertido o
//no, 10 es no invertido y 11 es invertido y bit 0 y
//1 para determinar medio ciclo pwm o completo
TCCR2B |= 0b00000001;
TCCR0A |= 0b10000001; //bit 7 y 6 para determinar si pwm es invertido o
//no, 10 es no invertido y 11 es invertido y bit 0 y
//1 para determinar medio ciclo pwm o completo
TCCR0B |= 0b00000001;
/*EL REGISTRO TTCR#$*/
OCR0A = 0; //valor inicial de pwm para el pin 0A
OCR2A = 255; //valor inicial de pwm para el pin 2A
while(1)
{
do{
OCR0A++;
OCR2A = OCR2A - 1;
_delay_ms (10L);
}while(OCR0A <255);
_delay_ms (2000L);
do{
OCR2A++;
OCR0A = OCR0A - 1;
_delay_ms (10L);
}while(OCR0A >0);
_delay_ms (3000L);
}
return 0;
}
• Crear el archivo
• sudo nano pwm1.c
124. 124
.hex & Programmer:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
• Pasos para usar AVR-GCC
• Conectar el Arduino y quemarlo
• sudo make FNAME=codigo1
125. 2.4.- Patrón de diseño: máquina
de estado
125
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
126. 126
Maquina de Estados
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
Memoria de
Estados
(SRAM)
Decodificador
de Salidas
(FLASH)
Decodificador
Estado
Siguiente
(FLASH)
Entradas
Estado
Siguiente
Estado
Actual Salidas
Maquina modelo Mealy
Memoria de
Estados
(SRAM)
Decodificador
de Salidas
(FLASH)
Decodificador
Estado
Siguiente
(FLASH)
Entradas
Estado
Siguiente
Estado
Actual Salidas
Maquina modelo Moore
127. 127
Diseño de Estados
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
El Diagrama de Estados es una herramienta gráfica que describe las transiciones paso a
paso de una MSS.
Se representa como un arreglo de círculos (óvalos) interconectados con segmentos con
flechas. Cada círculo (óvalo) representa un estado (Estado Presente) de la MSS y las
flechas representan los flancos de Reloj que hacen que la MSS cambie a otro estado
(Estado Siguiente).
Estados: Representan situaciones
diferentes de una secuencia en el
tiempo.
Segmentos: Representan la
transición de estado en estado.
Solo se ejecutan en el instante del
flanco positivo de Reloj.
128. 128
Diseño de Maquinas de Estado
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
Entender los requerimientos del problema
y bajo que condiciones se generan las
salidas (Mealy o Moore).
Diagrama de Estados primitivo (suele tener
estados redundantes), con un estado inicial
al cual se debe regresar al encender la
fuente de poder, al presionar Reset o bajo
condiciones de las entradas.
Tabla de estados primitivo, para identificar y
eliminar estados redundantes. Redibujar el
Diagrama de Estados simplificado.
Asignar códigos/ID de estados y realizar la
implementación
131. 131
Respuesta:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
//pines
int puerta = 8;
//Codigo de estados
const int estado_a=0;//inicio
const int estado_b=1;//ingreso digito1
const int estado_c=2;//ingreso digito 2
const int estado_d=3;//ingreso digito3
const int estado_e=4;//ingreso digito 4
const int clave0='1';//digito 1de la clave
const int clave1='2';//digito 1de la clave
const int clave2='3';//digito 1de la clave
const int clave3='4';//digito 1de la clave
//variables
int incomingByte = 0;
int estado;
int estado_actual =0;//estado a
int estado_siguiente=0;
//inicializar
void setup() {
pinMode(puerta,OUTPUT);
Serial.begin(9600);// opens serial port,sets data rate to 9600 bps
}
//funciones
void DecodificadorEstadoSiguiente(){
switch (estado_actual){
case estado_a:
if(incomingByte==clave0){
estado_siguiente=estado_b;
Serial.println("Estado Siguinte:b");
}
break;
case estado_b:
if(incomingByte==clave1){
estado_siguiente=estado_c;
Serial.println("Estado Siguinte:c");
}
break;
case estado_c:
if(incomingByte==clave2){
estado_siguiente=estado_d;
Serial.println("Estado Siguinte:d");
}
break;
case estado_d:
if(incomingByte==clave3){
estado_siguiente=estado_e;
Serial.println("Estado Siguinte:e");
}
break;
case estado_e:
estado_siguiente=estado_a;
Serial.println("EstadoSiguinte:a");
break;
default:
estado_siguiente=estado_a;
break;
}
}
void MemoriaEstado(){
if(estado_siguiente!=estado_actual){
estado_actual=estado_siguiente;
Serial.println("Estadoactual = Siguiente");
}
}
void DecodificadorSalida(){
if(estado_actual==estado_e){
Serial.println("Abrir puerta");
digitalWrite(puerta,HIGH);
delay(2000);
}else{
digitalWrite(puerta,LOW);
}
}
//main
void loop(){
if (Serial.available()> 0) {
incomingByte = Serial.read();
Serial.print("Digito ingresado:");
Serial.println(incomingByte);
}
DecodificadorSalida();//Deco.Salida
DecodificadorEstadoSiguiente();//Deco.Est. Sig.
MemoriaEstado();//Mem.Estado
}
Clave:
1234
https://www.tinkercad.com/things/aXc9Yn8tVyr-glorious-habbi-
migelo/editel?sharecode=EzUd90gvwd18uOZrJr51vVLm9Ty87kE41-Tr3CE5H9Q
132. 132
Ejemplo
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
Programar una máquina secuencial que debe detectar una clave correcta de 4 dígitos (1-
2-3-4), cada vez que se detecta la clave se debe generar un pulso en la salida Puerta. La
validación de la clave debe realizarse luego de ingresados 4 dígitos, si la clave es incorrecta
se empezará a contar los Errores. Si el número de intentos fallidos de ingreso de la clave
es mayor a 3, se deberá activar la salida Alarma la cual solo se deberá apagar al ingresar la
clave correcta.
Sistema de
Seguridad
Dígito Puerta
Alarma
133. 133
Respuesta:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
//pines
int puerta = 8;int alarma=7;
//Codigo de estados
const int estado_a=0;//ingreso digito 1
const int estado_b=1;//ingreso digito2
const int estado_c=2;//ingreso digito 3
const int estado_d=3;//ingreso digito4
const int clave0='1';//digito 1de la clave
const int clave1='2';//digito 1de la clave
const int clave2='3';//digito 1de la clave
const int clave3='4';//digito 1de la clave
//variables
int incomingByte = 0;
int estado;
int estado_actual =0;//estado a
int estado_siguiente=0;
int digitos[4];
int errores=0;
//inicializar
void setup() {
pinMode(puerta,OUTPUT);
Serial.begin(9600);// opens serial port,sets data rate to 9600 bps
}
//funciones
void DecodificadorEstadoSiguiente(){
switch (estado_actual){
case estado_a:
digitos[0]=incomingByte;
estado_siguiente=estado_b;
Serial.println("EstadoSiguinte:b");
break;
case estado_b:
digitos[1]=incomingByte;
estado_siguiente=estado_c;
Serial.println("EstadoSiguinte:c");
break;
case estado_c:
digitos[2]=incomingByte;
estado_siguiente=estado_d;
Serial.println("EstadoSiguinte:d");
break;
case estado_d:
digitos[3]=incomingByte;
estado_siguiente=estado_a;
Serial.println("EstadoSiguinte:a");
break;
default:
estado_siguiente=estado_a;
break;
}
}
void MemoriaEstado(){
if(estado_siguiente!=estado_actual){
estado_actual=estado_siguiente;
Serial.println("Estadoactual = Siguiente");
}
}
void DecodificadorSalida(){
if(estado_actual==estado_d){
if((digitos[0]==clave0)&& (digitos[1]==clave1)&& (digitos[2]==clave2)&& (digitos[3]==clave3)){
errores=0;
Serial.println("Abrir puerta");
digitalWrite(puerta,HIGH);
delay(2000);
digitalWrite(puerta,LOW);
}else{
Serial.println("Error");
errores+=1;
}
if(errores>3){
digitalWrite(alarma,HIGH);
Serial.println("AlarmaON");
}else{
digitalWrite(alarma,LOW);
Serial.println("AlarmaOFF");
}
}
}
//main
void loop(){
if (Serial.available()> 0) {
incomingByte = Serial.read();
Serial.print("Digito ingresado:");
Serial.println(incomingByte);
DecodificadorEstadoSiguiente();//Deco. Est.Sig.
DecodificadorSalida();//Deco.Salida
MemoriaEstado();//Mem.Estado
}
}
Clave:
1234
https://www.tinkercad.com/things/aXc9Yn8tVyr-glorious-habbi-
migelo/editel?sharecode=EzUd90gvwd18uOZrJr51vVLm9Ty87kE41-Tr3CE5H9Q
134. Sensor1
End Device
Sensor1
End Device
Sensor3
End Device
Sensor4
End Device
Actuator
(On/Off o PWM)
End Device
Coordinator
134
Tarea
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
135. 135
Tarea 1
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
ActuadorByte On/Off
Del anterior sistema ciberfísico, implementar el actuador utilizando conceptos de
maquina secuencial. La trama de comunicación que deberá recibir y ser validada es la
siguiente:
Start byte ID byte Byte Task Byte Data Byte Checksum
0x24 ($)
0x31 (1) – ED [Sens.1]
0x32 (2) – ED [Sens.2]
0x33 (3) – ED [Sens.3]
0x34 (4) – ED [Sens.4]
0x35 (5) – ED [Act.]
0x36 (6) – C
0x41 (A) – Read
0x42 (B) – Configure SPS
0x43 (C) – Sleep Mode
0x44 (D) – wake up mode
0x00
.
0x30 (0)
.
0xFF ()
XOR (Start byte, ID
byte, byte Task, byte
Data)
136. 136
Tarea 2
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
Del anterior sistema ciberfísico, implementar uno de los sensores utilizando conceptos de
maquina secuencial. La trama de comunicación que deberá recibir y ser validada es la
siguiente:
Start byte ID byte Byte Task Byte Data Byte Checksum
0x24 ($)
0x31 (1) – ED [Sens.1]
0x32 (2) – ED [Sens.2]
0x33 (3) – ED [Sens.3]
0x34 (4) – ED [Sens.4]
0x35 (5) – ED [Act.]
0x36 (6) – C
0x41 (A) – Read
0x42 (B) – Configure SPS
0x43 (C) – Sleep Mode
0x44 (D) – wake up mode
0x00
.
0x30 (0)
.
0xFF ()
XOR (Start byte, ID
byte, byte Task, byte
Data)
SensorByte
Trama
Sensor
Luego de hacer la lectura del sensor, este End Device deberá responder con la misma
trama agregando el dato leído en Byte data.
137. 137
Referencias:• Introducción al lenguaje C y herramientas GNU
• The C programming Language, Kernighan, Ritchie, 1988
• TCPL_C1
• TCPL_C2
• TCPL_C3
• TCPL_C4
• Introduction to Embedded Systems, Jiménez, Palomera, Couvertier, 2014
• IES_C5
• Gestión de memoria
• The C programming Language, Kernighan, Ritchie, 1988
• TCPL_C5
• Computer Systems, 3ra Edición, Bryant, O'Hallaron, 2017
• CS: 9.8-9.11
• Gestión de memoria y patrón de diseño máquina de estado
• Embedded Systems Design 3ra Edición, Peter Marwedel, 2018
• ESD: 2.4.1-2
• Making Embedded Systems, Elecia White, 2011
• MES: 5
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
138. 138
Recursos:
• Algunos contenidos vistos en clase como presentaciones,
ejercicios resueltos, entre otros. Serán almacenados y
compartidos en el siguiente Drive:
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110