Fórum

PIC16F628A E SENSOR...
 
Notifications
Clear all

PIC16F628A E SENSOR DS18B20 – VERSÃO DISPLAY DE 7 SEGUIMENTOS para 16F870

9 Posts
2 Users
0 Likes
1,685 Leituras
(@thalis)
Active Member
Joined: 5 anos ago
Posts: 10
Topic starter  

Boa tarde

POderia me auxiliar modifiquei seu programa para usar com uma placa que tenho, mas nao consegui fazer a varredura funcionar 

no pic 16F870. Segue o programa abaixo, estou usando os segmentos nos pinos RB7a RB0, e acionamento em nivel baixo dos transistores BC558 sao na porta C3 a C0.

desde ja agradeço


   
Quote
(@thalis)
Active Member
Joined: 5 anos ago
Posts: 10
Topic starter  

Opa, esqueci do programa:

// http://larios.tecnologia.ws/iBlog/archives/5512

//***************************************************************************
//
// Termometro com DS18B20
//
// Objetivo: Medir temperatura com DS18B20 (Maxim)
// Utiliza um pic 16f628a e 4 display de 7 seguimentos (anodo comum)
//
// Cláudio Lários Data:16/03/2014
//
// DS18B20 em modo normal, com alimentação de 5 volts.
// Faixa de medição: -55 a 125 °C
// Tempo de conversão : 750 ms.

// Aplicação: Visualizar temperatura ambiente, de freezer, geladeiras em
// mercados, aquários, estufas e outros usos.
// (Atenção: Somente visualiza! Não controla!)
// Material para uso didático apenas.
//
//************************************************************************
#include <16F870.h>
#fuses HS,NOWDT,PUT,NOLVP,NOPROTECT, NOBROWNOUT, WRT
#priority timer0
//INTRC_IO, NOMCLR
//
***************************************************************************
//

//frequência do PIC
#use delay(clock=4000000) //tempo por instrução=1us
//bytes
//#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
//#byte trisa = 0x85
#byte trisb = 0x86
#byte trisc = 0x00

#bit gie = 0x8b.7
#bit peie = 0x8b.6
#bit t0ie = 0x8b.5

//bits
#bit dq = 0X5.0 //PINO 2 - entrada sinal do DS18B20
#bit trisdq = 0X85.0
#bit ponto= 0x06.7

//variáveis globais
int dig3,dig2,dig1,dig0,mux;
short neg;
int buffer[2]={0,0};

//tabelas
// retorna 0 1 2 3 4 5 6 7 8 9 10 (-)
byte const tabela [] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
byte const tabela_neg[]={ 0,1,1,2,3,3,4,5,6,6,6,7,8,8,9,9};

//==============================================================================
// ROTINA DE INTERRUPÇÃO DO TIMER 0
//==============================================================================

#int_timer0

//multiplexa display de 7 seg
void display_refress() {

if(++mux>3){ mux=0;}
portc=1; //apaga seguimentos para mudança
switch (mux) {//escolhe digito a ser apresentado (elimina zeros a direita)
case 0:
portb=tabela[dig0]; portc=0b11111110; break;
case 1:
if ((dig3)||(dig2)||(dig1)){portb=tabela[dig1]; ponto=0; portc=0b11111101; break;} //
case 2:
if ((dig3)||(dig2)){portb=tabela[dig2]; portc=0b11111011; break;}
case 3:
if (dig3){portb=tabela[dig3]; portc=0b11110111; break;}

}
}
//==============================================================================
// ROTINA DE RESET 1W
//==============================================================================

short RESET (VOID){
short resp;
dq=0;
trisdq=0;//saída
delay_us(480); //delay de reset
trisdq=1;//alta impedancia
delay_us(60); //aguarda resposta do ds1820 com '0'
resp= dq;
delay_us(420);
return (resp);

}

//==============================================================================
// ROTINA DE ENVIO DE 1 BIT
//==============================================================================
void write_1w (short bit){
gie=0;
dq=0;
trisdq=0; // '0'
trisdq=bit;// himp
delay_us(120);
trisdq=1;// himp
gie=1;
}
//==============================================================================
// ROTINA DE ENVIO DE COMANDO
//==============================================================================

void comando (int dado){
int i,d;
for (i=0;i<8;i++) {
d=dado&0x01;
dado=dado>>1;
write_1w(d); //envia um bit para o barramento
}
}
//==============================================================================
// ROTINA DE FORNECIMENTO DE VCC ADICIONAL EM MODO 'PARASITA'
//==============================================================================

void sup_vcc() {
gie=0;
dq=1;
trisdq=0; // '0'
gie=1;
delay_ms(1000);
trisdq=1;//hi imp
dq=0;
}

//==============================================================================
// ROTINA DE LEITURA DE 1 BIT
//==============================================================================

short le_bit(){
short f;
gie=0;
dq=0;
trisdq=0; // '0'
trisdq=1; //hi
delay_us(15);
f=dq; //correto
gie=1;
return (f);
}
//==============================================================================
// ROTINA DE LEITURA DE 1 BYTE
//==============================================================================
int le_byte(){
int i,dado=0;
for (i=0;i<8;i++) {
shift_right(&dado,1,le_bit());
delay_us(90);
}
return (dado);
}

//==============================================================================
// ROTINA DE CONVERSÃO HEX PARA DECIMAL
//==============================================================================
void converte_dec(){

int a,dig0a,dig1a,dig2a,dig3a;

neg=0;
if(buffer[1]>127) neg=1; //+ ou -
for(a=0;a<4;a++) shift_left(buffer,2,0);
buffer[0]=(swap(buffer[0])&0x0f);//acerta parte fracionária (após virgula)

dig0a=0;
dig1a=0;
dig2a=0;
dig3a=0;

while(buffer[1]){
--buffer[1];
if(++dig1a>9) {dig1a=0;
if(++dig2a>9) {dig2a=0; ++dig3a;}
}
}

dig0a= tabela_neg[buffer[0]];//busca valores pós virgula

dig0= dig0a;
dig1= dig1a;
dig2= dig2a;

if(neg){
dig3=0x0a; //traço de negativo (-)
}
else
{ dig3= dig3a;}

 

}
//==============================================================================
// ROTINA PRINCIPAL
//==============================================================================

void main() {
//setup_comparator(NC_NC_NC_NC);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16);
setup_timer_1(T1_DISABLED);

portc=0xff;
portb=0xff;
trisb= 0b00000000; //sentido das portas
trisc= 0b11110000;
t0ie=1;//habilita interrupções tmr0
gie=1; //habilita interrupções geral

dig0=0; //zera contadores inicialmente
dig1=0;
dig2=0;
dig3=0;

//==============================================================================
// LOOP PRINCIPAL
//==============================================================================

while (TRUE) {

 

//==============================================================================
// le temperatura
//==============================================================================

 

while(reset());//aguarda um reset bem sucedido
comando(0xcc); //skip rom
comando (0x44); //envia comando de ler temperatura
// sup_vcc(); //fornece tensão para o ci por 1 seg.
while(reset());//aguarda um reset bem sucedido
comando(0xcc); //skip rom
comando (0xbe); //ler scratchpad 1820
buffer[0]=le_byte(); // le byte l da temperatura no scratchpad
buffer[1]=le_byte(); // le byte h da temperatura no scratchpad
converte_dec(); //converte para decimal e coloca para apresentação

}//while

}//main


   
ReplyQuote
(@clarios)
Reputable Member Admin
Joined: 12 anos ago
Posts: 357
 

Olá Thalis!

Tente esta correção no seu programa:

Você colocou
#byte trisc = 0x00

Quando deveria ser:
#byte trisc = 0x87

Verifique se não vai dar mais algum erro.


   
ReplyQuote
(@thalis)
Active Member
Joined: 5 anos ago
Posts: 10
Topic starter  

Boa tarde

Grato pela resposta!!!

Agora tenho leitura no display !

Mas ainda tenho um problema: tenho leituras tipo esta em 2299 e logo passa 3380, outro de 1999 para 2280 , quando coloco a mao no sensor.

Tambem no digito '1' de exemplo 3210, tenho a impressao que tem sempre um numero 6 espelhado no digito '1'.

So observando sem colocar a amo no sensor para aquecimento, indica  1195, estabilizado.

desde ja agradeço


   
ReplyQuote
(@clarios)
Reputable Member Admin
Joined: 12 anos ago
Posts: 357
 

Olá Thalis!

Quando se coloca a mão no sensor, você deverá presenciar mudança na temperatura até alcançar a temperatura do corpo, aproximadamente 36 graus Cº.

Creio que esteja normal neste aspecto.

Quanto ao 'ghost 6' tente ver a polarização do transistor neste display. Verifique se não inverteu coletor com emissor.  Suponho que esteja usando o emissor no vcc e o coletor alimentando o ânodo do display (PNP).

(Note que, neste tipo de ligação, o emissor não pode ter tensão maior que o fornecido pelo port do pic. Portanto nunca use tensão maiores que o vcc do pic).

Ainda temos um problema: O pino de saída em nível '1' nem sempre será 5 volts, mas algo entre 4,2 volts a 4,7 volts.

Vamos supor que o emissor esteja ligado ao 5 volts (vcc). Medindo a saída do pic  sem ligar a base do transistor (aberta), suponha que  tenha, por exemplo,  4,5 volts em nível alto. Quando ligamos a base nesta saída  teremos uma pequena corrente circulando pelo transistor pois a diferença de 0,5 volts já começa a conduzir o transistor ( a condução ocorre entre 0,5 a 0,8 volts dependendo do transistor e da temperatura ambiente). Isto pode produzir um leve brilho quando ele estiver 'cortado'  tendo um mistura de valores dos outros displays.

Se for o caso, tente usar um resistor polarizador entre a base e o emissor de uns 2K. E da base para o pic use um de 10K.


   
ReplyQuote
(@thalis)
Active Member
Joined: 5 anos ago
Posts: 10
Topic starter  

Boa noite ! E aí blz? Aqui esta frio em torno de 10ºC na rua...

Então, fiz as alterações que me propunha. Sim o emissor no vcc e o coletor alimentando o ânodo do display (PNP).

Assim, segurando o sensor na mao observei que foi ate 3331 e ficou neste valor... acho que é por causa do frio no ambiente...

E sem colocar a mão no sensor indicava 1131. E Fui observando o display no momento indicava 2223, 2222, 2221... quando chegou em 2209, se manifestou aquele efeito 'ghost' no mesmo display de antes das alterações.Aí foi baixando a temperatura depois deste 2209, apareceu 2281,2280 e após 1199 e foi correto ate 1189 e ai desliguei.

Ta muito estranho. 

Aqui nao tem como passar uma foto,video?!!

Excelentes experimentos do seu site, estou aprendendo muito, obrigado

Abraço

 

 


   
ReplyQuote
(@clarios)
Reputable Member Admin
Joined: 12 anos ago
Posts: 357
 

Olá Thalis!

Veja também que na modificação para usar transistores PNP faltou acertar esta porção do código:

// ROTINA DE INTERRUPÇÃO DO TIMER 0
//==============================================================================

#int_timer0

//multiplexa display de 7 seg
void display_refress() {

if(++mux>3){ mux=0;}
portc=1; //apaga seguimentos para mudança  <------------------Está apagando somente o display ligado no portc.0

Mude para :

portc=0x0f; //apaga displays ligados em PC0..PC3

Por favor, faça a correção e veja se o efeito 'ghost 6' desaparece.


   
ReplyQuote
(@thalis)
Active Member
Joined: 5 anos ago
Posts: 10
Topic starter  

Olá, Claudio. Feitoooooooooo!

Funcionou!!

Agora vou dar uma estudada para colocar mais um sensor e ficar alternado entre as duas leituras no display.

valeu grande abraço 


   
ReplyQuote
(@clarios)
Reputable Member Admin
Joined: 12 anos ago
Posts: 357
 

Parabéns!  A persistência sempre compensa!


   
ReplyQuote
(@thalis)
Active Member
Joined: 5 anos ago
Posts: 10
Topic starter  

Boa tarde

 Estou tentando simular no proteus 8, mas os algarismos so aparece alguns segmentos aleatoriamente nos displays??!!

Me parece que o proteus é lento para o simulação do programa!!?? 

Acrescentei alguns delays... mas nao obtive exito!!

 


   
ReplyQuote
Back To Top