Máquina de votação eletrônica usando EEPROM interna do AVR

Máquina de votación electrónica que utiliza la EEPROM interna del AVR

Las máquinas de votación basadas en microcontroladores han hecho que el proceso de votación y recuento del lote de votos sea más fácil que antes. Anteriormente, los votos se marcaban en papel y luego se guardaban de forma segura en una caja en una habitación bien protegida durante días. El proceso de separar los votos y contarlos manualmente puede llevar muchos días. Pero después de encontrar la urna electrónica, los votos se pueden marcar sin utilizar papel, lo que hace que el proceso de votación sea respetuoso con el medio ambiente. Además, hace que el proceso de recuento sea más rápido y los resultados pueden anunciarse en un período de tiempo comparativamente más corto.

Debe existir un controlador dentro de la Máquina de Votación Electrónica ( EVM ) que controle el proceso y debe existir un medio de almacenamiento donde se almacenen los datos de la votación. Debería haber una unidad de ballet que se usara de tal manera que quien viniera a votar solo pudiera votar uno. También debe haber un teclado que puedan utilizar quienes deseen votar. En este proyecto, se utiliza el microcontrolador AVR para demostrar el funcionamiento de una máquina de votación más simple que puede comunicarse en serie con una PC y que puede almacenar el conteo de votos en su memoria interna.

Este proyecto trata sobre cómo podemos hacer uso de las capacidades EEPROM internas del AVR para almacenar datos para fines futuros. En este proyecto estamos fabricando una máquina de votación electrónica (EVM) utilizando la EEPROM del AVR. Al igual que en el EVM normal, hay una unidad de control y una unidad de ballet. La unidad de ballet se puede utilizar para votar solo después de habilitarla presionando una tecla en la unidad de control. Después de emitir un solo voto, la unidad de ballet se desactivará nuevamente. Cada vez que un usuario presiona una tecla, la pantalla LCD muestra por qué candidato votó.

Lo interesante es que cada vez que se emita un voto, el conteo se actualizará automáticamente en la EEPROM interna. De esta forma, una vez realizada la votación, podremos desconectar el equipo de la red eléctrica y mantenerlo seguro hasta el día del recuento. Podemos encender el tablero e incluso después de un largo período de tiempo podemos leer el número de votos emitidos para cada candidato conectando el EVM al HyperTerminal mediante comunicación serial con AVR .

Código fuente del proyecto

###


 #definir F_CPU 8000000
#incluir #incluir #incluir #incluir #incluir "lcd.h" #incluir "usart.h" vacío switch_init(vacío); led_init vacío (vacío); vacío evm_init (vacío); vacío evm_raedy_wait (vacío); anular evm_vote (nulo); char read_key_wait(nulo); void update_count (int dirección_candidato); vacío send_count_out(vacío); void reset_count(nulo); int principal (nulo) { char poll_result_mode = 1; evm_init; MENÚ: //-----------------------------------------// salida estándar = &lcd_out; lcd_claro; printf("A-ENCUESTA B-CONTADOR"); printf("nRESET COUNT-C"); //-----------------------------------------// poll_result_mode=read_key_wait; //espera hasta que se presione cualquier tecla // y leer el valor actual desde el teclado cambiar ( poll_result_mode ) { caso 0: mientras (1) { evm_raedy_wait; evm_voto; } ir a MENÚ; caso 1: enviar_cuenta_out; ir a MENÚ; caso 2: restablecer_cuenta; ir a MENÚ; } mientras (1); } switch_init vacío (vacío) { cli; DDRC &= 0xE0; PORTC = 0xFF; DDRD = 0x80; PUERTO = 0x80; saber ; } led_init vacío (vacío) { cli; DDRD = 0x80; PUERTO = 0x80; saber ; } vacío evm_init { led_init; cambiar_init; usuariot_init; lcd_init; } vacío evm_raedy_wait (vacío) { lcd_claro; printf("_______EVM______"); //============ espere hasta que la unidad evm esté habilitada por el interruptor externo ================// mientras ((PINC y 0x10)); _delay_ms(50); mientras (!(PINC y 0x10)); PUERTO &= 0x7F; //============ espere hasta que la unidad evm esté habilitada por el interruptor externo ================// lcd_claro; printf("PUEDES VOTAR AHORA"); } char read_key_wait (nulo) { botón de carácter; mientras (0x0F == (botón = (PINC y 0x0F))); //espera hasta que se presione cualquier tecla // y leer el valor actual desde el teclado _delay_ms(50); boton interruptor) { caso 0x0B: devolver 0; caso 0x07: devolver 1; caso 0x0D: devolver 2; caso 0x0E: devolver 3; }; devolver 0; } vacío evm_vote (vacío) { botón de carácter; botón=read_key_wait; //espera hasta que se presione cualquier tecla // y leer el valor actual desde el teclado boton interruptor) { caso 0: actualizar_cuenta(0); lcd_claro; printf("Votaste por A"); romper; caso 1: actualizar_cuenta(1); lcd_claro; printf("Votaste por B"); romper; caso 2: actualizar_cuenta(2); lcd_claro; printf("Votaste por C"); romper; caso 3: actualizar_cuenta(3); lcd_claro; printf("Votaste por D"); romper; }; PUERTO = 0x80; _delay_ms(3000); } void update_count (int dirección_candidato) { int dirección_base = 100; recuento interno = 0; recuento = eeprom_read_byte ((carácter sin firmar *) (dirección_base + dirección_candidato)); contar++; eeprom_write_byte ((carácter sin firmar *) (dirección_base + dirección_candidato), recuento); } nulo send_count_out(nulo) { int dirección_base = 100; int yo = 0; salida estándar = &uart_out; printf("n________________________EVM______________________"); para (yo = 0; yo < 4; yo++) printf("nCANDIDATO: %c, NO. VOTOS: %d", ('A' + i), eeprom_read_byte ((unsigned char *) (base_address + i))); } nulo reset_count(nulo) { int dirección_base = 100; int yo = 0; para (yo = 0; yo < 4; yo++) eeprom_write_byte ((carácter sin firmar *) (dirección_base + i), 0); lcd_claro; printf("RESTABLECER(OK)"); _delay_ms (2000); } ########## LCD ##########

#ifndef _LCD_H #definir _LCD_H #ifndef F_CPU #definir F_CPU 8000000 #terminara si #incluir #incluir #incluir #incluir #incluir #definir jajaja PA0 #definir rw PA1 #definir en PA2 lcd_init vacío; vacío dis_cmd(char); vacío dis_data(char); vacío lcdcmd(char); void lcddata(char); vacío lcd_clear(vacío); vacío lcd_2nd_line (vacío); vacío lcd_1st_line (vacío); void lcd_string(const char *datos); int lcd_print(char c, ARCHIVO *flujo); int lcd_scroll(const char *datos); lcd_out ARCHIVO = FDEV_SETUP_STREAM(lcd_print, NULL, _FDEV_SETUP_WRITE); char disp_beg = " "; int lcd_print(carácter c, ARCHIVO *flujo) { si('n' ==c) lcd_2nd_line; otro dis_data(c); devolver 0; } int lcd_scroll(const char *datos) { ent i; int j = 0; strcat(disp_beg, datos); para(yo = 0; yo < 14; yo++) strcat(disp_beg, " "); mientras(1) { para(i = 0;i < 16;i++) { si(!disp_beg(i + j)) devolver 0; otro; dis_data(disp_beg(i + j)); } j++; _delay_ms(500); lcd_claro; } devolver 0; } void lcd_string(const char *datos) { a(;*datos;datos++) dis_data (*datos); } vacío lcd_clear(vacío) { dis_cmd(0x01); _delay_ms(10); } vacía lcd_2nd_line (vacía) { dis_cmd(0xC0); _delay_ms(1); } vacío lcd_1st_line (vacío) { dis_cmd(0x80); _delay_ms(1); } void lcd_init // función para inicializar { DDRA=0xFF; dis_cmd(0x02); // para inicializar la pantalla LCD en modo de 4 bits. dis_cmd(0x28); //para inicializar la pantalla LCD en 2 líneas, 5X7 puntos y modo de 4 bits. dis_cmd(0x0C); dis_cmd(0x06); dis_cmd(0x80); dis_cmd(0x01); _delay_ms(500); salida estándar = &lcd_out; } void dis_cmd(char cmd_value) { char cmd_value1; cmd_valor1 = cmd_valor & 0xF0; //enmascara el mordisco inferior porque se utilizan los pines PA4-PA7. lcdcmd(cmd_valor1); //enviar a LCD cmd_valor1 = ((cmd_valor<<4) & 0xF0); //desplaza 4 bits y enmascara lcdcmd(cmd_valor1); //enviar a LCD } void dis_data(char datos_valor) { carácter_valor_datos1; valor_datos1=valor_datos&0xF0; lcddata(valor_datos1); valor_datos1=((valor_datos<<4)&0xF0); lcddata(valor_datos1); } vacío lcdcmd (char cmdout) { PUERTO=cmdout; PUERTA&=~(1< PUERTA&=~(1< PUERTO =(1< _delay_ms(1); PUERTA&=~(1< } anular datos lcd (salida de datos de caracteres) { PUERTO=salida de datos; PUERTO =(1< PUERTA&=~(1< PUERTO =(1< _delay_ms(1); PUERTA&=~(1< } #terminara si

###

Código fuente del proyecto

###


 #ifndef _USART_H
#definir _USART_H #ifndef F_CPU #definir F_CPU 8000000 #terminara si #definir USART_BAUDRATE 9600 #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#incluir #incluir #incluir anular usert_init; void usert_putch (envío de caracteres sin firmar); sin firmar int user_getch; void usert_send_string(const char* datos); int uart_print(char c, ARCHIVO *flujo); uart_out ARCHIVO = FDEV_SETUP_STREAM(uart_print, NULL, _FDEV_SETUP_WRITE); int uart_print(char c, ARCHIVO *flujo) { si (c == 'n') uart_print('r', flujo); loop_until_bit_is_set(UCSRA, UDRE); UDR = c; devolver 0; } anular user_init { UCSRB = (1 << RXEN) (1 << TXEN); //Activa el circuito de transmisión y recepción. UCSRC = (1 << URSEL) (1< //Utiliza tamaños de caracteres de 8 bits UBRRL = BAUD_PRESCALE; // Carga los 8 bits inferiores del valor de velocidad en baudios. //en el byte bajo del registro UBRR UBRRH = (BAUD_PRESCALE >> 8); // Carga los 8 bits superiores del valor de velocidad en baudios. //en el byte alto del registro UBRR salida estándar = &uart_out; } void usert_putch (envío de caracteres sin firmar) { mientras ((UCSRA & (1 << UDRE)) == 0); // No hacer nada hasta que la UDR esté lista. // para que se escriban más datos en él UDR = enviar; // envía el byte } int sin firmar usat_getch { mientras ((UCSRA & (1 << RXC)) == 0); // No hacer nada hasta que los datos se hayan recibido y estén listos para ser leídos en la UDR retorno(UDR); //devuelve el byte } void usert_send_string(const char* datos) { a(; *datos; datos++) usert_putch(*datos); } #terminara si

###

Diagramas de circuito

el circuito

Componentes del proyecto

  • ATmega16
  • LCD
  • Resistor

Vídeo del proyecto

Volver al blog

Deja un comentario

Los comentarios deben ser aprobados antes de su publicación.