0% encontró este documento útil (0 votos)
59 vistas5 páginas

Practica 3 (S8)

Este programa controla un contador ascendente/descendente en dos displays de 7 segmentos utilizando dos botones. Cuando el contador alcanza 50, se activa un relay y se enciende un LED por un tiempo. El programa fue modificado para mostrar el estado del relay en un tercer display y los estados de los botones en LEDs.

Cargado por

Rafael nuñez
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)
59 vistas5 páginas

Practica 3 (S8)

Este programa controla un contador ascendente/descendente en dos displays de 7 segmentos utilizando dos botones. Cuando el contador alcanza 50, se activa un relay y se enciende un LED por un tiempo. El programa fue modificado para mostrar el estado del relay en un tercer display y los estados de los botones en LEDs.

Cargado por

Rafael nuñez
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

Fernando Rivas - A00099636 - 2021-07-07

PRÁCTICA 3

Actividad 1:

Analizar la lógica de funcionamiento del programa presentado, compilarlo utilizando el IDE AtmelStudio, y
verificar que se cumplen las funciones enunciadas. Este programa lee el estado de PC1, PC0. Según el estado
en el estado de los pines PC1 y PC0, se ejecutan las acciones que se indican en la tabla siguiente:

PC1 PC0 Operación


0 0 Apagar Displays
0 1 Visualizar conteo descendente
1 0 Visualizar conteo ascendente
1 1 Detener conteo

Cuando la cuenta llega al valor 50, se detiene el conteo por un momento y se activa el Relay durante
el tiempo de parada.

Programa Página
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h> Cargar librerias estándares:
- Avr/io.h = registros del MCU y otros…
#define D0_ON PORTA &= ~(1<<6);
#define D1_ON PORTA &= ~(1<<7);
-
Útil/delay.h = macro para generar delay en ms. 6
#define DISPLAY_OFF PORTA |= (3<<6);
#define RELAY_ON PORTD |= (1<<7);
#define RELAY_OFF PORTD &= ~(1<<7); Definir macros para escritura salida
#define LED_ON PORTD |= (1<<0);
#define LED_OFF PORTD &= ~(1<<0);
unsigned char hex2dec(unsigned char byte); void
setupPorts(void);// configuración de puertos
unsigned char readSW(void);//lectura de interruptores en PC1 y PC0 22
void display(unsigned char c);//presenta contador BCD en dos displays (D1 y D0)
unsigned char digito[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; 26
Arreglo de mapeo de binario a 7 segmentos.
char last = 0x00;
Variable no utilizada???… 7
int main(void) Funcion main(): punto de entrada 7
PORTB = 0;
Limpiar PORTB (display 7 segmentos)
setupPorts(); char
x = 0x00, temp; Inicializar puertos
Declarar variables: x(inicializada en 0), temp (para bucles)
while(1)
{
if(!readSW())
{ Primer caso: PC = 00 -> apagar display
DISPLAY_OFF; continue;
}
if(readSW()==3)
{
display(hex2dec(x)); Segundo caso: PC = 11 -> detener conteo
continue;
}
display(hex2dec(x));
if(x == 0x32)
{ 6,12,9,15,
for(temp=0;temp<20;temp++)
{ Caso especial: detener el Contador en 50, abrir relay,
RELAY_ON; LED_ON;
display(hex2dec(x));
esperar un tiempo, y continuar conteo
}
RELAY_OFF;
LED_OFF;
}
if(readSW()==01)
{ x++; Tercer caso: PC = 10 -> Conteo ascendente
if(x>99)
x = 0; }
else if (readSW()==02)
Fernando Rivas - A00099636 - 2021-07-07

{ x--;
if(x==255)
x = 99;
Ultimo caso: PC=01 -> Conteo descendente
}
}
}

void display(unsigned char c)


{
for(int i =0;i<10;i++)
{
DISPLAY_OFF; Funcion auxiliar: visualizar y multiplexar un numero
PORTB = digito[c&0x0F];
D0_ON;
(codificado BCD) en el par de display 7-segmento.
_delay_ms(10); 14
DISPLAY_OFF;
PORTB = digito[c>>4];
D1_ON;
_delay_ms(10);
}
}
void setupPorts(void)
{ Funcion de setup: Configurar las direcciones y pullup de
DDRA = 0xFF;
DDRB = 0xFF; los puertos utilizados.
DDRC = 0x00; 18
DDRD |= 0x81;
PORTC = 0x03;
}
unsigned char readSW(void)
{
unsigned char car; car
= PINC&0x03; switch
(car) Funcion auxiliar: convierte la entrada de los botones
{ case 0x03: (invertida por los pullup) a su respectiva entrada invertida.
return 0x00;
case 0x02:
return 0x01; Se puede simplificar con complemento + mascara 11
case 0x01:
return 0x02;
case 0x00:
return 0x3;
default: return 0xFF;
}
}

unsigned char hex2dec(unsigned char byte)//Convierte un byte hex a decimal pack bcd
{
unsigned char d1, d0, x; Funcion auxiliar: convierte un numero de binario normal a codificación en BCD (2
x = byte / 10; d0 = byte numeros BCD en 8 bits).
% 10; d1 = x%10; byte = 16
d1<<4|d0;
return byte; Podría simplificarse a la expresión “return byte+6*(byte/10)”, pero perdería la
} capacidad de expansión si se desearan más dígitos.
Fernando Rivas - A00099636 - 2021-07-07

SW1

Actividad 2:

Actividad 2:
Una vez realizada la actividad 1, se requiere modificar el programa para agregar las siguientes
funcionalidades: El display conectado al Puerto A mediante el IC 7448 vidualiza el valor cero (0) cuando el
Relay RL1 está desactivado y un uno (1) cuando RL1 se activa. Los LEDs se utilizan para indicar el estado de
los interruptores SW1 y SW2 ( LED encendido = SW cerrado).
Fernando Rivas - A00099636 - 2021-07-07

Página siguiente: código del programa (Probado en mismo circuito, con algunas de las optimizaciones
discutidas en la primera tabla)
Fernando Rivas - A00099636 - 2021-07-07
/*
* practica3_contador_up_down.c
* Tiene dos botones (izquierda y derecha):
* - Cuando se presiona el de la izquierda, el contador incrementa.
* - Cuando se presiona el de la derecha, el contador decrementa.
* - Cuando se precionan ambos, el contador se queda igual.
* - Si no se presiona nada, el display se apaga.
*
* El relay se enciende momentaneamente
* cuando el contador este en 50.
*
* VERSION MODIFICADA PARA TENER FUNCIONES EXTRA:
* - El display en PORTA visualiza 0 si el relay
* esta desactivado, y visualiza 1 si el relay se activa.
* - Los LED se usan para indicar estado de SW1 y SW2.
*
* Created: 2021-07-01 [Link] PM
* Author : User
* Version optmimizada
*/

#define F_CPU 1000000UL


#include <avr/io.h>
#include <util/delay.h>

#define D0_ON PORTA &= ~(1<<6)


#define D1_ON PORTA &= ~(1<<7)
#define DISPLAY_OFF PORTA |= (3<<6)
#define RELAY_ON PORTD |= (1<<7)
#define RELAY_OFF PORTD &= ~(1<<7)
#define LED_ON PORTD |= (1<<0)
#define LED_OFF PORTD &= ~(1<<0)
#define RELAY_7SEG_ON PORTA |= (1<<0)
#define RELAY_7SEG_OFF PORTA &= ~(1<<0)

unsigned char digito[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

void setupPorts();
unsigned char getCode();
unsigned char hex2dec(unsigned char byte);
void display(unsigned char c);

int main(void)
{
setupPorts();
char x = 0, temp;
while (1)
{
if (getCode() == 0) { // No display
DISPLAY_OFF;
continue;
}
if (getCode() == 3) { // Dont change counter
display(hex2dec(x));
continue;
}

display(hex2dec(x));

if (x == 50) { // On t=50, open relay


RELAY_ON;
LED_ON;
RELAY_7SEG_ON; // Modificacion #1: mostrar 1 en 7 seg cuando relay se encienda.
for (temp = 0; temp < 20; ++temp) {
display(hex2dec(x));
}
RELAY_OFF;
LED_OFF;
RELAY_7SEG_OFF; // Modificacion #1: y apagar cuando relay se apague.
}

if (getCode() == 1) {
x++;
if (x > 99) x = 0;
}
else if (getCode() == 2) {
x--;
if (x == 0xFF) x = 99;
}
}
}

void setupPorts() {
DDRA = 0xFF; // Todo salida
DDRB = 0xFF; // Todo salida
DDRC = 0x00; // Todo entrada
DDRD = 0x81; // Salida ultimo y primero.
PORTC = 0x03; // Activar pullup en PC0 y PC1.
}

unsigned char getCode() {


char out = ~PINC & 0x03;
// Modificacion #2: visualizar estados de SW1-SW2
// en LEDs de PA5-PA4
// Se enmascara solo la parte deseada de PORTA,
// y se aplica OR con la entrada en PINC.
//
// (Mas complicado que con un IF, pero
// sirve para demostrar el uso de
// las operaciones bit por bit)
PORTA = (PORTA & ~(3 << 4)) | (out << 4);
return out;
}

unsigned char hex2dec(unsigned char byte) {


return byte + 6 * (byte / 10);
}

void display(unsigned char c) {


for (char i = 0; i < 10; i++) {
DISPLAY_OFF;
PORTB = digito[c & 0x0F];
D0_ON;
_delay_ms(10);
DISPLAY_OFF;
PORTB = digito[c >> 4];
D1_ON;
_delay_ms(10);
}
}

También podría gustarte