Implementação prática
Atividade 2.1
Baixe o programa “Mem_2_1.c” (listado mais abaixo). Adapte as faixas das teclas para o seu teclado. Lembrar que as teclas estão representadas pelo seu código ASCII
Implemente o hardware mostrado na imagem acima:
- Teclado com 16 teclas matricial por conversor A/D e interrupção
- Sensor de porta fechada. Utilizar circuito de um botão simples simulando um sensor de contato
- Acionamento de tranca: Saída com led indicativo e circuito para acionamento de trava elétrica. Utilizar circuito sugerido na imagem acima com acoplador ótico e acionamento por relé (permite acionamento AC ou DC).
Avaliação: Apresentar hardware e software em funcionamento
EFEITO MAGNÉTICO (TRAVA ELETROMAGNÉTICA)
Atividade 2.2
Modifique o programa da atividade 2.1 para:
- Solicitar a senha para operação de trancar a porta (utilizar a mesma senha de abertura)
- Verificar se a porta está fechada antes de acionar a tranca
Avaliação: Apresentar hardware e software em funcionamento
Fluxograma de sugestão para implementação da atividade 2.2:
Programa Mem_2_1.c
/*
* File: Mem_2_1.c
* Author: Pilger
*
* Created on 4 de Outubro de 2017, 10:17
*
* Programa cofre digital
* Rotina de leitura de 3 teclas para gerar um senha com valor entre 0 e 255
* Realiza a troca de senha
* Solicita 2 vezes a digitação de senha e testa se menor que 255
* compara so 2 valores se forem iguai e menor que 255 grava no endereço 0x00 da EEPROM
* Abertura de porta
* Solicita senha
* Senha == 255 -> troca de senha
* Senha <255 testa se senha é a mesma da eeprom
* Senha errada, mensagem de erro
* Senha correta
* destrava porta
* espera abrir
* espera fechar
* tranca a porta
*
*/
#define _XTAL_FREQ 48000000
#include <stdio.h>
#include <xc.h>
#include "C:\h\Config_PIC18F4550.h"
#include "c:\h\biblioteca_lcd_2x162_48M_XC.h"
#define tranca LATBbits.LATB7
#define sensor_porta PORTBbits.RB6
//prototipos de funções
void inicia_regs(void);
void interrupt ISR_alta_prioridade(void);
void config_int(void);
void config_int0(void);
void config_AD(void);
int conv_AD(void);
void delay_ms(int i);
int le_3_tec(unsigned char ns1);
unsigned char testa255(unsigned char ns);
void troca_senha(void);
void Eeprom_write(char addr, char data);
unsigned char Eeprom_read(unsigned char addr);
unsigned char fl_tec = 0, tec = 0;
/* fl_tec: flag que indica que chegou uma tecla
* tec: valor asc da tecla recebida
*/
void main(void) {
unsigned char buffer[16];
unsigned char senha_digitada = 0, senha_eeprom = 0;
inicia_regs();
config_int();
config_int0(); // configura as interrupções
config_AD(); // configura e inicializa o conversor AD
lcd_inicia(0x28, 0x0f, 0x06); // incializa o LCD com 4 linhas
lcd_LD_cursor(0); // Desliga o cursor
tranca = 1; // tranca inicialmente ativada
while (1) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd(" Cofre digital ");
delay_ms(2000);
senha_digitada = testa255(0);
lcd_posicao(2, 1);
sprintf(buffer, "Senha = %03d ", senha_digitada);
imprime_buffer_lcd(buffer, 15);
if (senha_digitada == 255) {
troca_senha();
} else {
senha_eeprom = Eeprom_read(0);
if (senha_digitada == senha_eeprom) {
tranca = 0; // abre tranca
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd(" Destravado ");
lcd_posicao(2, 1);
imprime_string_lcd(" Porta Fechada ");
while (!sensor_porta); //espera a porta abrir
lcd_posicao(1, 1);
imprime_string_lcd(" Porta Aberta ");
lcd_posicao(2, 1);
imprime_string_lcd("Feche p/travar ");
while (sensor_porta); // aguarda porta fechar
tranca = 1; // fecha tranca
lcd_posicao(1, 1);
imprime_string_lcd(" Cofre digital ");
lcd_posicao(2, 1);
imprime_string_lcd(" Porta Fechada ");
delay_ms(2000);
} else {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO - Senha ");
lcd_posicao(2, 1);
imprime_string_lcd(" nao confere");
delay_ms(2000);
}
}
}
}
// função de configuração do conversor A/D
void config_AD(void) {
ADCON0 = 0b00000001; /* canal AN0 selecionado <5:2> 0000
Flag GO - /DONE desligado <1> 0
Módulo conversor ligado <0> 1 */
ADCON1 = 0b00111110; /* Vref- = GND <5> 0 RA2 <5> 1
Vref+ = VDD <4> 0
pino RA0/AN0 analógico e demais digitais <3:0> 1110 */
ADCON2 = 0b10110110; /* Resultado justificado a direita <7> 1
* Tempo de Aquisição de 16 TDA <5:3> 110
* TDA = 1,33us <2:0> 110
* 48MHz/64 = 750kHz = 1,33us */
}
// função que efeuta uma conversão A/D e retorna um inteiro com o valor convertido
int conv_AD(void) {
int result_AD; // Variável local para armazenar o resultado da conv
ADCON0bits.GO = 1; // inicia a conversão
while (ADCON0bits.GO); // Aguarda a o fim da conversão
result_AD = (((int) ADRESH) << 8) | (ADRESL);
return result_AD;
}
// função que inicia os registradores I/O
void inicia_regs(void) {
// Configura todas as portas multiplexadas com o módulo conversor A/D, como I/O digital. (cap13)
ADCON1 = 0x0F;
TRISA = 0b00001101;
TRISB = 0b01000001; // define a B0 como entrada (INT0) e B6 sensor da porta
TRISD = 0x00; // define a porta D como saída - onde está o LCD
TRISE = 0x00; // define a porta E como saída - onde está o Led que indica que passou pela interrupção
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0; // zeroa todos os pinos
}
// função de interrupção de alta prioridade
void interrupt ISR_alta_prioridade(void) {
delay_ms(100); // atraso de 0,1s
// este atraso é importante para evitar pulos do teclado, pois o up roda muito rápido 48MHz
int vc;
// unsigned char buffer[16];
fl_tec = 1;
tec = 0;
vc = conv_AD();
lcd_posicao(2, 1);
if (vc > 965 && vc < 1003) tec = 47;
else if (vc > 929 && vc < 965) tec = 57;
else if (vc > 899 && vc < 929) tec = 56;
else if (vc > 865 && vc < 899) tec = 55;
else if (vc > 821 && vc < 865) tec = 120;
else if (vc > 755 && vc < 821) tec = 54;
else if (vc > 737 && vc < 775) tec = 53;
else if (vc > 665 && vc < 737) tec = 52;
else if (vc > 575 && vc < 665) tec = 45;
else if (vc > 509 && vc < 575) tec = 51;
else if (vc > 453 && vc < 509) tec = 50;
else if (vc > 369 && vc < 453) tec = 49;
else if (vc > 260 && vc < 369) tec = 43;
else if (vc > 163 && vc < 260) tec = 35;
else if (vc > 70 && vc < 163) tec = 48;
else if (vc > 20 && vc < 70) tec = 42;
// sprintf(buffer, " Conv= %04d", vc);
// imprime_buffer_lcd(buffer, 15);
INTCONbits.INT0IF = 0; // Limpa o flag de ativação da interrupção
}
// função de configuração geral de interrupções
void config_int(void) { // configurações gerais a todas as interrupçãoes
RCONbits.IPEN = 1; // Habilita interrupção com nível de prioridade. End 0x08 - alta e 0x18 - baixo
INTCONbits.GIEH = 1; // Habilita todas as interrupções de alta prioridade
INTCONbits.GIEL = 0; // Desabilita todas as interrupções de baixa prioridade
}
// função de configuração da Interrupção externa 0
void config_int0(void) { // configurações específicas a INT0
INTCONbits.INT0IE = 1; // Ativa a inerrupção externa INT0 (RB0)
INTCON2bits.INTEDG0 = 0; // Interrupção externa INT0 na borda de descida
INTCONbits.INT0IF = 0; // Limpa o flag bit da interrupção externa INT0
}
// função que gera atraso em mlisegundos
void delay_ms(int i){
for ( int x = 0; x < i; x++ ) {
__delay_ms(1);
}
}
unsigned char testa255(unsigned char ns) {
// ns = 0 escreve "senha"
// ns = 1 escreve "senha 1" ou 2 escreve "senha 2"
int pass = 999;
unsigned char fl_testa = 1;
while (fl_testa) {
pass = le_3_tec(ns);
if (pass > 255) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO");
lcd_posicao(2, 1);
imprime_string_lcd("Senha > 255");
delay_ms(2000);
} else fl_testa = 0;
}
return (char) pass;
}
/*
* Função que lê 3 num do teclado de 0 a 9
* Backspace tecla *
* OK tecla # Saída da função e retorna um num de 0 a 999
*/
int le_3_tec(unsigned char ns1) {
// ns1 = 0 escreve "senha"
// ns1 = 1 escreve "senha 1" ou 2 escreve "senha 2"
unsigned char i = 0, fl_3 = 1, num_asc[4] = {48, 48, 48, 48};
int num = 0;
unsigned char buffer[16];
lcd_posicao(1, 1);
if (ns1 != 0) sprintf(buffer, "Digite senha %d ", ns1);
else sprintf(buffer, "Digite senha ");
imprime_buffer_lcd(buffer, 15);
// imprime_string_lcd("Digite senha ");
lcd_posicao(2, 1);
imprime_string_lcd(" * <- # OK ");
imprime_buffer_lcd(buffer, 3);
while (fl_3) {
if (fl_tec) {
fl_tec = 0; // desliga flag que avisa que tecla chegou
// lcd_posicao(1, 14);
// sprintf(buffer, "%d", i+1);
// imprime_buffer_lcd(buffer, 1);
if (tec == 35) { // tec # OK
if (i == 1) {
num_asc[0] = num_asc[2];
num_asc[2] = 48; //num_asc[1]=48;
} else if (i == 2) {
num_asc[0] = num_asc[1];
num_asc[1] = num_asc[2];
num_asc[2] = 48;
}
if (i < 4) i = 4;
} else if (tec == 42) { // tec * Backspace
if (i == 1) num_asc[2] = 48;
if (i == 2) num_asc[1] = 48;
if (i == 3) num_asc[0] = 48;
if (i > 0) i--;
else i = 0;
} else if (i < 3) {
if (tec < 58 && tec > 47) { // garante que só vale teclas de 0 a 9 para registrar
num_asc[2 - i] = tec;
i++;
}
}
if (i == 4) { //se # - OK foi pressionado
fl_3 = 0;
num = (num_asc[2] - 48)*100 + (num_asc[1] - 48)*10 + (num_asc[0] - 48); // converte asc para num
}
lcd_posicao(2, 1);
if (i == 0) sprintf(buffer, " ");
if (i == 1) sprintf(buffer, "%d ", num_asc[2] - 48);
if (i == 2) sprintf(buffer, "%d%d ", num_asc[2] - 48, num_asc[1] - 48);
if (i == 3) sprintf(buffer, "%d%d%d", num_asc[2] - 48, num_asc[1] - 48, num_asc[0] - 48);
imprime_buffer_lcd(buffer, 3);
}
}
return num;
}
void troca_senha(void) {
unsigned char fl_4 = 1;
unsigned char buffer[16];
int senha1 = 0, senha2 = 0;
while (fl_4) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("Troca de senha ");
delay_ms(2000);
lcd_posicao(1, 1);
imprime_string_lcd("Digite ");
lcd_posicao(2, 1);
imprime_string_lcd("Senha 1 ");
delay_ms(1000);
senha1 = testa255(1);
lcd_posicao(2, 1);
sprintf(buffer, "Senha 1 = %03d ", senha1);
imprime_buffer_lcd(buffer, 16);
delay_ms(2000);
lcd_posicao(1, 1);
imprime_string_lcd("Digite ");
lcd_posicao(2, 1);
imprime_string_lcd("Senha 2 ");
delay_ms(1000);
senha2 = testa255(2);
lcd_posicao(2, 1);
sprintf(buffer, "Senha 2 = %03d ", senha2);
imprime_buffer_lcd(buffer, 16);
delay_ms(2000);
if (senha1 == senha2) {
if (senha1 == 255) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO senha ");
lcd_posicao(2, 1);
imprime_string_lcd(" Nao pode 255 ");
delay_ms(2000);
} else {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("Senha 1=Senha 2");
lcd_posicao(2, 1);
imprime_string_lcd("Gravando senha ");
Eeprom_write(0, senha1);
delay_ms(2000);
fl_4 = 0;
}
} else {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO de senhas ");
lcd_posicao(2, 1);
sprintf(buffer, " %03d <> %3d ", senha1, senha2);
imprime_buffer_lcd(buffer, 16);
delay_ms(2000);
}
}
}
void Eeprom_write(char addr, char data) {
char intcon_temp;
while (EECON1bits.WR); // se uma escrita estiver em andamento, aguarda
EEADR = addr; // configura o endereço inicial da escrita
EECON1bits.EEPGD = 0; // Seleciona área de mem = eeprom
EECON1bits.CFGS = 0; // Seleciona área de mem = eeprom
EECON1bits.WREN = 1; // escrita permitida (1))
EEDATA = data; // escreve no registrador EEDATA o dado a ser gravado
intcon_temp = INTCON; // Guarda o valor do registrador INTCON
INTCON = 0; // Erase INTCON e disable interrups
EECON2 = 0x55; // senha de escrita em memória
EECON2 = 0xAA;
EECON1bits.WR = 1; // habilita a escrita , volta a zero no fim da op
while (EECON1bits.WR); // aguarda o fim da escrita, pois leva 4ms
INTCON = intcon_temp; // restaura o valor do registrador INTCON
}
unsigned char Eeprom_read(unsigned char addr) {
EEADR = addr; // EEADR recebe o endereço passado para a função
EECON1bits.EEPGD = 0; // Seleciona área de mem = eeprom
EECON1bits.CFGS = 0; // Seleciona área de mem = eeprom
EECON1bits.FREE = 0; // modo de apagamento de flash não selecionada (0)
EECON1bits.WREN = 0; // escrita não permitida (0))
EECON1bits.RD = 1; // habilita opção de leitura, volta a zero no fim da op
return (EEDATA); // retorna o conteúdo lido (de EEDATA)
}
* File: Mem_2_1.c
* Author: Pilger
*
* Created on 4 de Outubro de 2017, 10:17
*
* Programa cofre digital
* Rotina de leitura de 3 teclas para gerar um senha com valor entre 0 e 255
* Realiza a troca de senha
* Solicita 2 vezes a digitação de senha e testa se menor que 255
* compara so 2 valores se forem iguai e menor que 255 grava no endereço 0x00 da EEPROM
* Abertura de porta
* Solicita senha
* Senha == 255 -> troca de senha
* Senha <255 testa se senha é a mesma da eeprom
* Senha errada, mensagem de erro
* Senha correta
* destrava porta
* espera abrir
* espera fechar
* tranca a porta
*
*/
#define _XTAL_FREQ 48000000
#include <stdio.h>
#include <xc.h>
#include "C:\h\Config_PIC18F4550.h"
#include "c:\h\biblioteca_lcd_2x162_48M_XC.h"
#define tranca LATBbits.LATB7
#define sensor_porta PORTBbits.RB6
//prototipos de funções
void inicia_regs(void);
void interrupt ISR_alta_prioridade(void);
void config_int(void);
void config_int0(void);
void config_AD(void);
int conv_AD(void);
void delay_ms(int i);
int le_3_tec(unsigned char ns1);
unsigned char testa255(unsigned char ns);
void troca_senha(void);
void Eeprom_write(char addr, char data);
unsigned char Eeprom_read(unsigned char addr);
unsigned char fl_tec = 0, tec = 0;
/* fl_tec: flag que indica que chegou uma tecla
* tec: valor asc da tecla recebida
*/
void main(void) {
unsigned char buffer[16];
unsigned char senha_digitada = 0, senha_eeprom = 0;
inicia_regs();
config_int();
config_int0(); // configura as interrupções
config_AD(); // configura e inicializa o conversor AD
lcd_inicia(0x28, 0x0f, 0x06); // incializa o LCD com 4 linhas
lcd_LD_cursor(0); // Desliga o cursor
tranca = 1; // tranca inicialmente ativada
while (1) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd(" Cofre digital ");
delay_ms(2000);
senha_digitada = testa255(0);
lcd_posicao(2, 1);
sprintf(buffer, "Senha = %03d ", senha_digitada);
imprime_buffer_lcd(buffer, 15);
if (senha_digitada == 255) {
troca_senha();
} else {
senha_eeprom = Eeprom_read(0);
if (senha_digitada == senha_eeprom) {
tranca = 0; // abre tranca
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd(" Destravado ");
lcd_posicao(2, 1);
imprime_string_lcd(" Porta Fechada ");
while (!sensor_porta); //espera a porta abrir
lcd_posicao(1, 1);
imprime_string_lcd(" Porta Aberta ");
lcd_posicao(2, 1);
imprime_string_lcd("Feche p/travar ");
while (sensor_porta); // aguarda porta fechar
tranca = 1; // fecha tranca
lcd_posicao(1, 1);
imprime_string_lcd(" Cofre digital ");
lcd_posicao(2, 1);
imprime_string_lcd(" Porta Fechada ");
delay_ms(2000);
} else {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO - Senha ");
lcd_posicao(2, 1);
imprime_string_lcd(" nao confere");
delay_ms(2000);
}
}
}
}
// função de configuração do conversor A/D
void config_AD(void) {
ADCON0 = 0b00000001; /* canal AN0 selecionado <5:2> 0000
Flag GO - /DONE desligado <1> 0
Módulo conversor ligado <0> 1 */
ADCON1 = 0b00111110; /* Vref- = GND <5> 0 RA2 <5> 1
Vref+ = VDD <4> 0
pino RA0/AN0 analógico e demais digitais <3:0> 1110 */
ADCON2 = 0b10110110; /* Resultado justificado a direita <7> 1
* Tempo de Aquisição de 16 TDA <5:3> 110
* TDA = 1,33us <2:0> 110
* 48MHz/64 = 750kHz = 1,33us */
}
// função que efeuta uma conversão A/D e retorna um inteiro com o valor convertido
int conv_AD(void) {
int result_AD; // Variável local para armazenar o resultado da conv
ADCON0bits.GO = 1; // inicia a conversão
while (ADCON0bits.GO); // Aguarda a o fim da conversão
result_AD = (((int) ADRESH) << 8) | (ADRESL);
return result_AD;
}
// função que inicia os registradores I/O
void inicia_regs(void) {
// Configura todas as portas multiplexadas com o módulo conversor A/D, como I/O digital. (cap13)
ADCON1 = 0x0F;
TRISA = 0b00001101;
TRISB = 0b01000001; // define a B0 como entrada (INT0) e B6 sensor da porta
TRISD = 0x00; // define a porta D como saída - onde está o LCD
TRISE = 0x00; // define a porta E como saída - onde está o Led que indica que passou pela interrupção
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0; // zeroa todos os pinos
}
// função de interrupção de alta prioridade
void interrupt ISR_alta_prioridade(void) {
delay_ms(100); // atraso de 0,1s
// este atraso é importante para evitar pulos do teclado, pois o up roda muito rápido 48MHz
int vc;
// unsigned char buffer[16];
fl_tec = 1;
tec = 0;
vc = conv_AD();
lcd_posicao(2, 1);
if (vc > 965 && vc < 1003) tec = 47;
else if (vc > 929 && vc < 965) tec = 57;
else if (vc > 899 && vc < 929) tec = 56;
else if (vc > 865 && vc < 899) tec = 55;
else if (vc > 821 && vc < 865) tec = 120;
else if (vc > 755 && vc < 821) tec = 54;
else if (vc > 737 && vc < 775) tec = 53;
else if (vc > 665 && vc < 737) tec = 52;
else if (vc > 575 && vc < 665) tec = 45;
else if (vc > 509 && vc < 575) tec = 51;
else if (vc > 453 && vc < 509) tec = 50;
else if (vc > 369 && vc < 453) tec = 49;
else if (vc > 260 && vc < 369) tec = 43;
else if (vc > 163 && vc < 260) tec = 35;
else if (vc > 70 && vc < 163) tec = 48;
else if (vc > 20 && vc < 70) tec = 42;
// sprintf(buffer, " Conv= %04d", vc);
// imprime_buffer_lcd(buffer, 15);
INTCONbits.INT0IF = 0; // Limpa o flag de ativação da interrupção
}
// função de configuração geral de interrupções
void config_int(void) { // configurações gerais a todas as interrupçãoes
RCONbits.IPEN = 1; // Habilita interrupção com nível de prioridade. End 0x08 - alta e 0x18 - baixo
INTCONbits.GIEH = 1; // Habilita todas as interrupções de alta prioridade
INTCONbits.GIEL = 0; // Desabilita todas as interrupções de baixa prioridade
}
// função de configuração da Interrupção externa 0
void config_int0(void) { // configurações específicas a INT0
INTCONbits.INT0IE = 1; // Ativa a inerrupção externa INT0 (RB0)
INTCON2bits.INTEDG0 = 0; // Interrupção externa INT0 na borda de descida
INTCONbits.INT0IF = 0; // Limpa o flag bit da interrupção externa INT0
}
// função que gera atraso em mlisegundos
void delay_ms(int i){
for ( int x = 0; x < i; x++ ) {
__delay_ms(1);
}
}
unsigned char testa255(unsigned char ns) {
// ns = 0 escreve "senha"
// ns = 1 escreve "senha 1" ou 2 escreve "senha 2"
int pass = 999;
unsigned char fl_testa = 1;
while (fl_testa) {
pass = le_3_tec(ns);
if (pass > 255) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO");
lcd_posicao(2, 1);
imprime_string_lcd("Senha > 255");
delay_ms(2000);
} else fl_testa = 0;
}
return (char) pass;
}
/*
* Função que lê 3 num do teclado de 0 a 9
* Backspace tecla *
* OK tecla # Saída da função e retorna um num de 0 a 999
*/
int le_3_tec(unsigned char ns1) {
// ns1 = 0 escreve "senha"
// ns1 = 1 escreve "senha 1" ou 2 escreve "senha 2"
unsigned char i = 0, fl_3 = 1, num_asc[4] = {48, 48, 48, 48};
int num = 0;
unsigned char buffer[16];
lcd_posicao(1, 1);
if (ns1 != 0) sprintf(buffer, "Digite senha %d ", ns1);
else sprintf(buffer, "Digite senha ");
imprime_buffer_lcd(buffer, 15);
// imprime_string_lcd("Digite senha ");
lcd_posicao(2, 1);
imprime_string_lcd(" * <- # OK ");
imprime_buffer_lcd(buffer, 3);
while (fl_3) {
if (fl_tec) {
fl_tec = 0; // desliga flag que avisa que tecla chegou
// lcd_posicao(1, 14);
// sprintf(buffer, "%d", i+1);
// imprime_buffer_lcd(buffer, 1);
if (tec == 35) { // tec # OK
if (i == 1) {
num_asc[0] = num_asc[2];
num_asc[2] = 48; //num_asc[1]=48;
} else if (i == 2) {
num_asc[0] = num_asc[1];
num_asc[1] = num_asc[2];
num_asc[2] = 48;
}
if (i < 4) i = 4;
} else if (tec == 42) { // tec * Backspace
if (i == 1) num_asc[2] = 48;
if (i == 2) num_asc[1] = 48;
if (i == 3) num_asc[0] = 48;
if (i > 0) i--;
else i = 0;
} else if (i < 3) {
if (tec < 58 && tec > 47) { // garante que só vale teclas de 0 a 9 para registrar
num_asc[2 - i] = tec;
i++;
}
}
if (i == 4) { //se # - OK foi pressionado
fl_3 = 0;
num = (num_asc[2] - 48)*100 + (num_asc[1] - 48)*10 + (num_asc[0] - 48); // converte asc para num
}
lcd_posicao(2, 1);
if (i == 0) sprintf(buffer, " ");
if (i == 1) sprintf(buffer, "%d ", num_asc[2] - 48);
if (i == 2) sprintf(buffer, "%d%d ", num_asc[2] - 48, num_asc[1] - 48);
if (i == 3) sprintf(buffer, "%d%d%d", num_asc[2] - 48, num_asc[1] - 48, num_asc[0] - 48);
imprime_buffer_lcd(buffer, 3);
}
}
return num;
}
void troca_senha(void) {
unsigned char fl_4 = 1;
unsigned char buffer[16];
int senha1 = 0, senha2 = 0;
while (fl_4) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("Troca de senha ");
delay_ms(2000);
lcd_posicao(1, 1);
imprime_string_lcd("Digite ");
lcd_posicao(2, 1);
imprime_string_lcd("Senha 1 ");
delay_ms(1000);
senha1 = testa255(1);
lcd_posicao(2, 1);
sprintf(buffer, "Senha 1 = %03d ", senha1);
imprime_buffer_lcd(buffer, 16);
delay_ms(2000);
lcd_posicao(1, 1);
imprime_string_lcd("Digite ");
lcd_posicao(2, 1);
imprime_string_lcd("Senha 2 ");
delay_ms(1000);
senha2 = testa255(2);
lcd_posicao(2, 1);
sprintf(buffer, "Senha 2 = %03d ", senha2);
imprime_buffer_lcd(buffer, 16);
delay_ms(2000);
if (senha1 == senha2) {
if (senha1 == 255) {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO senha ");
lcd_posicao(2, 1);
imprime_string_lcd(" Nao pode 255 ");
delay_ms(2000);
} else {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("Senha 1=Senha 2");
lcd_posicao(2, 1);
imprime_string_lcd("Gravando senha ");
Eeprom_write(0, senha1);
delay_ms(2000);
fl_4 = 0;
}
} else {
lcd_limpa_tela();
lcd_posicao(1, 1);
imprime_string_lcd("ERRO de senhas ");
lcd_posicao(2, 1);
sprintf(buffer, " %03d <> %3d ", senha1, senha2);
imprime_buffer_lcd(buffer, 16);
delay_ms(2000);
}
}
}
void Eeprom_write(char addr, char data) {
char intcon_temp;
while (EECON1bits.WR); // se uma escrita estiver em andamento, aguarda
EEADR = addr; // configura o endereço inicial da escrita
EECON1bits.EEPGD = 0; // Seleciona área de mem = eeprom
EECON1bits.CFGS = 0; // Seleciona área de mem = eeprom
EECON1bits.WREN = 1; // escrita permitida (1))
EEDATA = data; // escreve no registrador EEDATA o dado a ser gravado
intcon_temp = INTCON; // Guarda o valor do registrador INTCON
INTCON = 0; // Erase INTCON e disable interrups
EECON2 = 0x55; // senha de escrita em memória
EECON2 = 0xAA;
EECON1bits.WR = 1; // habilita a escrita , volta a zero no fim da op
while (EECON1bits.WR); // aguarda o fim da escrita, pois leva 4ms
INTCON = intcon_temp; // restaura o valor do registrador INTCON
}
unsigned char Eeprom_read(unsigned char addr) {
EEADR = addr; // EEADR recebe o endereço passado para a função
EECON1bits.EEPGD = 0; // Seleciona área de mem = eeprom
EECON1bits.CFGS = 0; // Seleciona área de mem = eeprom
EECON1bits.FREE = 0; // modo de apagamento de flash não selecionada (0)
EECON1bits.WREN = 0; // escrita não permitida (0))
EECON1bits.RD = 1; // habilita opção de leitura, volta a zero no fim da op
return (EEDATA); // retorna o conteúdo lido (de EEDATA)
}
Nenhum comentário:
Postar um comentário