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

  RSS

0

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

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

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

0

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.

 
0

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.

 
0

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

 

 

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.

0

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 

Parabéns!  A persistência sempre compensa!

0

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!!

 

 
Share: