Pesquisar neste blog

16/05/2022

Memória Externa RS232 Long e Float com PIC 16F877A

Código feito no CCS C Compiler

#include <16F877A.h>
#device adc = 8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //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 NOBROWNOUT //No brownout reset
#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 = 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"

#include "2404.C"
   long int End_HL(byte H, byte L){
   return (H<<8)+ L;
}
char* IntToHex(int value) {
   int a;
   int b;
   char* buffer;
   a = value && 16;
   b = (value>>4)&16;
   buffer[0] = (a<10)?'0'+a:'A'-(a-10);
   buffer[1] = (b<10)?'0'+b:'A'-(b-10);
   return buffer;
}
WRITE_FLOAT_EXT_EEPROM(long int n, float data) {
   int i;

   for (i = 0; i < 4; i++)
      write_ext_eeprom(i + n, *((int8*)&data + i) ) ;
}
float READ_FLOAT_EXT_EEPROM(long int n) {
   int i;
   float data;

   for (i = 0; i < 4; i++)
      *((int8*)&data + i) = read_ext_eeprom(i + n);
      return(data);
}
void eeprom_int16(unsigned int endereco, int16 valor_i16){
   write_ext_eeprom(endereco, make8(valor_i16,0));
   write_ext_eeprom(endereco+1, make8(valor_i16,1));
}
int16 read_int16_ext_eeprom(long int endereco) {
   int a, b;
   int16 valor;
   a = read_ext_eeprom(endereco);
   b = read_ext_eeprom(endereco + 1);
   valor = make16(b, a);
   return valor;
}
void main() {
   byte dispositivo1,dispositivo2;
   unsigned int8 a,b,c,d;
   unsigned int endereco;
   int16 Temperatura;
   float pressao = 21.37f;
   float result_f;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_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(); // Inicializa LCD
   delay_ms(10);
   init_ext_eeprom();
   delay_ms(10);

   printf (lcd_escreve,"\f iniciando...");
   delay_ms(2000);

   while (true){
      write_ext_eeprom(0x1, 6);
      write_ext_eeprom(0x2, 9);
      write_ext_eeprom(3, 12);
      write_ext_eeprom(4, 40);
      write_ext_eeprom(5, 50);
      write_ext_eeprom(6, 60);
      write_ext_eeprom(7, 70);

      Temperatura = 730;
      endereco = 8;
      eeprom_int16(endereco,Temperatura);

      endereco = 10;
      WRITE_FLOAT_EXT_EEPROM(endereco,pressao);
      printf(lcd_escreve,"\fValor: %d",read_ext_eeprom(0x2 ));
      printf(lcd_escreve,"\r\nValor: %d",read_ext_eeprom(4));
      delay_ms(3000);
      //a = read_ext_eeprom(8);  
      //b = read_ext_eeprom(9);
      //printf(lcd_escreve,"\fTemp.: %lu",make16(b,a));

      printf(lcd_escreve,"\fTemp.: %lu", read_int16_ext_eeprom(8));
      delay_ms(3000);
   
      result_f = READ_FLOAT_EXT_EEPROM(10);
      printf(lcd_escreve,"\fPressao: %.1f", result_f);
      delay_ms(3000);

   }
}

Software: PicsimLab


14/05/2022

Memória Externa RS232 com PIC 16F877A

Código feito no CCS C Compiler

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 20MHz)
#use rs232(baud = 9600, xmit = PIN_C6, rcv = PIN_C7)
#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"
//#include "input.c"
#include "2401.c"

void main() {
   BYTE value,value_recebido, cmd;
   EEPROM_ADDRESS address;
   unsigned int8 i = 0;
   init_ext_eeprom();
   lcd_ini();
   delay_us(50);
   // TODO: USER CODE!!
   printf (lcd_escreve,"\f iniciando...");
   delay_ms(2000);

   for(i = 0; i <= 128; i++){
      WRITE_EXT_EEPROM(i, 255 );
      WRITE_EXT_EEPROM(0, 8 ); 
      WRITE_EXT_EEPROM(1, 7);
      WRITE_EXT_EEPROM(2, 'P');
      WRITE_EXT_EEPROM(3, 'A');
      WRITE_EXT_EEPROM(4, 55);
      //WRITE_EXT_EEPROM(1, 7); //valores repetidos
   }
   value_recebido = READ_EXT_EEPROM(0);

   while(true){
      printf (lcd_escreve,"\f IFMT ");
      //printf("\n\rTemp = %d", value);
      printf (lcd_escreve,"\n\rValor: %i %c", value_recebido, value_recebido);
      delay_ms(2000);
   }
}

Saída gerada no Software PicsimLab























13/05/2022

Memória interna RS232 com PIC 16F877A

Código feito no CCS C Compiler

#include <16F877A.h>
#device adc = 8
#FUSES NOWDT   //Sem temporizador de vigilância
#FUSES HS      //Crystal osc <= 4 mhz para PCM/PCH, 3 mhz a 10 mhz para
#FUSES NOPUT   //Sem temporizador de inicialização
#FUSES NOPROTECT //Código não protegido contra leitura
#FUSES NODEBUG    //Sem modo de depuração para ICD
#FUSES BROWNOUT   //Redefinir quando o brownout for detectado
#FUSES NOLVP      //Sem progamação de baixa tensão, B3(PIC16) ou B5(PIC18) usado para E/S
#FUSES NOCPD      //No EE protection
#FUSES NOWRT      //Memória de programa não protegida contra gravação
#use delay(clock = 20MHz)

#use rs232(baud = 9600, parity = N, xmit = PIN_C6, rcv = PIN_C7, bits = 8)

#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"

void main(){
   unsigned int8 result = 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_us(50);
   // TODO: USER CODE!!
   printf (lcd_escreve,"\f iniciando...");
   delay_ms(2000);

   write_eeprom(0,'A'); // 0x41
   write_eeprom(1,221); //
   write_eeprom(2,'9'); //
   write_eeprom(3,'D'); //
   
   result = read_eeprom(2);

   while(true){
      printf (lcd_escreve,"\f IFMT ");
      //printf("\n\rTemp = %d", value);
      printf (lcd_escreve,"\n\rValor: %u %c", result, result); //imprimi o valor ASCII, seu caracter
      delay_ms(2000);
   }
}

Saída gerada no PicsimLab























Saída gerada no software Proteus 7.9




07/05/2022

Converter ADC em voltagem com PIC 16F877A

Objetivo: Receber um valor analógico através do potenciômetro, converter esse valor para tensão e exibir seus dados no LCD usando microcontrolador PIC 16F877A.

Código feito em CCS C Compiler

#include <16F877A.h>
#device adc = 8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT, NOWRT
#use delay(clock = 20MHz)
#include <lcd.c>

unsigned int8 analog;
float tensao ;

void main(){
   setup_adc(ADC_CLOCK_DIV_32);           // Set ADC conversion time to 32Tosc
   setup_adc_ports(AN0_AN1_AN3);          // Configure AN0,AN1 and AN3 as analog   
   setup_ccp2(CCP_PWM);                   // Configure CCP2 as a PWM
   setup_timer_2(T2_DIV_BY_16, 255, 1);   // Set PWM frequency to 488Hz
   set_adc_channel(0);                    // Select channel AN1   
   
   lcd_init();
   
   while(true) {
      analog = read_adc();
      tensao = (5.0 / 255.0) * analog; // 5V , (2^8) - 1 = 255
      
      printf(lcd_putc,"\fADC = %u\nTensao = %01.2f V",analog, tensao);
      delay_ms(100);
   }
}

Software Proteus versão 7.9




























Palavras chave:

Convert ADC to Voltage with PIC 16F877A
U beddelo ADC Voltage PIC 16F877A
Konwertuj ADC na napięcie za pomocą PIC 16F877A
Převeďte ADC na napětí pomocí PIC 16F877A
Konverter ADC til spenning med PIC 16F877A
Ngonversi ADC kanggo Tegangan karo PIC 16F877A
המר ADC למתח עם PIC 16F877A
Convertir ADC en tension avec PIC 16F877A
Преобразование АЦП в напряжение с помощью PIC 16F877A
Konvertera ADC till spänning med PIC 16F877A
PIC 16F877A를 사용하여 ADC를 전압으로 변환
Converteix ADC a voltatge amb PIC 16F877A
Tionndaidh ADC gu Voltage le PIC 16F877A

04/05/2022

Gerar frequência de 1KHz com PIC 16F877A

Exemplo1: Gere um sinal quadrado de 1KHz usando a interrupção do TEMPORIZADOR 0

Solução
Para 1KHz é necessário meio período de 500 us. De acordo com a equação de K overflow, usando um cristal de 4 MHz e um prescaler de 2

T = Tcm. Preescaler. (256 - Carregar TMR0)
500 us = (4/4000000).2.(256 - x)
x = 6 *

Código feito em CCS C Compiler

#include <16F877A.h>
#use delay(crystal = 4MHz)
#fuses XT, NOWDT
#use standard_io(B)

#int_TIMER0
void  RTCC_isr(void) {
  output_toggle(PIN_B0);
  set_timer0(0x1B);
}

void main(){
     
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); 
   set_timer0(0x1B);
   enable_interrupts(INT_TIMER0); // habilita a chave timer0
   enable_interrupts(GLOBAL);   // habilita a chave geral

   while(TRUE) ; 

}











02/05/2022

Query SQL em ordem crescente no google sheets

Objetivo: Selecionar usando SQL do google sheets apenas os dados ADM em ODEM CRESCENTE.

Resolução:

Inserindo os dados no excel e digitando ao lado com a tecla de comando CTL + E



Comando no google sheets:

=QUERY(F1:G14;"select F where G = 'ADM' order by F asc")

Resultado gerado






















Palavras chave:

Query SQL in ascending order on google sheets
שאילתות SQL בסדר עולה ב-google sheets
Query SQL kanthi urutan munggah ing lembaran google
Запрос SQL в порядке возрастания на листах Google
Dotaz SQL ve vzestupném pořadí na google listech
Googleスプレッドシートで昇順でSQLをクエリする
Запыт SQL у парадку ўзрастання на табліцах Google
Consulteu SQL en ordre ascendent als fulls de Google

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);
      
   }
}


















20/03/2022

Mini teste 1 - 2022/1

Projete um sistema com microcontrolador PIC (circuitos necessários para o microcontrolador funcionar) para funcionar da seguinte forma: 
quando o usuário do micro-ondas (figura 1) apertar o botão INÍCIO (primeira vez) o micro-ondas começa uma contagem decrescente de 30 para zero; se o usuário apertar novamente antes da contagem chegar a zero ele soma mais trinta a contagem atual e continua a contagem decrescente. Quando chegar em zero para a contagem e liga um LED OBS.: o circuito deve ter a os conectores para gravação; circuito do oscilador; alimentação; circuito do LED; circuito do botão e circuito para display de sete seguimentos.













Resolução:

CÓDIGO FEITO EM CCS C Compiler

#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 = 20MHz)

unsigned int cont_int = 0;
unsigned int tempo = 0, i =0;
int1 mostra_UD = 0;

byte const numeros[11] ={
 0b00111111, //0
 0b00000110, //1
 0b01011011, //2
 0b01001111, //3
 0b01100110, //4
 0b01101101, //5
 0b01111101, //6
 0b00000111, //7
 0b01111111, //8
 0b01101111 //9
 };

#int_RTCC
void RTCC_isr(void){
   
   if(++cont_int>154){
      //output_toggle(PIN_B5);
      tempo--;
      cont_int = 0;
   }
 
   if(mostra_UD==0){
      mostra_UD=1;
      i = tempo/10;
      output_d(numeros[i]);
      output_high(PIN_A4);
      output_low(PIN_A5);
   }else{
      mostra_UD=0;
      i = tempo%10;
      output_d(numeros[i]);
      output_low(PIN_A4);
      output_high(PIN_A5);
   }

 
   if(tempo==0){
      disable_interrupts(INT_RTCC);
      output_high(PIN_B6); //liga o buzzer
      
      delay_ms(2000);
      output_low(PIN_B6); //desliga o buzzer
   }
}
#int_EXT
void EXT_isr(void){
   enable_interrupts(INT_RTCC);
   tempo = tempo + 30;
   output_toggle(PIN_B4);
}



void main(){
   
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   // Programa o Timer0
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128); // overflow vai ser com 6,5ms

   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // Habilita/desabilita as interrupções do Timer0 e externa (b0)
   disable_interrupts(INT_RTCC);
   enable_interrupts(INT_EXT);

   ext_int_edge( L_TO_H );
   enable_interrupts(GLOBAL);

   // Apaga os display 7 segmentos
   output_low(PIN_A2);
   output_low(PIN_A3);
   output_low(PIN_A4);
   output_low(PIN_A5);
   output_low(PIN_B6); //desliga o buzzer

   while(true){
   };
}
 
Software: PicsimLab