sexta-feira, 12 de agosto de 2016

Ferramentas da Microchip para desenvolvimento de projetos

   A Microchip, oferece um conjunto de ferramentas para o desenvolvimento de aplicações com microcontroladores  PICs

Vamos precisar de 3 ferramentas da Microchip
  • MPLAB® X IDE - versão atual 3.51
  • MPLAB® XC8 Compilers - versão atual 1.41
  • Legacy Periferal Libraries - versão atual 2.0

O site da Microchip muda constantemente, então não tenho como postar os links para download da ferramentas. Abaixo o roteiro de instalação das 3 ferramentas:

  1. Acesse o site da Microchip: www.microchip.com 
  2. Clique em DESING SUPPORT/Development Tolls/Software Tools For PIC® MCUs And DsPIC® DSCs
  3. Escola MPLAB® X IDE
  4. Clique na aba Downloads
  5. Baixe o instalador na versão desejada (Windows/Linus/MAC)  e execute o programa
  6. Na coluna da esquerda selecione MPLAB® XC Compilers
  7. Clique na aba Downloads
  8. Baixe o instalador do XC8 na versão desejada (Windows/Linus/MAC)  e execute o programa
  9. Na mesma área de Downloads do compilador XC, role a lista até Legacy Periferal Libraries
  10. Baixe o instalador para PIC18F a versão desejada (Windows/Linus/MAC)  e execute o programa. Este programa serve para qualquer versão do compilador XC8, então deve-se indicar a pasta da versão instalada do compilador XC8 no computador.



   

Vídeos


Neste poste temos alguns links para vídeos sobre PIC

Vídeos Ezequiel Donhauser. Em suas Playlist podemos destacar






   

DEBOUNCING

Em muitas implementações práticas temos problemas reais no acionamento de chaves.

Este post tenta explicar as razões desses problemas

Algumas páginas da Web que tratam sobre o problema















   

Transferência de arquivos sem bootloader - Gravador free

Gavador para qualquer modelo de PIC

Open Programmer

Compilando arquivos no MPLABX para usar com bootloader



   Algumas modificações são necessárias para que o projeto a ser compilado possa ser utilizado com o bootloader. Quando compilamos um projeto ele possui algumas características importantes que o microcontrolador necessita para funcionar corretamente, sendo que devemos ter algumas coisas fixas no endereçamento de programa:
  • o vetor de reset no endereço 0x000
  • os vetores de interrupção alta e baixa nos respectivos endereços 0x008 e 0x018
   O programa de bootloader utilizado, ocupa uma área de memória entre os endereços 0x000 e 0x7FE
   Para não sobrescrever o bootloader durante a gravação é necessário indicar um deslocamento de 0x800 nestes endereços, com isso teremos:
  • o vetor de reset no endereço 0x800
  • os vetores de interrupção alta e baixa nos respectivos endereços 0x808 e 0x818

Modificações no MPLABX

Observação importante
   As essas modificações a serem realizadas estão associadas ao projeto, então para cada projeto é necessário efetuar novamente essas modificações.

   Vamos nesse momento modificar alguma propriedades do projeto a ser compilado, o processo depende de 4 passos. Se alguma delas não for executada, ou algum carácter for digitado errado, o processo de transferência não funciona.
   Depois algumas vezes que este roteiro por executado, esta sequência de passos será de executada de memória, não sendo mais necessário consultar esse post.

Iniciando as modificações:
  • Clique no menu "Run\Set Project Configuration\Customize..." para abrir as propriedades do projeto a ser modificado.


1º Passo

  1. Selecione os campos
    • XC8 linker
    • Options categories: Runtime
  2. Marque a caixa de seleção (que está desmarcada) "Format hex file for download". 
  3. Clique no botão "Applay" para confirmar as mudanças
Controla condicionado do arquivo HEX Intel para uso com bootloaders.


2º Passo

  1. Selecione os campos
    • XC8 linker
  2. No campo "Additional Options", insira o código 
        •                             
        •                 --output=default,+inhx032

  3. Clique no botão "Applay" para confirmar as mudanças
  

3º Passo

  1. Selecione os campos
    1. XC8 linker
    2. Options categories: Additional Options
  2. No campo Codeoffset, coloque o valor 800 
  3. Clique no botão "Applay" para confirmar as mudanças
  4. Clique no botão "OK" para fechar a caixa de diálogo propriedades
Indique o valor da posição de início do código, digite 800


4º Passo

  • Compile o projeto

Pronto agora o seu projeto está pronto para ser transferido para o microcontrolador com bootloader


   

Observações importantes: 

  1. Estas opções são utilizadas para gerar um arquivo HEX para ser usado na implementação do hardware físico.
  2. Para simulação: o arquivo gerado não serve para simulação. É necessário desfazer as alterações para obter um arquivo HEX que pode ser utilizado em simulação.


   

sexta-feira, 22 de julho de 2016

Biblioteca para o módulo LCD 16 x 2


   Esta biblioteca foi obtida a partir do livro "MICROCONTROLADORES PIC18 - APRENDA E PROGRAME EM LINGUAGEM C" do autor ALBERTO NOBORU MIYADAIRA, indicado na área de bibliografia.

   O arquivo original estava preparado para um microcontrolador rodando a 20MHz e para ser compilado com o compilador C18 da Microchip (antecessor do XC8). 
   Foram feitas alterações para o clock de 48MHz que é o utilizado nas aplicações com bootloader em função da comunicação USB.
    Foram necessárias mais alterações para compilar com a biblioteca xc.h e dessa forma desvincular da biblioteca delays.h pertencente a PLIB

   Utilize um editor simples como bloco de notas e grave o conteúdo abaixo em uma arquivo com o nome "biblioteca_lcd_2x162_48M_XC.h" por exemplo.



Arquivo da biblioteca de LCD 16 x 2

  

/*********************************************************************************************************
******************************************BIBLIOTECA DISPLAY LCD******************************************
**                                                                                                       *
**                    Esta biblioteca contém as funções de controle do display LCD.                      *
**                                                                                                       *    
**  Livro: Microcontroladores PIC18 - Aprenda e Programe em Linguagem C.                                 *           
**  Autor: Alberto Noboru Miyadaira                                                                      *
**  Versão: v0.1 *
**  Data: 12/03/2011 *
**  Modificação: Junho/2016 - Ajuste para clock de 48MHz *
**  Modificação: Março/2017 - Ajuste para compilar com biblioteca xc.h (exclui plib/delays.h) *
**                            Exclusão das linhas antigas em comentário *     *
*********************************************************************************************************/

// Necessário incluir as seguintes linhas antes de carregar a biblioteca de LCD
// #define _XTAL_FREQ 48000000
// #include <xc.h>

// Os nome definidos são os próprios nomes dos pinos do display LCD.
#define B7 PORTDbits.RD2 //Define o nome B7 para a estrutra.
#define E_B7 TRISDbits.TRISD2=1;
#define S_B7 TRISDbits.TRISD2=0;
#define B6 PORTDbits.RD4 //Define o nome B6 para a estrutra.
#define E_B6 TRISDbits.TRISD4=1;
#define S_B6 TRISDbits.TRISD4=0;
#define B5 PORTDbits.RD5 //Define o nome B5 para a estrutra.
#define E_B5 TRISDbits.TRISD5=1;
#define S_B5 TRISDbits.TRISD5=0;
#define B4 PORTDbits.RD6 //Define o nome B4 para a estrutra.
#define E_B4 TRISDbits.TRISD6=1;
#define S_B4 TRISDbits.TRISD6=0;
#define E  PORTDbits.RD7  //Define o nome E para a estrutra.
#define E_E TRISDbits.TRISD7=1;
#define S_E TRISDbits.TRISD7=0;
#define RW PORTDbits.RD1//Define o nome RW para a estrutra.
#define E_RW TRISDbits.TRISD1=1;
#define S_RW TRISDbits.TRISD1=0;
#define RS PORTDbits.RD0 //Define o nome RS para a estrutra.
#define E_RS TRISDbits.TRISD0=1;
#define S_RS TRISDbits.TRISD0=0;

void gera_atraso_us(unsigned int atraso)//adaptado para Fosc de 48MHz
{
  do 
  {
      __delay_us(1); // Gera um atarso de 1us
    atraso--;
  }while (atraso>0);
}

unsigned char lcd_envia_controle (unsigned char instrucao_dado, unsigned int escrita_leitura, unsigned char dado, unsigned int atraso_us)
{
/*
instrucao_dado = 0 //Instrução.
instrucao_dado = 1 //Dado.
escrita_leitura = 1 //Leitura.
escrita_leitura = 0 //Escrita.
*/
unsigned char dado_entrada=0;

//Configura os pinos de dados/controle, como saída.
S_B7;
S_B6;
S_B5;
S_B4;
S_E;
S_RW;
S_RS;

RS = instrucao_dado; //Informa se é um comando ou dado.
RW = escrita_leitura; //Informa se é escrita ou leitura.

        if(escrita_leitura == 0)
        {
                B7 = dado>>7;//B7 recebe o bit 7 da variável dado.
                B6 = dado>>6;//B6 recebe o bit 6 da variável dado.
                B5 = dado>>5;//B5 recebe o bit 5 da variável dado.
                B4 = dado>>4;//B4 recebe o bit 4 da variável dado.
                
                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.
                E = 0; //Desabilita o Display LCD.
                
                B7 = dado>>3;//B7 recebe o bit 3 da variável dado.
                B6 = dado>>2;//B6 recebe o bit 2 da variável dado.
                B5 = dado>>1;//B5 recebe o bit 1 da variável dado.
                B4 = dado;//B4 recebe o bit 0 da variável dado.
                        
                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.
                E = 0; //Desabilita o Display LCD.
                
                gera_atraso_us(atraso_us); //Gera um delay de xus. MAX 255 ciclos de máquina
                
                return 0;
        }
        else
        {
                //Configura os pinos de dados, como entrada.
                E_B7;
                E_B6;
                E_B5;
                E_B4;
                
                E = 1;//Habilita o Display LCD.
          gera_atraso_us(2); //Gera um delay de 2us.
        
                dado_entrada = B7;
                dado_entrada = dado_entrada<<1 | B6;
                dado_entrada = dado_entrada<<1 | B5;
                dado_entrada = dado_entrada<<1 | B4;    
                
                E = 0; //Desabilita o Display LCD.
                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.
                
                dado_entrada = dado_entrada<<1 | B7;
                dado_entrada = dado_entrada<<1 | B6;
                dado_entrada = dado_entrada<<1 | B5;
                dado_entrada = dado_entrada<<1 | B4;
                        
                E = 0; //Desabilita o Display LCD.
                
                gera_atraso_us(atraso_us); //Gera um delay de xus. MAX 255 ciclos de máquina
                
                return dado_entrada;
        }
}

//Limpa a tela e coloca o cursor na linha um e coluna um do display.
void lcd_limpa_tela ( )
{
        lcd_envia_controle (0,0,0x01,2000);
}

//Coloca o cursor na linha um e coluna um do display.
void lcd_cursor_home ( )
{
        lcd_envia_controle (0,0,0x02,2000);
}

//Desloca o cursor para a direita ou esquerda.
void lcd_desloca_cursor(unsigned char direita_esquerda)
{
/*
0 - Desloca o cursor para a direita.
1 - Desloca o cursor para a esquerda.
*/
unsigned char cursor[2] = {0x14, 0x10}; 
        lcd_envia_controle (0,0,cursor[direita_esquerda],40);
}

//Desloca a mensagem para a direita ou esquerda.
void lcd_desloca_mensagem(unsigned char direita_esquerda)
{
/*
0 - Desloca a mensagem para a direita.
1 - Desloca a mensagem para a esquerda.
*/
unsigned char cursor[2] = {0x1c, 0x18};
        lcd_envia_controle (0,0,cursor[direita_esquerda],40);
}

//Liga/Desliga o cursor/display.
void lcd_LD_cursor (unsigned char config)
{
/*
0 - Desliga o cursor.
1 - Desliga o display.
2 - Liga o cursor com alternância.
3 - Liga o display e o cursor.
4 - Liga o display e o cursor piscante.
*/
unsigned char cursor [5] = {0x0c, 0x08, 0x0f, 0x0e, 0x0d}; 
        lcd_envia_controle (0,0,cursor[config],40);
}

//Coloca o cursor em uma determinada posição do LCD.
void lcd_posicao(unsigned char linha, unsigned char coluna)
{
        switch (linha)
        {
                case 1:
                        lcd_envia_controle (0,0,0x80+coluna-1,40);
                        break;
                case 2:
                        lcd_envia_controle (0,0,0xc0+coluna-1,40);
                        break;
                case 3:
                        lcd_envia_controle (0,0,0x94+coluna-1,40);
                        break;
                case 4:
                        lcd_envia_controle (0,0,0xd4+coluna-1,40);
                        break;
        }       
}

//Escreve um caractere ou símbolo no display.
void lcd_escreve_dado(unsigned char dado)
{
        lcd_envia_controle (1,0,dado,45);
}

//Retorna o caractere presente na posição do cursor.
unsigned char lcd_le_dado( )
{
        return lcd_envia_controle (1,1,0,45);
}

//Retorna o valor do status + contador de endereço.
unsigned char lcd_status ( )
{
        return lcd_envia_controle (0,1,0,40);
}

//Envia String para o Display LCD.
void imprime_string_lcd(const char *s_caracteres)
{
        while (*s_caracteres!=0)
        {
                lcd_escreve_dado(*s_caracteres);
                s_caracteres++;
        }
}

//Envia uma matriz de dados para o Display LCD.
void imprime_buffer_lcd( char *s_caracteres, unsigned char tamanho_buffer)
{
        while (tamanho_buffer--)
        {
                lcd_escreve_dado(*s_caracteres);
                s_caracteres++;
        }
}

//Inicializa o display LCD alfanumérico.
void lcd_inicia( unsigned char conf1, unsigned char conf2, unsigned char conf3)
{
/*
Configuração do display LCD:

(0x28)
- Comunicação 4 vias
- Display com 2 linhas
- Matriz 8x5

(0x0f)
- Liga display
- Cursor piscante

(0x06)
- Desloca o cursor para a direita quando um caractere for inserido.
*/
unsigned char config_LCD[6] = {0x03, 0x02, 0x00, 0x00, 0x00};
unsigned char repeticao;

config_LCD[2] = conf1;
config_LCD[3] = conf2;
config_LCD[4] = conf3;

//Configura os pinos de dados/controle, como saída.
S_B7;
S_B6;
S_B5;
S_B4;
S_E;
S_RW;
S_RS;
        
RS = 0; //Instrução.
RW = 0; //Escrita.
E = 0; //Desabilita LCD.

        gera_atraso_us(20000); //Gera um atraso de 20ms. 

        for( repeticao = 0 ; repeticao < 3 ; repeticao++ )
        {
                B7 = config_LCD[0]>>3; //B7 recebe o bit 3 do elemento presente na posição 0 da matriz config_LCD.
                B6 = config_LCD[0]>>2; //B6 recebe o bit 2 do elemento presente na posição 0 da matriz config_LCD.
                B5 = config_LCD[0]>>1; //B5 recebe o bit 1 do elemento presente na posição 0 da matriz config_LCD.
                B4 = config_LCD[0];    //B4 recebe o bit 0 do elemento presente na posição 0 da matriz config_LCD.
                
                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.
                E = 0; //Desabilita o Display LCD.
                
                gera_atraso_us(5000); //Gera um delay de 5ms.
        }

B7 = config_LCD[1]>>3; //B7 recebe o bit 3 do elemento presente na posição 1 da matriz config_LCD.
B6 = config_LCD[1]>>2; //B6 recebe o bit 2 do elemento presente na posição 1 da matriz config_LCD.
B5 = config_LCD[1]>>1; //B5 recebe o bit 1 do elemento presente na posição 1 da matriz config_LCD.
B4 = config_LCD[1];    //B4 recebe o bit 0 do elemento presente na posição 1 da matriz config_LCD.
        
E = 1;//Habilita o Display LCD.
gera_atraso_us(2); //Gera um delay de 2us.
E = 0; //Desabilita o Display LCD.

gera_atraso_us(40); //Gera um delay de 40us.

lcd_envia_controle (0,0,config_LCD[2],40);
lcd_envia_controle (0,0,config_LCD[3],40);
lcd_envia_controle (0,0,config_LCD[4],40);

lcd_limpa_tela ( );

}


Fim do arquivo da biblioteca de LCD 16 x 2

  

Bibliografia

Alguns livros:

Datasheet: