O pedido de sugestões já rendeu esse artigo, que foi pedido pelo usuário amilcar, sugerindo um teclado USB com algumas teclas e terra comum, então segue o projeto.

Depois de pesquisar um pouco criei o projeto a seguir com o PIC18F2550, que pode facilmente ser substituído por outros PIC’s com USB.

O código se divide em duas partes a primeira é a leitura de um teclado matricial de 4×4 e a segunda é a estruturação do arquivo de descrição do USB para que o PIC seja “entendido” como um teclado USB.

A primeira parte foi utilizado um trecho do código do artigo [PIC] Leitura de Teclado Matricial 3×4, ampliando para 4×4.

A segunda foi de um trecho de um código que eu tinha guardado a algum tempo onde é configurado a USB para um Teclado HID.

Duvidas, postem nos comentários.

Usar no Proteus 8.0 ou superior.


Fazer o download dos arquivos do firmware e simulação:

Esse conteúdo é exclusivo para usuários registrados. Favor login.
[PIC][MIKROC][PROTEUS] Teclado USB

Fazer o download do PDF dos códigos de teclas para teclado USB:

KeyCodes for USB Keyboard


Segue o código:

[sections] [section title=”Esquema Elétrico”]
Esquema Teclado USB
Esquema Teclado USB
[/section]

[section title="Código Fonte - Principal"]

/*
               DATEK Tecnologia Eletrônica Ltda.

********************************************************************************
 PROGRAMA EXEMPLO: Mostrar como criar um teclado USB reduzido.
         OBJETIVO: Aprender como criar um teclado USB reduzido.
            AUTOR: Fabio Mulero.[fabio@datek.com.br]
********************************************************************************
 MICROCONTROLADOR: PIC18F2550.

 PLACA DE DESENVOLVIMENTO: SIMULAÇÃO NO PROTEUS

 SOFTWARE: MikroC PRO for PIC Versão: 6.0.1

********************************************************************************
*/
//### DEFINES ##################################################################
#define SIM          1
#define NAO          0
#define LIGA         SIM
#define DESLIGA      NAO
#define VERDADEIRO   SIM
#define FALSO        NAO

//--- DECLARAÇÃO DAS CONSTANTES DO TECLADO -------------------------------------
#define TECLA_A                    0X04
#define TECLA_B                    0X05
#define TECLA_C                    0X06
#define TECLA_D                    0X07
#define TECLA_E                    0X08
#define TECLA_F                    0X09
#define TECLA_G                    0X0A
#define TECLA_PGUP                 0X4B
#define TECLA_PGDW                 0X4E
#define TECLA_SETA_DIR             0X4F
#define TECLA_SETA_ESQ             0X50
#define TECLA_SETA_CIMA            0X52
#define TECLA_SETA_BAIXO           0X51
#define TECLA_ENTER                0X28
#define TECLA_ESPACO               0X2C
// MODIFIERS
#define TECLA_ALT                  0XE2

//### ALIAS ####################################################################
//--- CONFIGURAçãO DOS PINOS DO TECLADO ----------------------------------------
sbit TECLADO_LINHA1     at RC0_bit;
sbit TECLADO_LINHA2     at RC1_bit;
sbit TECLADO_LINHA3     at RC2_bit;
sbit TECLADO_LINHA4     at RC6_bit;

sbit TECLADO_COLUNA1    at LATB0_bit;
sbit TECLADO_COLUNA2    at LATB1_bit;
sbit TECLADO_COLUNA3    at LATB2_bit;
sbit TECLADO_COLUNA4    at LATB3_bit;

sbit TECLADO_LINHA1_Direction    at TRISC0_bit;
sbit TECLADO_LINHA2_Direction    at TRISC1_bit;
sbit TECLADO_LINHA3_Direction    at TRISC2_bit;
sbit TECLADO_LINHA4_Direction    at TRISC6_bit;

sbit TECLADO_COLUNA1_Direction   at TRISB0_bit;
sbit TECLADO_COLUNA2_Direction   at TRISB1_bit;
sbit TECLADO_COLUNA3_Direction   at TRISB2_bit;
sbit TECLADO_COLUNA4_Direction   at TRISB3_bit;

//==============================================================================
unsigned char readbuff[64] absolute 0x500;      //readbuffer should be in RAM  (MCU specific)
unsigned char writebuff[64] absolute 0x540;     //writebuffer should be in RAM (MCU specific)

//### PROTOTIPOS DE FUNÇÃO #####################################################
void KeyboardRead(unsigned char *Tecla,unsigned char *Modificador);
void readKeyboard();
void Init_main();

//### INTERRUPÇÃO ##############################################################
void interrupt()
{
     USB_Interrupt_Proc();        // USB servicing inside the interrupt
}

//### MAIN #####################################################################
void main()
{
   //Initialize ports
   Init_main();

   while(1)//MAIN LOOP
   {
      readKeyboard();
   }
}

//#######################  K E Y B O A R D   ###################################
void readKeyboard()
{
   unsigned char modifier=0;
   unsigned char keycode;

   //Some Keyboard Buttons
   KeyboardRead(&keycode,&modifier);

   writebuff[0]=0x01;
   writebuff[1]=modifier;              //modifiers[ALT,SHIFT,CONTROL,ETC]
   writebuff[2]=0x00;                  //reserved;
   writebuff[3]=keycode;               // KEYCODES
   writebuff[4]=0;
   writebuff[5]=0;
   writebuff[6]=0;
   writebuff[7]=0;
   writebuff[8]=0;

   while(!HID_Write(writebuff,64));
}

//##############################################################################
void Init_main(){
   TECLADO_LINHA1_Direction = 1;
   TECLADO_LINHA2_Direction = 1;
   TECLADO_LINHA3_Direction = 1;
   TECLADO_LINHA4_Direction = 1;

   TECLADO_COLUNA1_Direction = 0;
   TECLADO_COLUNA2_Direction = 0;
   TECLADO_COLUNA3_Direction = 0;
   TECLADO_COLUNA4_Direction = 0;
   RBPU_bit = 1; // habilita pull-up interno.
   HID_Enable(readbuff,writebuff);
}

// LER MATRIZ DE TECLAS
void KeyboardRead(unsigned char *Tecla,unsigned char *Modificador)
{
   *Tecla=0;
   *Modificador=0;

   TECLADO_COLUNA1 =  TECLADO_COLUNA2 =  TECLADO_COLUNA3 = TECLADO_COLUNA4 = LIGA;
   TECLADO_COLUNA1 =  DESLIGA;
   Delay_1ms();
   if(TECLADO_LINHA1 == DESLIGA)
   {
      *Tecla=TECLA_A;
   }
   if(TECLADO_LINHA2 == DESLIGA)
   {
      *Tecla=TECLA_E;
   }
   if(TECLADO_LINHA3 == DESLIGA)
   {
      *Tecla=TECLA_PGDW;
   }
   if(TECLADO_LINHA4 == DESLIGA)
   {
      *Tecla=TECLA_SETA_BAIXO;
   }
   TECLADO_COLUNA1 =  LIGA;
   TECLADO_COLUNA2 =  DESLIGA;
   Delay_1ms();
   if(TECLADO_LINHA1 == DESLIGA)
   {
      *Tecla=TECLA_B;
   }
   if(TECLADO_LINHA2 == DESLIGA)
   {
      *Tecla=TECLA_F;
   }
   if(TECLADO_LINHA3 == DESLIGA)
   {
      *Tecla=TECLA_SETA_DIR;
   }
   if(TECLADO_LINHA4 == DESLIGA)
   {
      *Tecla=TECLA_ENTER;
   }
   TECLADO_COLUNA2 =  LIGA;
   TECLADO_COLUNA3 =  DESLIGA;
   Delay_1ms();
   if(TECLADO_LINHA1 == DESLIGA)
   {
      *Tecla=TECLA_C;
   }
   if(TECLADO_LINHA2 == DESLIGA)
   {
      *Tecla=TECLA_G;
   }
   if(TECLADO_LINHA3 == DESLIGA)
   {
      *Tecla=TECLA_SETA_ESQ;
   }
   if(TECLADO_LINHA4 == DESLIGA)
   {
      *Tecla=TECLA_ESPACO;
   }
   TECLADO_COLUNA3 =  LIGA;
   TECLADO_COLUNA4 =  DESLIGA;
   Delay_1ms();
   if(TECLADO_LINHA1 == DESLIGA)
   {
      *Tecla=TECLA_D;
   }
   if(TECLADO_LINHA2 == DESLIGA)
   {
      *Tecla=TECLA_PGUP;
   }
   if(TECLADO_LINHA3 == DESLIGA)
   {
      *Tecla=TECLA_SETA_CIMA;
   }
   if(TECLADO_LINHA4 == DESLIGA)
   {
      *Modificador=TECLA_ALT;
   }
   TECLADO_COLUNA4 =  LIGA;
}




[/section]

[section title="Código Fonte - Descritivo USB"]




const unsigned int USB_VENDOR_ID = 0x0314;
const unsigned int USB_PRODUCT_ID = 0x2201;
const char USB_SELF_POWER = 0x80;            // Self powered 0xC0,  0x80 bus powered
const char USB_MAX_POWER = 50;               // Bus power required in units of 2 mA
const char HID_INPUT_REPORT_BYTES = 64;
const char HID_OUTPUT_REPORT_BYTES = 64;
const char USB_TRANSFER_TYPE = 0x03;         //0x03 Interrupt
const char EP_IN_INTERVAL = 1;
const char EP_OUT_INTERVAL = 1;

const char USB_INTERRUPT = 1;
const char USB_HID_EP = 1;
const char USB_HID_RPT_SIZE = 115;

/* Device Descriptor */
const struct {
    char bLength;               // bLength         - Descriptor size in bytes (12h)
    char bDescriptorType;       // bDescriptorType - The constant DEVICE (01h)
    unsigned int bcdUSB;         // bcdU SB          - USB specification release number (BCD)
    char bDeviceClass;          // bDeviceClass    - Class Code
    char bDeviceSubClass;       // bDeviceSubClass - Subclass code
    char bDeviceProtocol;       // bDeviceProtocol - Protocol code
    char bMaxPacketSize0;       // bMaxPacketSize0 - Maximum packet size for endpoint 0
    unsigned int idVendor;      // idVendor        - Vendor ID
    unsigned int idProduct;     // idProduct       - Product ID
    unsigned int bcdDevice;     // bcdDevice       - Device release number (BCD)
    char iManufacturer;         // iManufacturer   - Index of string descriptor for the manufacturer
    char iProduct;              // iProduct        - Index of string descriptor for the product.
    char iSerialNumber;         // iSerialNumber   - Index of string descriptor for the serial number.
    char bNumConfigurations;    // bNumConfigurations - Number of possible configurations
} device_dsc = {
      0x12,                   // bLength
      0x01,                   // bDescriptorType
      0x0200,                 // bcdUSB
      0x00,                   // bDeviceClass
      0x00,                   // bDeviceSubClass
      0x00,                   // bDeviceProtocol
      8,                      // bMaxPacketSize0
      USB_VENDOR_ID,          // idVendor
      USB_PRODUCT_ID,         // idProduct
      0x0001,                 // bcdDevice
      0x01,                   // iManufacturer
      0x02,                   // iProduct
      0x00,                   // iSerialNumber
      0x01                    // bNumConfigurations
  };

/* Configuration 1 Descriptor */
const char configDescriptor1[]= {
    // Configuration Descriptor
    0x09,                   // bLength             - Descriptor size in bytes
    0x02,                   // bDescriptorType     - The constant CONFIGURATION (02h)
    0x29,0x00,              // wTotalLength        - The number of bytes in the configuration descriptor and all of its subordinate descriptors
    1,                      // bNumInterfaces      - Number of interfaces in the configuration
    1,                      // bConfigurationValue - Identifier for Set Configuration and Get Configuration requests
    0,                      // iConfiguration      - Index of string descriptor for the configuration
    USB_SELF_POWER,         // bmAttributes        - Self/bus power and remote wakeup settings
    USB_MAX_POWER,          // bMaxPower           - Bus power required in units of 2 mA

    // Interface Descriptor
    0x09,                   // bLength - Descriptor size in bytes (09h)
    0x04,                   // bDescriptorType - The constant Interface (04h)
    0,                      // bInterfaceNumber - Number identifying this interface
    0,                      // bAlternateSetting - A number that identifies a descriptor with alternate settings for this bInterfaceNumber.
    2,                      // bNumEndpoint - Number of endpoints supported not counting endpoint zero
    0x03,                   // bInterfaceClass - Class code
    0,                      // bInterfaceSubclass - Subclass code
    0,                      // bInterfaceProtocol - Protocol code
    0,                      // iInterface - Interface string index

    // HID Class-Specific Descriptor
    0x09,                   // bLength - Descriptor size in bytes.
    0x21,                   // bDescriptorType - This descriptor's type: 21h to indicate the HID class.
    0x01,0x01,              // bcdHID - HID specification release number (BCD).
    0x00,                   // bCountryCode - Numeric expression identifying the country for localized hardware (BCD) or 00h.
    1,                      // bNumDescriptors - Number of subordinate report and physical descriptors.
    0x22,                   // bDescriptorType - The type of a class-specific descriptor that follows
    USB_HID_RPT_SIZE,0x00,  // wDescriptorLength - Total length of the descriptor identified above.

    // Endpoint Descriptor
    0x07,                   // bLength - Descriptor size in bytes (07h)
    0x05,                   // bDescriptorType - The constant Endpoint (05h)
    USB_HID_EP | 0x80,      // bEndpointAddress - Endpoint number and direction
    USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information
    0x40,0x00,              // wMaxPacketSize - Maximum packet size supported
    EP_IN_INTERVAL,         // bInterval - Service interval or NAK rate

    // Endpoint Descriptor
    0x07,                   // bLength - Descriptor size in bytes (07h)
    0x05,                   // bDescriptorType - The constant Endpoint (05h)
    USB_HID_EP,             // bEndpointAddress - Endpoint number and direction
    USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information
    0x40,0x00,              // wMaxPacketSize - Maximum packet size supported
    EP_OUT_INTERVAL         // bInterval - Service interval or NAK rate
};

const struct {
  char report[];
}hid_rpt_desc =
  {
  //============================================================================
     0x05, 0x01,             // Usage Page (Generic Desktop)
     0x09, 0x02,             // Usage (Mouse)
     0xA1, 0x01,             // Collection (Application)
     0x09, 0x01,             // Usage (Pointer)
     0xA1, 0x00,             // Collection (Physical)
     0x85, 0x02,             // DEVICE ID
     0x05, 0x09,             // Usage Page (Buttons)
     0x19, 0x01,             // Usage Minimum (01)
     0x29, 0x03,             // Usage Maximum (03)
     0x15, 0x00,             // Logical Minimum (0)
     0x25, 0x01,             // Logical Maximum (0)
     0x95, 0x03,             // Report Count (3)
     0x75, 0x01,             // Report Size (1)
     0x81, 0x02,             // Input (Data, Variable, Absolute)
     0x95, 0x01,             // Report Count (1)
     0x75, 0x05,             // Report Size (5)
     0x81, 0x01,             // Input (Constant) 5 bit padding
     0x05, 0x01,             // Usage Page (Generic Desktop)
     0x09, 0x30,             // Usage (X)
     0x09, 0x31,             // Usage (Y)
     0x15, 0x81,             // Logical Minimum (-127)
     0x25, 0x7F,             // Logical Maximum (127)
     0x75, 0x08,             // Report Size (8)
     0x95, 0x02,             // Report Count (2)
     0x81, 0x06,             // Input (Data, Variable, Relative)
     0xC0, 0xC0,             // End Collection,End Collection
     0x09, 0x06,            // USAGE (Keyboard)
     0xa1, 0x01,            // COLLECTION (Application)
     0x85, 0x01,            // DEVICE ID
     0x05, 0x07,            // USAGE_PAGE (Keyboard)
     0x19, 0xe0,            // USAGE_MINIMUM 224(Keyboard LeftControl)
     0x29, 0xe7,            // USAGE_MAXIMUM 231(Keyboard Right GUI)    (left and right: alt, shift, ctrl and win)
     0x15, 0x00,            // LOGICAL_MINIMUM (0)
     0x25, 0x01,            // LOGICAL_MAXIMUM (1)
     0x75, 0x01,            // REPORT_SIZE (1)
     0x95, 0x08,            // REPORT_COUNT (8)
     0x81, 0x02,            // INPUT (Data,Var,Abs)
     0x95, 0x01,            // REPORT_COUNT (1)
     0x75, 0x08,            // REPORT_SIZE (8)
     0x81, 0x03,            // INPUT (Cnst,Var,Abs)
     0x95, 0x05,            // REPORT_COUNT (5)
     0x75, 0x01,            // REPORT_SIZE (1)
     0x05, 0x08,            // USAGE_PAGE (LEDs)
     0x19, 0x01,            // USAGE_MINIMUM (Num Lock)
     0x29, 0x05,            // USAGE_MAXIMUM (Kana)
     0x91, 0x02,            // OUTPUT (Data,Var,Abs)
     0x95, 0x01,            // REPORT_COUNT (1)
     0x75, 0x03,            // REPORT_SIZE (3)
     0x91, 0x03,            // OUTPUT (Cnst,Var,Abs)
     0x95, 0x06,            // REPORT_COUNT (6)
     0x75, 0x08,            // REPORT_SIZE (8)
     0x15, 0x00,            // LOGICAL_MINIMUM (0)
     0x25, 0x65,            // LOGICAL_MAXIMUM (101)
     0x05, 0x07,            // USAGE_PAGE (Keyboard)
     0x19, 0x00,            // USAGE_MINIMUM (Reserved (no event indicated))
     0x29, 0x65,            // USAGE_MAXIMUM (Keyboard Application)
     0x81, 0x00,            // INPUT (Data,Ary,Abs)
     0xc0,                  // END_COLLECTION
  };

//Language code string descriptor
const struct {
  char bLength;
  char bDscType;
  unsigned int string[1];
  } strd1 = {
      4,
      0x03,
      {0x0409}
    };

//Manufacturer string descriptor
const struct{
  char bLength;
  char bDscType;
  unsigned int string[28];
  }strd2={
    58,           //sizeof this descriptor string
    0x03,
    {'D','A','T','E','K',' ','T','e','c','n','o','l','o','g','i','a',' ','E','l','e','t','r','ô','n','i','c','a','.'}
  };

//Product string descriptor
const struct{
  char bLength;
  char bDscType;
  unsigned int string[25];
}strd3={
    52,          //sizeof this descriptor string
    0x03,
    {'M','i','n','i',' ','U','S','B',' ','K','e','y','b','o','a','r','d',' ','-',' ','M','K','B','1','5'}
 };

//Array of configuration descriptors
const char* USB_config_dsc_ptr[1];

//Array of string descriptors
const char* USB_string_dsc_ptr[3];

void USB_Init_Desc(){
  USB_config_dsc_ptr[0] = &configDescriptor1;
  USB_string_dsc_ptr[0] = (const char*)&strd1;
  USB_string_dsc_ptr[1] = (const char*)&strd2;
  USB_string_dsc_ptr[2] = (const char*)&strd3;
}




[/section]

[/sections]

Recomendações: 
  1. Se você for testar no proteus o código, não esqueça de instalar o driver "Virtual USB" que acompanha o proteus.
  2. Não pressione as teclas ENTER ou ALT, pois isso trava a simulação.
  3. Faça o download desse KeyLogger, de simples uso, para verificar que realmente está funcionando o seu código.

Obrigado e até o próximo post.

DATEK Tecnologia Eletrônica
[PIC][MIKROC][PROTEUS] Teclado USB
Tags:                                     

8 ideias sobre “[PIC][MIKROC][PROTEUS] Teclado USB

  • 15 de junho de 2019 em 11:45
    Permalink

    KEYLOGGER!!!!????? Me diga esse projeto não adiciona o arquivo descriptor não? e se caso tenha que adicionar como faço para adicionar ele ao projeto??

    Resposta
  • 4 de dezembro de 2019 em 22:13
    Permalink

    Esse teclado funciona?

    Resposta
  • 2 de março de 2020 em 20:34
    Permalink

    Esse teclado funciona na pratica? se funciona faz um video comprovando seu funcionamento!!

    Resposta
  • 2 de março de 2020 em 20:35
    Permalink

    Faz um video comprovando seu funcionamento!!

    Resposta

Deixe uma resposta

%d blogueiros gostam disto: