0% encontró este documento útil (0 votos)
32 vistas18 páginas

Informe Micro C++

El código controla un semáforo simulado cambiando los estados de los puertos en diferentes momentos para encender las luces del semáforo de forma secuencial. Utiliza variables y condicionales para determinar el estado actual y realizar las acciones correspondientes.

Cargado por

Edinson
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
32 vistas18 páginas

Informe Micro C++

El código controla un semáforo simulado cambiando los estados de los puertos en diferentes momentos para encender las luces del semáforo de forma secuencial. Utiliza variables y condicionales para determinar el estado actual y realizar las acciones correspondientes.

Cargado por

Edinson
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

“Año del Bicentenario, de la consolidación de nuestra Independencia,

y de la conmemoración de las Heroicas Batallas de Junín y Ayacucho”

Docente:
Antonio Fiestas Ugas
Curso:
Microcontroladores
Tema:
Informe
Integrantes:
Iman Noriega Edinson
Pasco Gallo Rafael

Lima - Perú
2024-0
SEMÁFORO
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

int flag = 0;

int main(void)
{

DDRB = 0xFF;
//puerto B como salida
DDRC = 0xFF;
//puerto C como salida
PORTB = 0x00;
//apago el puerto B
PORTC = 0x00;
//apago el puerto C
while (1)
{

//primer estado
if(flag == 0){

PORTB = (1<<0); //encender el rojo


PORTC = (1<<2); //encender el verde
_delay_ms(20000);
flag = 1;
}

//segundo estado
else if(flag == 1){

PORTB = (1<<0); //encender el rojo


PORTC = (1<<1); //encender el amarillo
_delay_ms(15000);
flag = 2;
}

//tercer estado
else if(flag == 2){

PORTB = (1<<2); //encender el verde


PORTC = (1<<0); //encender el rojo
_delay_ms(20000);
flag = 3;
}

//cuarto estado
else if(flag == 3){

PORTB = (1<<1); //encender el amarillo


PORTC = (1<<0); //encender el rojo
_delay_ms(15000);
flag = 0;

}
}
}
EXPLICACIÓN DEL CÓDIGO

● flag: Esta variable se utiliza para mantener el estado actual del programa. Se inicia en
cero y se modifica según el flujo del programa.

Configuración de los puertos

● DDRB = 0xFF: Configura todas las líneas del puerto B como salidas. Esto significa
que estas líneas se usarán para enviar señales a otros componentes.
● DDRC = 0xFF: Similar al anterior, pero para el puerto C.
● PORTB = 0x00: Inicialmente apaga todas las líneas del puerto B.
● PORTC = 0x00: Igual para el puerto C.

Flujo del programa

El programa tiene un bucle infinito (while (1)) que repite el proceso constantemente.
Dentro de este bucle, se verifican los valores de flag para determinar el estado actual y se
ejecutan las acciones correspondientes.

1. Primer estado (flag == 0):


● Enciende una luz roja en el puerto B (usando (1<<0), que activa el primer bit
del puerto).
● Enciende una luz verde en el puerto C (usando (1<<2)).
● Se espera 20,000 milisegundos (20 segundos).
● Luego, se cambia flag a 1 para indicar el siguiente estado.
2. Segundo estado (flag == 1):
● Mantiene la luz roja en el puerto B y enciende una luz amarilla en el puerto C.
● Espera 15,000 milisegundos (15 segundos).
● Luego, cambia flag a 2.
3. Tercer estado (flag == 2):
● Enciende una luz verde en el puerto B y una luz roja en el puerto C.
● Espera 20,000 milisegundos.
● Luego, cambia flag a 3.
4. Cuarto estado (flag == 3):
● Enciende una luz amarilla en el puerto B y una roja en el puerto C.
● Espera 15,000 milisegundos.
● Luego, vuelve a flag = 0, reiniciando el ciclo.

CONTADOR
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

//Mis Variables
uint8_t numero = 0;

int main(void) {

DDRB = 0xFF; // puerto B


como salida
PORTB = 0x00; //
apagar todo el puerto B
numero = 0; // inicio el
contador en 0

while (1)
{
if(numero <= 9){
numero++;
PORTB = numero;
_delay_ms(1000);
}
else if (numero > 9){
numero = 0;
}
}
}

EXPLICACIÓN DEL CODIGO

Configuración de puerto y variables

● uint8_t numero = 0;: Declara una variable numero de tipo entero de 8 bits
sin signo, iniciada en 0. Esta variable será el contador.
● DDRB = 0xFF;: Configura todo el puerto B como salida, lo que significa que
puede enviar señales para controlar otros dispositivos.
● PORTB = 0x00;: Apaga todas las salidas del puerto B para asegurarse de que
estén desactivadas al comienzo.

Bucle principal

Dentro del bucle infinito (while (1)), el código sigue esta lógica:

1. Incrementar el contador: Si numero es menor o igual a 9, se incrementa


numero en 1 (numero++).
● Actualizar el puerto B: El valor de numero se asigna directamente a
PORTB, encendiendo las salidas correspondientes. Esto podría
encender LEDs u otros dispositivos conectados a esas líneas del
puerto B.
● Retraso: El código espera 1000 milisegundos (1 segundo) antes de
continuar. Esto crea un efecto de cuenta regresiva visible en el
hardware conectado.
2. Reiniciar el contador: Si numero es mayor que 9, se reinicia a 0. Esto permite
que el bucle comience de nuevo.
PRENDER UN LED CON UN PULSADOR

#include <avr/io.h>
int main(void)
{
//Entradas y Salidas
DDRB = (1 << 0); //0x00
DDRD = (0 << 0); //0x01

//PORT
PORTB = (0 << 0);
PORTD = (0 << 0);

while (1)
{
PORTB = PIND;
}
}

EXPLICACIÓN DEL CÓDIGO

Configuración de puertos

● DDRB = (1 << 0): Configura el primer pin del puerto B como salida. El resto de los
bits en DDRB se dejan sin cambios.
● DDRD = (0 << 0): Configura el primer pin del puerto D como entrada. Aquí, (0 <<
0) indica que el primer bit es cero, por lo que el pin se configura como entrada.

Inicialización de puertos

● PORTB = (0 << 0): Apaga el primer pin del puerto B (lo pone en estado bajo).
● PORTD = (0 << 0): También apaga el primer pin del puerto D. Al configurar un
puerto como entrada, esto también puede activar resistencias de pull-down
(dependiendo del hardware).

Bucle principal

El código entra en un bucle infinito (while (1)) donde se realiza lo siguiente:

● Copiar estado de PIND a PORTB: La línea PORTB = PIND; copia el valor del puerto D
al puerto B. El microcontrolador lee el valor actual del puerto D y lo escribe
directamente en el puerto B.
● Esto significa que el primer pin del puerto B se encenderá o apagará según el
estado del primer pin del puerto D.
LEER UNA FILA DE LA MATRIZ
#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>

int main(void)
{
// Definimos como salida D2 D3 D4 D5

DDRD|= (1<<DDD2)|(1<<DDD3)|(1<<DDD4)|(1<<DDD5);

DDRD&=~((1<<6)|(1<<7));

// Definimos como entrada D6 D7 B0 B1 B2 B3 B4 B5

DDRB&= ~((1<<DDB1) | (1<<DDB0));

DDRB|=(1<<2)|(1<<3)|(1<<4)|(1<<5);

char input=0;

while (1) {
PORTD|=(1<<3);

PORTB|=(1<<2);

input=((PIND&0xC0)>>6)+((PINB&0x03)<<2);

switch(input) {

case 1:
PORTD|=(1<<2);
_delay_ms(200);
break;

case 2:
PORTD|=(1<<3);
_delay_ms(200);
break;

case 4:
PORTD|=(1<<4);
_delay_ms(200);
break;

case 8:
PORTD|=(1<<5);
_delay_ms(200);
break;
}
}
return 0;
}

EXPLICACIÓN DEL CÓDIGO

● Definición de salidas:
● DDRD |= (1 << DDD2) | (1 << DDD3) | (1 << DDD4) | (1 <<
DDD5);: Configura los pines D2, D3, D4 y D5 del puerto D como salidas.
● DDRB |= (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5);: Configura
los pines B2, B3, B4 y B5 del puerto B como salidas.
● Definición de entradas:
● DDRD &= ~((1 << 6) | (1 << 7));: Configura los pines D6 y D7 del
puerto D como entradas (los bits en 0 indican entradas).
● DDRB &= ~((1 << DDB1) | (1 << DDB0));: Configura los pines B0 y
B1 del puerto B como entradas.
Bucle principal

El bucle principal (while (1)) contiene el código de control que ejecuta una acción
basada en la entrada y la salida configuradas anteriormente.

1. Inicialización de salidas:
● PORTD |= (1 << 3);: Activa el pin D3 del puerto D.
● PORTB |= (1 << 2);: Activa el pin B2 del puerto B.
2. Lectura de entradas y operación bit a bit:
● input = ((PIND & 0xC0) >> 6) + ((PINB & 0x03) << 2);: Aquí, el
código realiza una operación bit a bit para obtener valores de entrada:
● Toma los bits 6 y 7 del puerto D (máscara 0xC0) y los desplaza 6
posiciones hacia la derecha.
● Toma los bits 0 y 1 del puerto B (máscara 0x03) y los desplaza 2
posiciones hacia la izquierda.
● Los resultados se suman para obtener un valor entero input que
representa diferentes combinaciones de estos bits.
3. Control mediante switch-case:
● El código usa un bloque switch para ejecutar diferentes acciones
según el valor de input:
● case 1: Enciende el pin D2 y espera 200 milisegundos.
● case 2: Enciende el pin D3 y espera 200 milisegundos.
● case 4: Enciende el pin D4 y espera 200 milisegundos.
● case 8: Enciende el pin D5 y espera 200 milisegundos.

MOSTRAR LOS NÚMEROS EN BINARIO


#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>

// Configuración de teclas
#define FILA 4
#define COLUMNA 4

const uint8_t fila_pin[FILA] = {PD0, PD1, PD2, PD3}; // Filas en PORTD


const uint8_t columna_pin[COLUMNA] = {PB0, PB1, PB2, PB3}; // Columnas en PORTB

const char matriz_pul[FILA][COLUMNA] = {


{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

void setup();
char leer_matriz();
void prender_leds(char pulsador);

// configuración inicial
void setup() {
// filas como salidas
for (int i = 0; i < FILA; i++) {
DDRD |= (1 << fila_pin[i]); // Filas como salidas
}

// columnas como entradas con resistencias pull-up


for (int i = 0; i < COLUMNA; i++) {
DDRB &= ~(1 << columna_pin[i]); // Columnas como entradas
PORTB |= (1 << columna_pin[i]); // Activar pull-up interno
}

// Configurar los pines de PORTC como salidas para los LEDs


DDRC |= 0xFF;
}

// Leer el teclado matricial


char leer_matriz() {
for (int fila = 0; fila < FILA; fila++) {
// Apagar todas las filas
for (int i = 0; i < FILA; i++) {
PORTD &= ~(1 << fila_pin[i]);
}

// Activar solo la fila actual


PORTD |= (1 << fila_pin[fila]);
// Leer columnas
for (int col = 0; col < COLUMNA; col++) {
if (!(PINB & (1 << columna_pin[col]))) { // Verificar
_delay_ms(50); // Retardo
return matriz_pul[fila][col]; // Devolver la tecla presionada
}
}
}

return '\0';
}

// Prender LEDs dependiendo de la tecla presionada


void prender_leds(char pulsador) {
// Apagar todos los LEDs
PORTC &= ~0xFF;

// Enciende el LED correspondiente al número presionado


int valor = pulsador - '0';
PORTC |= (1 << valor); // Encender el LED
}

int main(void) {

while (1) {
char pulsador = leer_matriz(); // Leer el teclado matricial

// Si la tecla es un número (0 al 9), controlar LEDs


if (pulsador >= '0' && pulsador <= '9') {
prender_leds(pulsador); // Controlar LEDs según el número
}

_delay_ms(200); // Retardo
}

return 0;
}
EXPLICACIÓN DEL CÓDIGO

1. Teclado Matricial: Un teclado donde las teclas están dispuestas en una matriz
de 4 filas y 4 columnas. Cada tecla es identificada por su posición en la
matriz.
2. Configuración Inicial (Setup):
● Las filas del teclado (PD0, PD1, PD2, PD3) se configuran como salidas.
● Las columnas (PB0, PB1, PB2, PB3) se configuran como entradas con
resistencias pull-up para detectar teclas presionadas.
● El puerto C (usado para controlar LEDs) se configura como salida.

Funciones
1. Leer el Teclado Matricial (leer_matriz()):
● Recorre las filas para activar una a la vez y verifica si alguna columna
está activa.
● Si se detecta una tecla presionada, devuelve el valor correspondiente
de la matriz matriz_pul.
● Para evitar rebotes (ruido eléctrico), se añade un pequeño retardo
(_delay_ms).
2. Prender LEDs Según la Tecla Presionada (prender_leds(char pulsador)):
● Apaga todos los LEDs en el puerto C.
● Si el carácter presionado es un número (0 al 9), enciende el LED
correspondiente.

Bucle Principal (main())


El bucle principal realiza las siguientes acciones en un ciclo infinito:

1. Leer el Teclado:
● Llama a leer_matriz() para obtener la tecla presionada.
● Si es un número del 0 al 9, llama a prender_leds() para encender el
LED correspondiente.
2. Agregar Retardo:
● Se incluye un retardo de 200 ms para evitar lecturas rápidas y permitir
tiempo para la interacción con el hardware.
CONCLUSIONES

En los siguientes proyectos hemos aprendido a utilizar el lenguaje c++ aplicado al


microcontrolador atmega 328p

La declaración de variables es similar , pero en donde se notó gran diferencia fue en


configurar los puertos, ya que en assemble era más sencillo.

En arduino no te deja usar algunos puertos ni pines lo que me dificulta mucho estar
moviendo y ordenando los bits, preferiría que se pudiera usar el micro independiente para
poder usar sin problemas los demás puertos, considero que sería más entendible y
ordenado.

También podría gustarte