Pesquisar neste blog

22/04/2022

Inserir valor analógico com display 7segmentos

 Objetivo: Capturar o valor analógico lido e exibir na tela LCD + no display de 7 segmentos.






Código feito em CCS C Compiler

#include <16F877A.h>

#device adc = 8

#include <math.h>


#FUSES NOWDT, HS, NOPROTECT, NODEBUG

#FUSES NOBROWNOUT, NOLVP, NOCPD, NOWRT

#use delay(crystal = 20MHz)


#ifndef lcd_enable

   #define lcd_enable   pin_e1 // pino enable do LCD

   #define lcd_rs       pin_e2 // pino rs do LCD

   //#define lcd_rw       pin_e2 // pino rw do LCD

   #define lcd_d4       pin_d4 // pino de dados d4 do LCD

   #define lcd_d5       pin_d5 // pino de dados d5 do LCD

   #define lcd_d6       pin_d6 // pino de dados d6 do LCD

   #define lcd_d7       pin_d7 // pino de dados d7 do LCD

#endif


#include <mod_lcd.c>

unsigned int8 valor, aux, c, d, u;

unsigned int8 vetor[] = {0b00111111, 0b00000110, // 0 a 9

   0b01011011, 0b01001111, 0b01100110, 0b01101101,

   0b01111101, 0b00000111, 0b01111111, 0b01100111 };


void main(){

   setup_adc_ports(AN0);

   setup_adc(ADC_CLOCK_INTERNAL);

   set_adc_channel(0);

   

   lcd_ini();


   while(TRUE){

      //TODO: User Code


      valor = read_adc();

      if(valor >= 99){

         valor = 99;

      }  

      aux = valor/100;     // extrai o primeiro piso das centenas

      c = (int)floor(aux); // converte para inteiro

      

      aux = ((valor/10)-(10*c)); //extrai o primeiro piso das dezenas

      d = (int)floor(aux);       //converte para inteiro

      

      aux = ((valor)-(100*c)-(10*d));  //extrai o primeiro piso das unidades

      u = (int)floor(aux);             //converte para inteiro

      

      printf (lcd_escreve,"\fValor = %u\r\n",valor);

      delay_ms(20); 

      output_b(vetor[d]);

      output_c(vetor[u]);  

   }

}

Software: Proteus versão 7.9






21/04/2022

Ligando todos os displays no PicsimLab

Objetivo: Ligar todos displays no Pic Genius com microcontrolador 16F877A

Código feito em CCS C Compiler

#include <16F877A.h>
#device adc=8

#use delay(clock=20MHz)
  
byte const display [ ] = {
   0b000000,  // display desligado
   0b000100, // display 1
   0b001000, // display 2
   0b010000, // display 3
   0b100000,  // display 4
   0b111100 //todos os display
};

int i = 0;
void main(){
   
   while(true){
      output_a(display[i]);
      delay_ms(500);
      i++;
   }
}

Simulador: PicsimLab



11/04/2022

Comandos no SQL Server #4

















--disable trigger trig_controla_ddl on database

CREATE TRIGGER trig_controla_dd1 ON DATABASE
FOR create_procedure, alter_procedure, drop_procedure, drop_table, alter_table AS
   IF Datepart(hh, Getdate()) <= 8
OR Datepart(hh, Getdate()) >= 17
   BEGIN
DECLARE @msg VARCHAR(200)
SELECT @msg = 'Complete o trabalho em horario comercial'
PRINT (@msg)
ROLLBACK
  END

07/04/2022

#Desafio 5

Software: Proteus versão 7.9


Software: PicsimLab




























Código feito em CCS C Compiler

Biblioteca: mod_lcd.c

/************************************************************************/
/*  MOD_LCD.C - Biblioteca de manipulação d módulo LCD                 */                                                                    */
/************************************************************************/

// As definições a seguir são utilizadas para acesso aos pinos do display
// caso o pino RW n�o seja utilizado, comente a defini��o lcd_rw
#ifndef lcd_enable
   #define lcd_enable       pin_e1      // pino enable do LCD
   #define lcd_rs         pin_e0      // pino rs do LCD
   //#define lcd_rw      pin_e2      // pino rw do LCD
   #define lcd_d4         pin_d4      // pino de dados d4 do LCD
   #define lcd_d5         pin_d5      // pino de dados d5 do LCD
   #define lcd_d6         pin_d6      // pino de dados d6 do LCD
   #define lcd_d7         pin_d7      // pino de dados d7 do LCD
#endif

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 linhas
#define lcd_seg_lin 0x40    // Endere�o da segunda linha na RAM do LCD

// a constante abaixo define a seq��ncia de inicializa��o do m�dulo LCD
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};

byte lcd_le_byte(){
// l� um byte do LCD (somente com pino RW)
   byte dado;
   // configura os pinos de dados como entradas
   input(lcd_d4);
   input(lcd_d5);
   input(lcd_d6);
   input(lcd_d7);
   // se o pino rw for utilizado, coloca em 1
   #ifdef lcd_rw
      output_high(lcd_rw);
   #endif
   output_high(lcd_enable); // habilita display
   dado = 0;   // zera a vari�vel de leitura
   // l� os quatro bits mais significativos
   if (input(lcd_d7)) bit_set(dado,7);
   if (input(lcd_d6)) bit_set(dado,6);
   if (input(lcd_d5)) bit_set(dado,5);
   if (input(lcd_d4)) bit_set(dado,4);
   // d� um pulso na linha enable
   output_low(lcd_enable);
   output_high(lcd_enable);
   // l� os quatro bits menos significativos
   if (input(lcd_d7)) bit_set(dado,3);
   if (input(lcd_d6)) bit_set(dado,2);
   if (input(lcd_d5)) bit_set(dado,1);
   if (input(lcd_d4)) bit_set(dado,0);
   output_low(lcd_enable);   // desabilita o display
   return dado;   // retorna o byte lido
}

void lcd_envia_nibble( byte dado ){
// envia um dado de quatro bits para o display
   // coloca os quatro bits nas saidas
   output_bit(lcd_d4,bit_test(dado,0));
   output_bit(lcd_d5,bit_test(dado,1));
   output_bit(lcd_d6,bit_test(dado,2));
   output_bit(lcd_d7,bit_test(dado,3));
   // d� um pulso na linha enable
   output_high(lcd_enable);
   output_low(lcd_enable);
}


void lcd_envia_byte( boolean endereco, byte dado ){
   // coloca a linha rs em 0
   output_low(lcd_rs);
   // aguarda o display ficar desocupado
   //while ( bit_test(lcd_le_byte(),7) ) ;
   // configura a linha rs dependendo do modo selecionado
   output_bit(lcd_rs,endereco);
   delay_us(100);   // aguarda 100 us
   // caso a linha rw esteja definida, coloca em 0
   #ifdef lcd_rw
      output_low(lcd_rw);
   #endif
   // desativa linha enable
   output_low(lcd_enable);
   // envia a primeira parte do byte
   lcd_envia_nibble(dado >> 4);
   // envia a segunda parte do byte
   lcd_envia_nibble(dado & 0x0f);
}


void lcd_ini(){
// rotina de inicializa��o do display

   byte conta;
   output_low(lcd_d4);
   output_low(lcd_d5);
   output_low(lcd_d6);
   output_low(lcd_d7);
   output_low(lcd_rs);
   #ifdef lcd_rw
      output_high(lcd_rw);
   #endif
   output_low(lcd_enable);
   delay_ms(15);
   // envia uma seq��ncia de 3 vezes 0x03
   // e depois 0x02 para configurar o m�dulo
   // para modo de 4 bits
   for(conta=1;conta<=3;++conta){
      lcd_envia_nibble(3);
      delay_ms(5);
   }
   lcd_envia_nibble(2);
   // envia string de inicializa��o do display
   for(conta=0;conta<=3;++conta) lcd_envia_byte(0,INI_LCD[conta]);
}

void lcd_pos_xy( byte x, byte y){
   byte endereco;
   if(y!=1)
      endereco = lcd_seg_lin;
   else
      endereco = 0;
   endereco += x-1;
   lcd_envia_byte(0,0x80|endereco);
}

void lcd_escreve( char c){
// envia caractere para o display
   switch (c)   {
     case '\f'    :   lcd_envia_byte(0,1);
              delay_ms(2);
            break;
     case '\n'   :
     case '\r'    :   lcd_pos_xy(1,2);
              break;
     case '\b'    :   lcd_envia_byte(0,0x10);
              break;
     default   :   lcd_envia_byte(1,c);
              break;
   }
}

char lcd_le( byte x, byte y){
// le caractere do display
   char valor;
   // seleciona a posi��o do caractere
   lcd_pos_xy(x,y);
   // ativa rs
   output_high(lcd_rs);
   // l� o caractere
   valor = lcd_le_byte();
   // desativa rs
   output_low(lcd_rs);
   // retorna o valor do caractere
   return valor;
}

Arquivo principal: Bicicleta.c

#include <16F877A.h>
#device adc = 8
#FUSES NOWDT
#FUSES HS
#FUSES NOPUT
#FUSES NOPROTECT
#FUSES NODEBUG
#FUSES BROWNOUT
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT

#use delay(clock = 20MHz)

#ifndef lcd_enable
   #define lcd_enable   pin_e1 // pino enable do LCD
   #define lcd_rs       pin_e2 // pino rs do LCD
   //#define lcd_rw       pin_e2 // pino rw do LCD
   #define lcd_d4       pin_d4 // pino de dados d4 do LCD
   #define lcd_d5       pin_d5 // pino de dados d5 do LCD
   #define lcd_d6       pin_d6 // pino de dados d6 do LCD
   #define lcd_d7       pin_d7 // pino de dados d7 do LCD
#endif
#include <mod_lcd.c>

//#use fast_io(B) //habilita todas as portas B
//#use fast_io(D)
#define delay 50

unsigned int8 diametro = 0, cont = 0;
unsigned boolean flag = false;
int HORA = 0, MINUTO = 0, SEGUNDO = 0;
int8 velocidade, distancia;

#INT_RTCC
void  RTCC_isr(void) {
   output_toggle(PIN_B0); 
   cont++;
}

void main(){
     
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //overflow en 13.1 
   setup_adc_ports(AN0_AN1_AN3);   
   setup_adc(ADC_CLOCK_DIV_16);     
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);    
   set_adc_channel(0);    
   delay_us(50);
   
   //output_b(0);
   //set_tris_b(0x03);
   port_b_pullups(TRUE);
   output_d(0);
   set_tris_d(0);
      
   lcd_ini();
      
   while(TRUE){
      diametro = read_adc();
      
      printf (lcd_escreve,"\fIns. dist: %u",diametro);
      delay_ms(200);
            
      while( ! input(PIN_B1)){
         velocidade = diametro * 3.1415 * 0.5;
         distancia = velocidade * (HORA + MINUTO);
         SEGUNDO++;
         
         if(SEGUNDO > 59){
            SEGUNDO = 0;
            MINUTO++;
         }
         
         if(MINUTO > 59){
            MINUTO = 0;
            HORA++;
         }
         
         if(HORA > 23) HORA = 0;
         lcd_pos_xy(1,2);
         printf (lcd_escreve,"  V = %u r/s \n%u:%u:%u Dt= %u ",velocidade, HORA, MINUTO, SEGUNDO, distancia);
         output_c(0b1000);
         delay_ms(delay);
         output_c(0b0100);
         delay_ms(delay);
         output_c(0b0010);
         delay_ms(delay);
         output_c(0b0001);
         delay_ms(delay);
         
         distancia++;
      }
      
   }
}

05/04/2022

Ligar os displays no PicsimLab com Pic 16F628A

Código feito em CCS C Compiler

#include <16F628A.h>
#FUSES NOWDT                     //No Watch Dog Timer
#FUSES NOBROWNOUT     //No brownout reset
#FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal = 4MHz)
#define LED PIN_B4
#define DELAY 3
#define DELAY_LIGADO 5

void apaga(){
   OUTPUT_B(0);
}
void dois(){
 
   /*output_high(PIN_B2);
   output_high(PIN_B3);
   output_high(PIN_B0);
   output_high(PIN_B7);
   output_high(PIN_B6);*/
 
   OUTPUT_B(0b11011101);

}
void um(){
   OUTPUT_B(0b0101000); // para ligar o display da direita => RB4 = 1
}
void main(){
 //apaga();
 //dois();
   while(true){
      apaga();
      delay_ms(DELAY);
      dois();
      delay_ms(DELAY_LIGADO);

      apaga();
      delay_ms(DELAY);
      um();
      delay_ms(DELAY_LIGADO);
   }
}

Software: PicsimLab com PIC 16F628A




















04/04/2022

#Desafio 4 - Biblioteca expandida

Acrescentar funções a biblioteca mod_lcd.c e criar uma nova com o nome mod_lcd_plus.c 

1. A biblioteca mod_lcd_plus.c deve ter no mínimo cinco funções a mais que a original sendo que uma delas servira para desenha caracteres definidos pelo usuário. Essa nova função deve chamar lcd_escreve_graphic. As outras quatros funções podem ser definida por você, isto é, você define o nome e o que a função vai fazer. 

2. Faça um programa para apresentar a nova biblioteca que rode no PICSimLab com a board PICGenios e o PIC 16F877A

Resolução feita em CCS C Compiler

Arquivo: mod_lcd_graphic.c

/************************************************************************/
/* MOD_LCD_GRAPHIC.C - Biblioteca de manipulação de módulo LCD ++ */
/* */
/* Autor: Fábio Pereira e Alberto Willian Mascarenhas */
/* */
/************************************************************************/
// Command set for Hitachi 44780U LCD display controller
#define LCD_CLEAR 0x01 // It clears everythings
#define LCD_HOME 0x02 // set the cursor to first line and first row
#define LCD_CURSOR_BACK 0x10 // moves curson one position back
#define LCD_CURSOR_FWD 0x14 //moves curson one position forward
#define LCD_PAN_LEFT 0x18 // used to scroll text left side to scroll text
#define LCD_PAN_RIGHT 0x1C // used to scroll text right side to scroll text
#define LCD_CURSOR_OFF 0x0C // stops display curson on screen
#define LCD_CURSOR_ON 0x0E // turns on cursor display
#define LCD_CURSOR_BLINK 0x0F // curson keeps blinking
#define LCD_CURSOR_LINE2 0xC0 // move curson to scond line or second row
// As definições a seguir são utilizadas para acesso aos pinos do display
// caso o pino RW não seja utilizado, comente a definição lcd_rw
#ifndef lcd_enable
#define lcd_enable pin_e1 // pino enable do LCD
#define lcd_rs pin_e0 // pino rs do LCD
//#define lcd_rw pin_e2 // pino rw do LCD
#define lcd_d4 pin_d4 // pino de dados d4 do LCD
#define lcd_d5 pin_d5 // pino de dados d5 do LCD
#define lcd_d6 pin_d6 // pino de dados d6 do LCD
#define lcd_d7 pin_d7 // pino de dados d7 do LCD
#endif
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 linhas
#define lcd_seg_lin 0x40 // Endereço da segunda linha na RAM do LCD
// a constante abaixo define a seqüência de inicialização do módulo LCD
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};
byte lcd_le_byte()
// lê um byte do LCD (somente com pino RW)
{
byte dado;
// configura os pinos de dados como entradas
input(lcd_d4);
input(lcd_d5);
input(lcd_d6);
input(lcd_d7);
// se o pino rw for utilizado, coloca em 1
#ifdef lcd_rw
output_high(lcd_rw);
#endif
 output_high(lcd_enable); // habilita display
dado = 0; // zera a variável de leitura
// lê os quatro bits mais significativos
if (input(lcd_d7)) bit_set(dado,7);
if (input(lcd_d6)) bit_set(dado,6);
if (input(lcd_d5)) bit_set(dado,5);
if (input(lcd_d4)) bit_set(dado,4);
// dá um pulso na linha enable
output_low(lcd_enable);
output_high(lcd_enable);
// lê os quatro bits menos significativos
if (input(lcd_d7)) bit_set(dado,3);
if (input(lcd_d6)) bit_set(dado,2);
if (input(lcd_d5)) bit_set(dado,1);
if (input(lcd_d4)) bit_set(dado,0);
output_low(lcd_enable); // desabilita o display
return dado; // retorna o byte lido
}
void lcd_envia_nibble( byte dado )
// envia um dado de quatro bits para o display
{
// coloca os quatro bits nas saidas
output_bit(lcd_d4,bit_test(dado,0));
output_bit(lcd_d5,bit_test(dado,1));
output_bit(lcd_d6,bit_test(dado,2));
output_bit(lcd_d7,bit_test(dado,3));
// dá um pulso na linha enable
output_high(lcd_enable);
output_low(lcd_enable);
}
void lcd_envia_byte( boolean endereco, byte dado )
{
// coloca a linha rs em 0
output_low(lcd_rs);
// aguarda o display ficar desocupado
//while ( bit_test(lcd_le_byte(),7) ) ;
// configura a linha rs dependendo do modo selecionado
output_bit(lcd_rs,endereco);
delay_us(100); // aguarda 100 us
// caso a linha rw esteja definida, coloca em 0
#ifdef lcd_rw
output_low(lcd_rw);
#endif
// desativa linha enable
output_low(lcd_enable);
// envia a primeira parte do byte
lcd_envia_nibble(dado >> 4);
// envia a segunda parte do byte
lcd_envia_nibble(dado & 0x0f);
}
void lcd_ini()
// rotina de inicialização do display
{
byte conta;
output_low(lcd_d4);
output_low(lcd_d5);
output_low(lcd_d6);
output_low(lcd_d7);
output_low(lcd_rs);
#ifdef lcd_rw
output_high(lcd_rw);
#endif
output_low(lcd_enable);
delay_ms(15);
// envia uma seqüência de 3 vezes 0x03
// e depois 0x02 para configurar o módulo
// para modo de 4 bits
for(conta=1;conta<=3;++conta)
{
lcd_envia_nibble(3);
delay_ms(5);
}
lcd_envia_nibble(2);
// envia string de inicialização do display
for(conta=0;conta<=3;++conta) lcd_envia_byte(0,INI_LCD[conta]);
}
void lcd_pos_xy( byte x, byte y)
{
 byte endereco;
 if(y!=1)
 endereco = lcd_seg_lin;
 else
 endereco = 0;
 endereco += x-1;
 lcd_envia_byte(0,0x80|endereco);
}
void lcd_escreve( char c)
// envia caractere para o display
{
 switch (c)
{
 case '\f' : lcd_envia_byte(0,1);
 delay_ms(2);
break;
 case '\n' :
case '\r' : lcd_pos_xy(1,2);
 break;
 case '\b' : lcd_envia_byte(0,0x10);
 break;
 default : lcd_envia_byte(1,c);
 break;
 }
}
char lcd_le( byte x, byte y)
// le caractere do display
{
char valor;
// seleciona a posição do caractere
lcd_pos_xy(x,y);
// ativa rs
output_high(lcd_rs);
// lê o caractere
valor = lcd_le_byte();
// desativa rs
output_low(lcd_rs);
// retorna o valor do caractere
return valor;
}
//-----------------------------------------------------------------
//
// Funções adicionadas por Alberto Willian Mascarenhas
//
//-----------------------------------------------------------------
void CriaCaracterEspecial (unsigned char *Pattern, char Location)
{
 int i=0;
 lcd_envia_byte(0,0x40+(Location*8)); //Send the Address of CGRAM
 for (i=0; i<8; i++)
 lcd_envia_byte(1,Pattern [ i ] ); //Pass the bytes of pattern on LCD
}
void Lcd_Imprime_String(char *a)
{
 int i;
 for(i=0;a[i]!='\0';i++)
 lcd_envia_byte(1,a[i]); //Lcd_Print_Char(a[i]);
 //Split the string using pointers and call the Char function
}


Arquivo principal: LCD_expandida

#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock = 20000000)
#ifndef lcd_enable
 #define lcd_enable pin_e1 // pino enable do LCD
 #define lcd_rs pin_e2 // pino rs do LCD
 //#define lcd_rw pin_e2 // pino rw do LCD
 #define lcd_d4 pin_d4 // pino de dados d4 do LCD
 #define lcd_d5 pin_d5 // pino de dados d5 do LCD
 #define lcd_d6 pin_d6 // pino de dados d6 do LCD
 #define lcd_d7 pin_d7 // pino de dados d7 do LCD
#endif

#include "mod_lcd_graphic.c"

//unsigned char Desenho0 [ ] = { 0x0e, 0x0e, 0x04, 0x04, 0x1f, 0x04, 0x0a, 0x0a } ;
unsigned char Desenho1 [ ] = {0b01110,0b01110,0b00100,0b01110,0b10101,0b00100,0b01010,0b01010} ; // Code for CGRAM memory space 1
unsigned char Desenho2 [ ] = {0b00000,0b00000,0b01010,0b00100,0b00100,0b10001,0b01110,0b00000} ; // Code for CGRAM memory space 2
unsigned char Desenho3 [ ] = {0b00100,0b01110,0b11111,0b11111,0b01110,0b01110,0b01010,0b01010} ; // Code for CGRAM memory space 3
unsigned char Desenho4 [ ] = {0b01110,0b10001,0b10001,0b11111,0b11011,0b11011,0b11111,0b00000} ; // Code for CGRAM memory space 4
unsigned char Desenho5 [ ] = {0b01110,0b10000,0b10000,0b11111,0b11011,0b11011,0b11111,0b00000} ; // Code for CGRAM memory space 5
unsigned char Desenho6 [ ] = {0b00000,0b10001,0b01010,0b10001,0b00100,0b01110,0b10001,0b00000} ; // Code for CGRAM memory space 6
unsigned char Desenho7 [ ] = {0b00000,0b00000,0b01010,0b10101,0b10001,0b01110,0b00100,0b00000} ; // Code for CGRAM memory space 7
unsigned char Desenho8 [ ] = {0b11111,0b11111,0b10101,0b11011,0b11011,0b11111,0b10001,0b11111} ; //


void main(){
   
    float valor = 67.3215;
    int i=0;
   
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_psp(PSP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);
    lcd_ini();
    delay_ms(50);
    
    while(TRUE){
      
       printf(lcd_escreve, "\f IFMT - MICROC. \r\n");
       printf (lcd_escreve," LCD -2022 ");
       delay_ms (2000);
       //CriaCaracterEspecial(Desenho0,0); // //
       CriaCaracterEspecial(Desenho1,1); // //
       CriaCaracterEspecial(Desenho2,2); // //
       CriaCaracterEspecial(Desenho3,3); // //
       CriaCaracterEspecial(Desenho4,4); // //
       CriaCaracterEspecial(Desenho5,5); // //
       CriaCaracterEspecial(Desenho6,6); // //
       CriaCaracterEspecial(Desenho7,7); // //
       CriaCaracterEspecial(Desenho8,8); // //
       
       lcd_escreve ('\f'); // Apaga (limpa) o display
       
      //lcd_envia_byte(0,0x86 ) ; //Place cursor at 6th position of first row
      //lcd_envia_byte(1, 1 ) ; //Display Desenho1
      //lcd_envia_byte(1, 2 ) ; //Display Desenho2
      
      for(i=1;i<=8;i++){
         lcd_envia_byte(1, i ) ; //Display Desenho1
      }
      delay_ms (10000);
      
    }
}
 
 
Simulação no PicsimLab




























Simulação no software proteus 7.9








02/04/2022

#Desafio 4 - Biblioteca LCD



Desafio: Acrescentar funções a biblioteca mod_lcd.c e criar uma nova com o nome mod_lcd_plus.c

    1. A biblioteca mod_lcd_plus.c deve ter no mínimo cinco funções a mais que a original sendo que uma delas servira para desenha caracteres definidos pelo usuário. Essa nova função deve chamar lcd_escreve_graphic. As outras quatros funções podem ser definida por você, isto é, você define o nome e o que a função vai fazer. 

    2. Faça um programa para apresentar a nova biblioteca que rode no PICSimLab com a board PICGenios e o PIC 16F877A 

Resolução em CÓDIGO FEITO EM CCS C Compiler

Arquivo: mod_lcd.c

/************************************************************************/
/*  MOD_LCD.C - Biblioteca de manipulação de módulo LCD                 */
/*                                                                      */
/*  Autor: Fábio Pereira                                                */
/*                                                                      */
/************************************************************************/

// As definições a seguir são utilizadas para acesso aos pinos do display
// caso o pino RW não seja utilizado, comente a definição lcd_rw
#ifndef lcd_enable
#define lcd_enable pin_e1 // pino enable do LCD
#define lcd_rs pin_e0 // pino rs do LCD
//#define lcd_rw pin_e2 // pino rw do LCD
#define lcd_d4 pin_d4 // pino de dados d4 do LCD
#define lcd_d5 pin_d5 // pino de dados d5 do LCD
#define lcd_d6 pin_d6 // pino de dados d6 do LCD
#define lcd_d7 pin_d7 // pino de dados d7 do LCD
#endif

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 linhas
#define lcd_seg_lin 0x40    // Endereço da segunda linha na RAM do LCD

// a constante abaixo define a seqüência de inicialização do módulo LCD
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};

byte lcd_le_byte()
// lê um byte do LCD (somente com pino RW)
{
byte dado;
// configura os pinos de dados como entradas
input(lcd_d4);
input(lcd_d5);
input(lcd_d6);
input(lcd_d7);
// se o pino rw for utilizado, coloca em 1
#ifdef lcd_rw
output_high(lcd_rw);
#endif
   output_high(lcd_enable); // habilita display
dado = 0; // zera a variável de leitura
// lê os quatro bits mais significativos
if (input(lcd_d7)) bit_set(dado,7);
if (input(lcd_d6)) bit_set(dado,6);
if (input(lcd_d5)) bit_set(dado,5);
if (input(lcd_d4)) bit_set(dado,4);
// dá um pulso na linha enable
output_low(lcd_enable);
output_high(lcd_enable);
// lê os quatro bits menos significativos
if (input(lcd_d7)) bit_set(dado,3);
if (input(lcd_d6)) bit_set(dado,2);
if (input(lcd_d5)) bit_set(dado,1);
if (input(lcd_d4)) bit_set(dado,0);
output_low(lcd_enable); // desabilita o display
return dado; // retorna o byte lido
}

void lcd_envia_nibble( byte dado )
// envia um dado de quatro bits para o display
{
// coloca os quatro bits nas saidas
output_bit(lcd_d4,bit_test(dado,0));
output_bit(lcd_d5,bit_test(dado,1));
output_bit(lcd_d6,bit_test(dado,2));
output_bit(lcd_d7,bit_test(dado,3));
// dá um pulso na linha enable
output_high(lcd_enable);
output_low(lcd_enable);
}


void lcd_envia_byte( boolean endereco, byte dado )
{
// coloca a linha rs em 0
output_low(lcd_rs);
// aguarda o display ficar desocupado
//while ( bit_test(lcd_le_byte(),7) ) ;
// configura a linha rs dependendo do modo selecionado
output_bit(lcd_rs,endereco);
delay_us(100); // aguarda 100 us
// caso a linha rw esteja definida, coloca em 0
#ifdef lcd_rw
output_low(lcd_rw);
#endif
// desativa linha enable
output_low(lcd_enable);
// envia a primeira parte do byte
lcd_envia_nibble(dado >> 4);
// envia a segunda parte do byte
lcd_envia_nibble(dado & 0x0f);
}


void lcd_ini()
// rotina de inicialização do display
{
byte conta;
output_low(lcd_d4);
output_low(lcd_d5);
output_low(lcd_d6);
output_low(lcd_d7);
output_low(lcd_rs);
#ifdef lcd_rw
output_high(lcd_rw);
#endif
output_low(lcd_enable);
delay_ms(15);
// envia uma seqüência de 3 vezes 0x03
// e depois 0x02 para configurar o módulo
// para modo de 4 bits
for(conta=1;conta<=3;++conta)
{
lcd_envia_nibble(3);
delay_ms(5);
}
lcd_envia_nibble(2);
// envia string de inicialização do display
for(conta=0;conta<=3;++conta) lcd_envia_byte(0,INI_LCD[conta]);
}

void lcd_pos_xy( byte x, byte y)
{
   byte endereco;
   if(y!=1)
    endereco = lcd_seg_lin;
   else
    endereco = 0;
   endereco += x-1;
   lcd_envia_byte(0,0x80|endereco);
}

void lcd_escreve( char c)
// envia caractere para o display
{
   switch (c)
{
     case '\f' : lcd_envia_byte(0,1);
  delay_ms(2);
break;
     case '\n' :
case '\r' : lcd_pos_xy(1,2);
  break;
     case '\b' : lcd_envia_byte(0,0x10);
  break;
     default : lcd_envia_byte(1,c);
  break;
   }
}

char lcd_le( byte x, byte y)
// le caractere do display
{
char valor;
// seleciona a posição do caractere
lcd_pos_xy(x,y);
// ativa rs
output_high(lcd_rs);
// lê o caractere
valor = lcd_le_byte();
// desativa rs
output_low(lcd_rs);
// retorna o valor do caractere
return valor;
}

Arquivo: mod_lcd_graphic

/************************************************************************/
/* MOD_LCD_GRAPHIC.C - Biblioteca de manipulação de módulo LCD ++ */
/* */
/* Autor: Fábio Pereira e Alberto Willian Mascarenhas */
/* */
/************************************************************************/
// Command set for Hitachi 44780U LCD display controller
#define LCD_CLEAR 0x01 // It clears everythings
#define LCD_HOME 0x02 // set the cursor to first line and first row
#define LCD_CURSOR_BACK 0x10 // moves curson one position back
#define LCD_CURSOR_FWD 0x14 //moves curson one position forward
#define LCD_PAN_LEFT 0x18 // used to scroll text left side to scroll text
#define LCD_PAN_RIGHT 0x1C // used to scroll text right side to scroll text
#define LCD_CURSOR_OFF 0x0C // stops display curson on screen
#define LCD_CURSOR_ON 0x0E // turns on cursor display
#define LCD_CURSOR_BLINK 0x0F // curson keeps blinking
#define LCD_CURSOR_LINE2 0xC0 // move curson to scond line or second row
// As definições a seguir são utilizadas para acesso aos pinos do display
// caso o pino RW não seja utilizado, comente a definição lcd_rw
#ifndef lcd_enable
#define lcd_enable pin_e1 // pino enable do LCD
#define lcd_rs pin_e0 // pino rs do LCD
//#define lcd_rw pin_e2 // pino rw do LCD
#define lcd_d4 pin_d4 // pino de dados d4 do LCD
#define lcd_d5 pin_d5 // pino de dados d5 do LCD
#define lcd_d6 pin_d6 // pino de dados d6 do LCD
#define lcd_d7 pin_d7 // pino de dados d7 do LCD
#endif
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 linhas
#define lcd_seg_lin 0x40 // Endereço da segunda linha na RAM do LCD
// a constante abaixo define a seqüência de inicialização do módulo LCD
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};
byte lcd_le_byte()
// lê um byte do LCD (somente com pino RW)
{
byte dado;
// configura os pinos de dados como entradas
input(lcd_d4);
input(lcd_d5);
input(lcd_d6);
input(lcd_d7);
// se o pino rw for utilizado, coloca em 1
#ifdef lcd_rw
output_high(lcd_rw);
#endif
 output_high(lcd_enable); // habilita display
dado = 0; // zera a variável de leitura
// lê os quatro bits mais significativos
if (input(lcd_d7)) bit_set(dado,7);
if (input(lcd_d6)) bit_set(dado,6);
if (input(lcd_d5)) bit_set(dado,5);
if (input(lcd_d4)) bit_set(dado,4);
// dá um pulso na linha enable
output_low(lcd_enable);
output_high(lcd_enable);
// lê os quatro bits menos significativos
if (input(lcd_d7)) bit_set(dado,3);
if (input(lcd_d6)) bit_set(dado,2);
if (input(lcd_d5)) bit_set(dado,1);
if (input(lcd_d4)) bit_set(dado,0);
output_low(lcd_enable); // desabilita o display
return dado; // retorna o byte lido
}
void lcd_envia_nibble( byte dado )
// envia um dado de quatro bits para o display
{
// coloca os quatro bits nas saidas
output_bit(lcd_d4,bit_test(dado,0));
output_bit(lcd_d5,bit_test(dado,1));
output_bit(lcd_d6,bit_test(dado,2));
output_bit(lcd_d7,bit_test(dado,3));
// dá um pulso na linha enable
output_high(lcd_enable);
output_low(lcd_enable);
}
void lcd_envia_byte( boolean endereco, byte dado )
{
// coloca a linha rs em 0
output_low(lcd_rs);
// aguarda o display ficar desocupado
//while ( bit_test(lcd_le_byte(),7) ) ;
// configura a linha rs dependendo do modo selecionado
output_bit(lcd_rs,endereco);
delay_us(100); // aguarda 100 us
// caso a linha rw esteja definida, coloca em 0
#ifdef lcd_rw
output_low(lcd_rw);
#endif
// desativa linha enable
output_low(lcd_enable);
// envia a primeira parte do byte
lcd_envia_nibble(dado >> 4);
// envia a segunda parte do byte
lcd_envia_nibble(dado & 0x0f);
}
void lcd_ini()
// rotina de inicialização do display
{
byte conta;
output_low(lcd_d4);
output_low(lcd_d5);
output_low(lcd_d6);
output_low(lcd_d7);
output_low(lcd_rs);
#ifdef lcd_rw
output_high(lcd_rw);
#endif
output_low(lcd_enable);
delay_ms(15);
// envia uma seqüência de 3 vezes 0x03
// e depois 0x02 para configurar o módulo
// para modo de 4 bits
for(conta=1;conta<=3;++conta)
{
lcd_envia_nibble(3);
delay_ms(5);
}
lcd_envia_nibble(2);
// envia string de inicialização do display
for(conta=0;conta<=3;++conta) lcd_envia_byte(0,INI_LCD[conta]);
}
void lcd_pos_xy( byte x, byte y)
{
 byte endereco;
 if(y!=1)
 endereco = lcd_seg_lin;
 else
 endereco = 0;
 endereco += x-1;
 lcd_envia_byte(0,0x80|endereco);
}
void lcd_escreve( char c)
// envia caractere para o display
{
 switch (c)
{
 case '\f' : lcd_envia_byte(0,1);
 delay_ms(2);
break;
 case '\n' :
case '\r' : lcd_pos_xy(1,2);
 break;
 case '\b' : lcd_envia_byte(0,0x10);
 break;
 default : lcd_envia_byte(1,c);
 break;
 }
}
char lcd_le( byte x, byte y)
// le caractere do display
{
char valor;
// seleciona a posição do caractere
lcd_pos_xy(x,y);
// ativa rs
output_high(lcd_rs);
// lê o caractere
valor = lcd_le_byte();
// desativa rs
output_low(lcd_rs);
// retorna o valor do caractere
return valor;
}
//-----------------------------------------------------------------
//
// Funções adicionadas por Alberto Willian Mascarenhas
//
//-----------------------------------------------------------------
void CriaCaracterEspecial (unsigned char *Pattern, char Location)
{
 int i=0;
 lcd_envia_byte(0,0x40+(Location*8)); //Send the Address of CGRAM
 for (i=0; i<8; i++)
 lcd_envia_byte(1,Pattern [ i ] ); //Pass the bytes of pattern on LCD
}
void Lcd_Imprime_String(char *a)
{
 int i;
 for(i=0;a[i]!='\0';i++)
 lcd_envia_byte(1,a[i]); //Lcd_Print_Char(a[i]);
 //Split the string using pointers and call the Char function
}

Arquivo principal: LCD expandida

//EXEMPLO RETIRADO DO LIVRO
#include <16F877A.h>
#device adc = 8
// Uma animação simples no display
//#include <16f877.h>
#use delay(clock = 20MHz)
#fuses HS,NOWDT,PUT,NOBROWNOUT,NOLVP
#include <mod_lcd.c>

void main(){
   char k;
   
   setup_adc_ports(no_analogs); // desliga as entradas analógicas
   lcd_ini();
   // configura registrador AC para o endereço inicial da CGRAM
   lcd_envia_byte(0,0x40);
   lcd_envia_byte(1,0x04); // primeira linha do primeiro caractere
   lcd_envia_byte(1,0x0e); // segunda linha do primeiro caractere
   lcd_envia_byte(1,0x15); // terceira linha do primeiro caractere
   lcd_envia_byte(1,0x04); // quarta linha do primeiro caractere
   lcd_envia_byte(1,0x04); // quinta linha do primeiro caractere
   lcd_envia_byte(1,0x04); // sexta linha do primeiro caractere
   lcd_envia_byte(1,0x04); // sétima linha do primeiro caractere
   lcd_envia_byte(1,0x00); // oitava linha do primeiro caractere
   lcd_envia_byte(1,0x00); // primeira linha do segundo caractere
   lcd_envia_byte(1,0x04); // segunda linha do segundo caractere
   lcd_envia_byte(1,0x0e); // terceira linha do segundo caractere
   lcd_envia_byte(1,0x15); // quarta linha do segundo caractere
   lcd_envia_byte(1,0x04); // quinta linha do segundo caractere
   lcd_envia_byte(1,0x04); // sexta linha do segundo caractere
   lcd_envia_byte(1,0x04); // sétima linha do segundo caractere
   lcd_envia_byte(1,0x00); // oitava linha do segundo caractere
   
   // registrador AC aponta para a primeira coluna da segunda linha
   lcd_envia_byte(0,0xC0);

   while(TRUE){
      
      // registrador AC aponta para a primeira coluna da segunda linha
      lcd_envia_byte(0,0xC0);
      // imprime o primeiro caractere do usuário
      lcd_envia_byte(1,0x00);
      delay_ms(300);
      // registrador AC aponta para a primeira coluna da segunda linha
      lcd_envia_byte(0,0xC0);
      // imprime o segundo caractere do usuário
      lcd_envia_byte(1,0x01);
      delay_ms(300);
      
   }
}