martes, 16 de agosto de 2022

Proyecto con lenguaje C compilador CCS micro: PIC16F1936. Cerradura digital con clave. Parte #2

 Proyecto Cerradura digital con clave.


Introduccion

La idea de este proyecto es desarrollar las habilidades necesarias tanto en programación como diseño de circuitos para enfrentar un proyecto útil y real. Vamos a tropezar con las dificultades típicas de un proyecto de mediano nivel donde tendremos que conocer muy bien un lenguaje de programación (CCS) y una familia de microcontroladores (PIC) así como la electrónica necesaria para hacerlo funcionar todo junto. Además, se requieren habilidades para esquematizar, diagramar y hacer diseño de PCB a fin de que se fabrica un sistema capas de ser comercializado y tenga la garantía del conocimiento de su funcionamiento.

Con el fin de probar la seguridad del sistema se buscará la manera de vulnerarlo en todas las formas posibles y así ir corrigiendo fallos de seguridad en la programación y el diseño.

Este sistema se convertirá luego en la base de un control de acceso capaz de manejar niveles de usuarios y horarios, almacenar información y asegurar su integridad, encriptación y fiabilidad.

Requisitos previos.
  • Tener conocimientos de electronica
  • Arquitectura de microcontroladores PIC
  • Lenguaje de programacion C y compilador CCS

Componentes esenciales  
Una de las partes mas importantes es el microcontrolador a usar.
En este proyecto se usara el microcontrolador PIC16F1936
Características:
  • 14KB de memoria flash para programación
  • RAM de 512KB
  • EEPROM de 256KB
  • Velocidad: 20MHz
  • 25 puertos de entrada/salida,
  • 11 canales de ADC de 10 bits,
  • 5 Timers (4 de 8 bit, 1 de 16 bit)
  • 2 comparadores
  • Interfaz: UART/USART, I2C, SPI
  • Voltaje de alimentación: 1.8V ~ 5.5V
  • Encapsulado: DIP-28
  • Montaje THT
Display LCD 2X16 estandar cualquier color.


Teclado 4X4

Como se puede observar estas son los tres componentes indispensables que tienes que tener para poder empezar con este proyecto.

Iniciando la programacion

A continuacion dejo una animacion con la simulacion que debes realizar en proteus.




El firmware se hira desarrollando paso a paso con el fin de ilustrar como es el proceso de escribir un codigo para una aplicacion que involucra perifericos en lenguaje C y compilado usando el compilador CCS.

Version 0.01


#include <16F1936.h>

#device ADC=10


#FUSES NOWDT, XT, PUT, NOMCLR, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, BORV25 


#use delay(crystal=20MHZ)

#use fast_io (B)


//comandos de control para el lcd

#define Lcd_Clr        0b00000001

#define On_Cur         0b00001110

#define On_Cur_On      0b00001111

#define Off_Cur        0b00001100

#define Shif_Cur_Righ  0b00010100

#define Shif_Cur_Left  0b00010000

#define Shif_Viz_Righ  0b00011100

#define Shif_Viz_Left  0b00011000

#define Lcd_Normal     0b00000110


#define LCD_RS_PIN PIN_C1

#define LCD_RW_PIN PIN_C2

#define LCD_ENABLE_PIN PIN_C3

#define LCD_DATA4 PIN_C4

#define LCD_DATA5 PIN_C5

#define LCD_DATA6 PIN_C6

#define LCD_DATA7 PIN_C7

#include <lcd.c>

//**************************************************

//Rutina que lee el teclado hexadesimal devuelve un valor ascci

int8   KeyScan(){

int8   k,j,dt=0;

         k=0b11101111;

        for(j=0;j<4;j++){

        output_b(k);        

        delay_ms(1);

        switch (input_b()){

            case  0xE7: dt='1'; break;

            case  0xEB: dt='2'; break;

            case  0xED: dt='3'; break;

            case  0xEE: dt='A'; break;

            case  0xDB: dt='5'; break;

            case  0xD7: dt='6'; break;

            case  0xDD: dt='4'; break;

            case  0xDE: dt='B'; break;

            case  0xB7: dt='7'; break;

            case  0xBB: dt='8'; break;

            case  0xBD: dt='9'; break;

            case  0xBE: dt='C'; break;        

            case  0x77: dt='*'; break;            

            case  0x7B: dt='0'; break;            

            case  0x7D: dt='#'; break;             

            case  0x7E: dt='D'; break;

        }

         if(dt!=0){break;}

         k<<=1;

        }

         delay_ms(100);

         return dt;

}

//**************************************************

//Esta rutina muestra los datos leidos del teclado en el display

void ReadClave(){

int8 j;

char dato;

     lcd_gotoxy(1,1);

     printf(lcd_putc,"Digite su clave");

     lcd_gotoxy(8,2);

     lcd_send_byte(0,On_Cur_On);  


    for(j=0;j<6;j++){

    dato=KeyScan();    

    if(dato>='0' & dato<='9'){lcd_putc(dato);}

    while(dato==KeyScan());

    

    }



}

//**************************************************

//Rutina principal

void main() {

char dato;

    PORT_B_PULLUPS(0xff);

    set_tris_b(0b00001111);

    output_b(0);

    

    lcd_init(); 

    lcd_gotoxy(1,1);

    printf(lcd_putc,"Inicie con A");


    while(1){

    if(KeyScan()=='A'){

    ReadClave();

    }

    }   

}

//**************************************************

Actualizacion del codigo.  18/08/2022

Ahora hay una contraseña fija la cual se compara con la ingresada y el micro da una respuesta acorde a una comparacion entre la contraseña guardada y la ingresada.

Tambien agregare comentarios a cada una de las sentencias, funciones y bucles para que no solo dios sepa que fue lo que se hizo si no nosotros tambien.

//******************************************************

#include <16F1936.h>

#device ADC=10


#FUSES NOWDT, XT, PUT, NOMCLR, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, BORV25 


#use delay(crystal=20MHZ)

#use fast_io (B)


//comandos de control para el lcd

#define Lcd_Clr        0b00000001

#define On_Cur         0b00001110

#define On_Cur_On      0b00001111

#define Off_Cur        0b00001100

#define Shif_Cur_Righ  0b00010100

#define Shif_Cur_Left  0b00010000

#define Shif_Viz_Righ  0b00011100

#define Shif_Viz_Left  0b00011000

#define Lcd_Normal     0b00000110


#define LCD_RS_PIN PIN_C1

#define LCD_RW_PIN PIN_C2

#define LCD_ENABLE_PIN PIN_C3

#define LCD_DATA4 PIN_C4

#define LCD_DATA5 PIN_C5

#define LCD_DATA6 PIN_C6

#define LCD_DATA7 PIN_C7


#include <lcd.c>

#include <string.h>


#define num  6


//Array que forman strings de caracteres

char s1[num+1];         //aca se almacena la contraseña ingresada

char s2[]="123456";     //contraseña interna


//**************************************************

//Rutina que lee el teclado hexadesimal devuelve un valor ascci

int8   KeyScan(){

int8   k,j,dt=0;

         k=0b11101111;

        for(j=0;j<4;j++){

        output_b(k);        

        delay_us(100);

        switch (input_b()){

            case  0xE7: dt='1'; break;

            case  0xEB: dt='2'; break;

            case  0xED: dt='3'; break;

            case  0xEE: dt='A'; break;

            case  0xDB: dt='5'; break;

            case  0xD7: dt='6'; break;

            case  0xDD: dt='4'; break;

            case  0xDE: dt='B'; break;

            case  0xB7: dt='7'; break;

            case  0xBB: dt='8'; break;

            case  0xBD: dt='9'; break;

            case  0xBE: dt='C'; break;        

            case  0x77: dt='*'; break;            

            case  0x7B: dt='0'; break;            

            case  0x7D: dt='#'; break;             

            case  0x7E: dt='D'; break;

        }

         if(dt!=0){break;}

         k<<=1;

        }

         delay_ms(1);

         return dt;

}

//**************************************************

//Rutina que lee la contraseña ingresada

//Esta se almacena en s1

void ReadClave(){

int8 j=0;

char dato;

     lcd_gotoxy(1,1);

     printf(lcd_putc,"Digite su clave");

     lcd_gotoxy(6,2);

     lcd_send_byte(0,On_Cur_On);  


    while(j<num){ //<< numero de digitos de la contraseña

    dato=KeyScan();    

    if(dato>='0' & dato<='9'){lcd_putc('*'); s1[j]=dato; j++;}

    while(dato==KeyScan());    

    }

    s1[j]=0;

    lcd_send_byte(0,Off_Cur);


}

//**************************************************

//Funcion principal, este configura el funcionamiento del micro

void main() {

char dato;

    PORT_B_PULLUPS(0xff); //activamos las resistencias en alto internas del puerto

    set_tris_b(0b00001111);//configuramos el puerto para la lectura del teclado

    output_b(0);    //iniciamos el puerto

    lcd_init();     //inicio del LCD

    lcd_gotoxy(1,1);//Posicionando el cursor

    printf(lcd_putc,"Inicie con A");//mensaje de usuario

//Este es el bucle central y se encaga de llamar las rutinas de lectura

//del teclado y hacer la comparacion de la contraseña ingresada con la guardada

//dando una respuesta adecuada

    while(1){

    if(KeyScan()=='A'){

    ReadClave();

    lcd_send_byte(0,Lcd_Clr);       

    if(!strcmp(s1,s2)){printf(lcd_putc,"Correcto"); }else{printf(lcd_putc,"Mal");}    

    }

    }   

}

//**************************************************

Espera a que cargue la animacion con el fin de ver la simulacion.



Click en la imagen para descargar codigo y simulacion