Ir ao conteúdo
  • Cadastre-se
Reipas

Pic16f877a + max6675

Posts recomendados

Olá, estou tendo problemas em criar um programa em CCS para  um termometro com pic16f877a e o max6675. Estou usando um código postado  aqui no fórum pelo  Fervolt com as inclusões  do pic  , do cristal e do LCD. Conforme ele sugeriu.Mas não consigo fazer funcionar. Alguem poderia me ajudar.

16f877a+ max6675.txt

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Reipas

 

Não funciona nada? tipo, o PIC não liga? não aparece a mensagem inicial no display(***TERMOMETRO***      MAX6675)?

 

A primeira coisa que você tem que ter certeza é de que seu PIC está ligando e está configurado corretamente, um teste básico seria colocar um led pra piscar a cada segundo, se não piscar ou se piscar muito rápido ou lento, tem que analisar as configurações. Seja mais específico para tentarmos te ajudar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite Vinicius !

Obrigado pelo retorno .Sim aparece a mensagem inicial no display mais nada. Coloquei outra mensagem abaixo(fora do void main () ) e o display não muda.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Alguém mais pode ter preguiça (=eu) de clicar no texto. Incorpore-o no tópico e se for muito grande use "spoiler". E não te esqueças de publicar o esquemático.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Reipas

 

Seu código está faltando coisas, isso porque estou julgando que estas funções de comunicação estejam corretas, por exemplo, no void main() não está chamando nada além do texto no display, veja como está:

 

void main ()
{
	LCD_INIT();//inicializa o display

	printf(lcd_putc,"\f ***TERMOMETRO***\n      MAX6675  " );//escreve no display

}

 

Do jeito que está, seu sistema vai simplesmente escrever no display e depois sai sem fazer mais nada, o correto seria assim:

 

void main ()
{
	LCD_INIT();//inicializa o display

	printf(lcd_putc,"\f ***TERMOMETRO***\n      MAX6675  " ); //escreve no display
	delay_ms(2000);//faz uma pausa de 2 seg
  	while(1){//entra em um laço eterno, sempre repetindo o que estiver aqui dentro
      int16 leitura = read_TC();//faz a leitura no CI
      printf(lcd_putc,"\f Temperatura:%d",leitura ); //escreve no display o valor da leitura
      delay_ms(1000);//faz uma pausa de 1 seg antes de repetir tudo novamente
    }
 
}

Pra começar, corrige isso aí.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá,

Tente esse código.

 

termostato.h

//Processador usado
#include <16F628A.h>

//Fusíveis de configuração do processador
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT
#FUSES PUT                      //Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES NOBROWNOUT               //No brownout reset
#FUSES MCLR
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
//#FUSES RESERVED                 //Used to set the reserved FUSE bits

//Frequencia de trabalho = 4 MHz
#use delay(clock=4000000)

 

main.c

#include <termostato.h>
#include <lcd.h>

#define TC_DATA      PIN_A0
#define TC_CLK       PIN_A1
#define TC_CS        PIN_A2

#include <max6675.c>


//*********** Rotina principal **************//
void main(){ 
 setup_comparator(NC_NC_NC_NC);

 //Inicializa LCD
 lcd_ini();
 
//****************** LOOP PRINCIPAL ********************
    while(true){
      
      limpa_tela();
               
      linha_1(1);
      printf(lcd_escreve,"Temp: %Lu", do_everything());
      lcd_envia_byte(1,0xdf); //simbolo grau °
      printf(lcd_escreve, "C  ");
      cursor(0);
      delay_ms(1000);
    }
//**************** FIM LOOP PRINCIPAL ******************

} 

 

 

 max6675.c

int1 thermocouple_error;         //a handy dandy global error flag to tell you if a thermocouple is connected or not

void init_TC(void){
   output_low(TC_CLK);
   output_low(TC_DATA);
   output_high(TC_CS);            //if we idle high, the chip keeps doing conversions. Change this if you like
}

int16 read_TC(void){              //It takes 200ms (ish) for the MAX6675 to perform a conversion
   int8 i;
   int16 data;

   output_low(TC_CS);            //stop any conversion processes
   delay_us(1);               //and give it some time to power up (not very much, admittedly)

   for (i=0;i<16;i++){
      output_high(TC_CLK);
      delay_us(1);
      output_low(TC_CLK);
      shift_left(&data,2,input(TC_DATA));      //reads in 2 bytes to data from the pin TC_DATA
   }

   thermocouple_error=bit_test(data,2);      //this is the thermocouple status bit
      
   output_high(TC_CS);
   return(data);
}

int16 sortout(int16 raw){
    return(0x0FFF & (raw>>4));      //returns only the bits converning temperature
}

//float toFloat_TC(int16 tmp){
//   return((float)tmp/4.0);      //adjusts data to floating point format, and accounts for the decimal point
//}

int16 do_everything(void){
   init_TC();
   delay_ms(200);               //200ms is a long time to be doing nothing. use a timer interrupt to avoid wasting time here
   return(sortout(read_TC()) / 4);
}

 

lcd.h

//Biblioteca para manipulação do módulo LCD Alfanumérico
//16 caracteres x 2 linhas

//LCD
#define lcd_enable     pin_b1      // pino enable do LCD
#define lcd_rs         pin_B0      // pino rs do LCD
#define lcd_d4         pin_B2      // pino de dados d4 do LCD
#define lcd_d5         pin_B3      // pino de dados d5 do LCD
#define lcd_d6         pin_B4      // pino de dados d6 do LCD
#define lcd_d7         pin_B5      // pino de dados d7 do LCD

//Define tipo de caracter a ser impresso
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 linhas

//Contante do tipo
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};


void lcd_envia_nibble( byte dado ){
   //delay_ms(1);
   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));
   output_high(lcd_enable);
   delay_us(500);
   output_low(lcd_enable);
}

void lcd_envia_byte( boolean endereco, byte dado ){
   output_low(lcd_rs);
   output_bit(lcd_rs,endereco);  
   output_low(lcd_enable);
   lcd_envia_nibble(dado >> 4);
   lcd_envia_nibble(dado & 0x0f);
}  

void lcd_escreve(char c){
     lcd_envia_byte(1,c);
 }  

void cursor(int temp){
   int dado = 0x0E;   
   if(!temp){
      dado = dado - 2;
   }
   lcd_envia_byte(0,dado);
}   

void limpa_tela(){
   lcd_envia_byte(0,0x01); //limpa tela
   delay_ms(2);
}

void linha_1(int adr){
   if(!adr){
      adr = 0x80;
   }else{
      adr = 0x80 + adr;
   }   
   lcd_envia_byte(0,adr);
}

void linha_2(int adr){
   if(!adr){
      adr = 0xC0;
   }else{
      adr = 0xC0 + adr;
   }   
   lcd_envia_byte(0,adr);
}

void lcd_ini(){
   byte conta;
   output_low(lcd_d4);
   output_low(lcd_d5);
   output_low(lcd_d6);
   output_low(lcd_d7);
   output_low(lcd_rs);
   
   output_low(lcd_enable);
   delay_ms(15);
   
   for(conta=1;conta<=3;++conta){
      lcd_envia_nibble(3);
      delay_ms(2);
   }
   lcd_envia_nibble(2);
   for(conta=0;conta<=3;++conta){
      lcd_envia_byte(0,INI_LCD[conta]);
      delay_ms(2);
   }
   cursor(0);
}

 

 

 

Att,

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 02/02/2017 às 15:18, Fervolt disse:

Olá,

Tente esse código.

 

termostato.h


//Processador usado
#include <16F628A.h>

//Fusíveis de configuração do processador
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT
#FUSES PUT                      //Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES NOBROWNOUT               //No brownout reset
#FUSES MCLR
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
//#FUSES RESERVED                 //Used to set the reserved FUSE bits

//Frequencia de trabalho = 4 MHz
#use delay(clock=4000000)

 

main.c


#include <termostato.h>
#include <lcd.h>

#define TC_DATA      PIN_A0
#define TC_CLK       PIN_A1
#define TC_CS        PIN_A2

#include <max6675.c>


//*********** Rotina principal **************//
void main(){ 
 setup_comparator(NC_NC_NC_NC);

 //Inicializa LCD
 lcd_ini();
 
//****************** LOOP PRINCIPAL ********************
    while(true){
      
      limpa_tela();
               
      linha_1(1);
      printf(lcd_escreve,"Temp: %Lu", do_everything());
      lcd_envia_byte(1,0xdf); //simbolo grau °
      printf(lcd_escreve, "C  ");
      cursor(0);
      delay_ms(1000);
    }
//**************** FIM LOOP PRINCIPAL ******************

} 

 

 

 max6675.c


int1 thermocouple_error;         //a handy dandy global error flag to tell you if a thermocouple is connected or not

void init_TC(void){
   output_low(TC_CLK);
   output_low(TC_DATA);
   output_high(TC_CS);            //if we idle high, the chip keeps doing conversions. Change this if you like
}

int16 read_TC(void){              //It takes 200ms (ish) for the MAX6675 to perform a conversion
   int8 i;
   int16 data;

   output_low(TC_CS);            //stop any conversion processes
   delay_us(1);               //and give it some time to power up (not very much, admittedly)

   for (i=0;i<16;i++){
      output_high(TC_CLK);
      delay_us(1);
      output_low(TC_CLK);
      shift_left(&data,2,input(TC_DATA));      //reads in 2 bytes to data from the pin TC_DATA
   }

   thermocouple_error=bit_test(data,2);      //this is the thermocouple status bit
      
   output_high(TC_CS);
   return(data);
}

int16 sortout(int16 raw){
    return(0x0FFF & (raw>>4));      //returns only the bits converning temperature
}

//float toFloat_TC(int16 tmp){
//   return((float)tmp/4.0);      //adjusts data to floating point format, and accounts for the decimal point
//}

int16 do_everything(void){
   init_TC();
   delay_ms(200);               //200ms is a long time to be doing nothing. use a timer interrupt to avoid wasting time here
   return(sortout(read_TC()) / 4);
}

 

lcd.h


//Biblioteca para manipulação do módulo LCD Alfanumérico
//16 caracteres x 2 linhas

//LCD
#define lcd_enable     pin_b1      // pino enable do LCD
#define lcd_rs         pin_B0      // pino rs do LCD
#define lcd_d4         pin_B2      // pino de dados d4 do LCD
#define lcd_d5         pin_B3      // pino de dados d5 do LCD
#define lcd_d6         pin_B4      // pino de dados d6 do LCD
#define lcd_d7         pin_B5      // pino de dados d7 do LCD

//Define tipo de caracter a ser impresso
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 linhas

//Contante do tipo
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};


void lcd_envia_nibble( byte dado ){
   //delay_ms(1);
   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));
   output_high(lcd_enable);
   delay_us(500);
   output_low(lcd_enable);
}

void lcd_envia_byte( boolean endereco, byte dado ){
   output_low(lcd_rs);
   output_bit(lcd_rs,endereco);  
   output_low(lcd_enable);
   lcd_envia_nibble(dado >> 4);
   lcd_envia_nibble(dado & 0x0f);
}  

void lcd_escreve(char c){
     lcd_envia_byte(1,c);
 }  

void cursor(int temp){
   int dado = 0x0E;   
   if(!temp){
      dado = dado - 2;
   }
   lcd_envia_byte(0,dado);
}   

void limpa_tela(){
   lcd_envia_byte(0,0x01); //limpa tela
   delay_ms(2);
}

void linha_1(int adr){
   if(!adr){
      adr = 0x80;
   }else{
      adr = 0x80 + adr;
   }   
   lcd_envia_byte(0,adr);
}

void linha_2(int adr){
   if(!adr){
      adr = 0xC0;
   }else{
      adr = 0xC0 + adr;
   }   
   lcd_envia_byte(0,adr);
}

void lcd_ini(){
   byte conta;
   output_low(lcd_d4);
   output_low(lcd_d5);
   output_low(lcd_d6);
   output_low(lcd_d7);
   output_low(lcd_rs);
   
   output_low(lcd_enable);
   delay_ms(15);
   
   for(conta=1;conta<=3;++conta){
      lcd_envia_nibble(3);
      delay_ms(2);
   }
   lcd_envia_nibble(2);
   for(conta=0;conta<=3;++conta){
      lcd_envia_byte(0,INI_LCD[conta]);
      delay_ms(2);
   }
   cursor(0);
}

 

 

 

Att,

Esse codigo é compatível com pic 18F? preciso de ajuda pra programar um controlador de temperatura

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Reginaldo_As

 

Sim, é compatível.

Só observar os "defines" dos pinos e compilar com CCS C Compiler.

 

Att,

  • Curtir 1
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Fervolt Bom dia! 

Você tem esse projeto salvo?

Poderia ajudar a implementar um controle PID nele para controle de temperatura, acionando um opto acoplador que controla  um TRIAC? Não estou sabendo como criar os arquivos <termostato.h>  e <lcd.h> que serão importados na compilação do Main ... O arquivo  max6675.c é compilado a parte ou junto com o  main?

 

Tenho um kit desenvolvimento com 18F4550 e também o CI do PIC16F628A, poderia implementar em um deles... Não consigo mandar mensagem direto, como faço pra falar direto com você, pode deixar seu contato?

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Reginaldo_As

 

Só criar arquivos de texto, colocar os respectivos nomes com suas extensões e salvar na pasta do projeto.

Entra no CCS, vai em novo projeto, e importa os arquivos criados.

 

Att,

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 03/12/2019 às 07:53, Reginaldo_As disse:

Poderia ajudar a implementar um controle PID nele para controle de temperatura, acionando um opto acoplador que controla  um TRIAC?

 

Você está ciente da teoria do PID ?

 

Porque terá de determinar os parâmetros do P, do I, e do D , que são sempre particulares para a sua aplicação, e levam em conta o comportamento de sua resistência de aquecimento ( e o seu sistema de acionamento via Triac ) , o volume de água, a dissipação da estrutura que envolve a água, etc.

 

O ajuste esses parâmetros sempre é empírico.

 

Olhe aqui :

https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en020434

 

Paulo

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Paulão

Penso que são muitos dados pra alimentar o pid manualmente e de fato isso é um saco.

Tem uns controladores pid que tem uma função algo como "autotuning". Já ouviu falar? Eu sempre quis saber como ela atua. Teorizo que ela adapta o pid à "realidade do momento" do sistema. Teoricamente isso é lindo.

Só sei que na função autotuning o sistema fica trabalhando em on-off. Teorizo que fica registrando as temperaturas, tempo que levou a chegar a ela, qual valor passou devido à inércia térmica, pra qual caiu. etc. Depois disso registrado ele ativa o pid baseado nisso. Lindo né? Queria saber como ele faz os ajustes...

Bem.. pelo menos fica a semente.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...