Você está na página 1de 5

C:\Users\lcfon\Downloads\PIC_VOLT_C\VOLTIMETRO COM 3 DIGITOS_628_c.

c
/*******************************************************************************

PIV_VOLT_C
PROJETO

VOLTIMETRO COM 3 DIGITOS DE 0 A 25 VOLTS

INICIO : 26/03/13 TERM.:27/03/13 (VERSO ASM)


INICIO : 30/12/14 TERM.:31/12/14 (ESTA VERSO EM 'C')
AUTOR: CLUDIO LRIOS
PROCESSADOR: PIC
16F628A
OBJETIVO: MEDIR TENSES DE 0 A 25 VOLTS,PARA USO EM FONTES DE ALIMENTAO
DE BANCADA
UTILIZA O METODO DELTA_SIGMA PARA CONVERTER A TENSO ANALGICA EM DIGITAL.
(MULTIPLEXAAO E BASE DE TEMPO PARA O CONVERSOR USANDO INTERRUPO DO TIMER0)
PINOS DO MICROCONTROLADOR:
1- NC
2- SEGUIMENTO 'C'
3- SEGUIMENTO 'D'
4- RESET
5- GND
6- SEGUIMENTO 'A'
7- SEGUIMENTO 'B'
8- CATODO COMUM DISPLAY '0'
9- NC
10-CATODO COMUM DISPLAY '2'
11-SEGUIMENTO 'E'
12-CATODO COMUM DISPLAY '1' E PONTO
13-NC
14-VCC
15-SEGUIMENTO 'F'
16-SEGUIMENTO 'G'
17-RESISTOR DE 47K (DESCARGA)
18-RESISTOR DE 150 (ENTRADA)
Use os 2 resistores de preciso de 47k 1% na entrada do conversor.
Capacitor de 220nF poliester.
Este arquivo parte integrante do BLOG LARIOS.TECNOLOGIA.WS.
Uso para fins didticos.
********************************************************************************/

#include <16F628A.h>
#use delay(clock=4000000)//OSCILADOR RC INTERNO DO PIC
#fuses NOWDT,INTRC_IO, NOPUT, NOPROTECT, BROWNOUT, MCLR, NOLVP, NOCPD
#use fast_io(a)//MODO RPIDO
#use fast_io(b)//MODO RPIDO
#zero_ram // ZERA RAM INICIALMENTE
//==============================================================================
//
Bytes
//==============================================================================
#byte
#byte
#byte
#byte
#byte
#byte

trisa
trisb
porta
portb
cmcon
vrcon

=
=
=
=
=
=

0x85
0x86
0x05
0x06
0x1f
0x9f
1

C:\Users\lcfon\Downloads\PIC_VOLT_C\VOLTIMETRO COM 3 DIGITOS_628_c.c


#byte timer0= 0x01
//==============================================================================
//
Bits
//==============================================================================
#bit
#bit
#bit
#bit
#bit
#bit
#bit
#bit
#bit
#bit
#bit
#bit

k0
=
k1
=
k2
=
desc =
c2_out=
seg_a =
seg_b =
seg_c =
seg_d =
seg_e =
seg_f =
seg_g =

0x06.2 //k0
0x06.6 //k1
0x06.4 //k2
0x05.0 //descarga ra0
0x1f.7// cmcon saida c2
0x06.0 //seg a
0x06.1 //seg b
0x05.3 //seg c
0x05.4 //seg d
0x06.5 //seg e
0x05.6 //seg f
0x05.7 //seg g

//==============================================================================
//
Variveis globais
//==============================================================================
int8 resc0,resc1;
int1
flag_ds;
//==============================================================================
//
Array com valor em 7 seguimentos
//
(obs. modo catodo comum, precisando inverte ao usar para anodo comum)
//==============================================================================
const int8 c7seg [10]={
//
(ABCDEFGP)
0b11111100,
/* RETORNA 0
FC */
0b01100000, /* RETORNA 1
60 */
0b11011010, /* RETORNA 2
DA */
0b11110010,
/* RETORNA 3
F2 */
0b01100110,
/* RETORNA 4
66 */
0b10110110,
/* RETORNA 5
B6 */
0b10111110,
/* RETORNA 6
BE */
0b11100000,
/* RETORNA 7
E0 */
0b11111110,
/* RETORNA 8
FE */
0b11110110
/* RETORNA 9
F6 */
};
//==============================================================================
//
//Estrutura para fins de deslocamento de dados
//==============================================================================
struct to_shift {
int8 c0;
int8 c1;
int8 res0;
int8 res1;
int8 res2;
} res;
//==============================================================================
//
Rotina de envio para sada dos seguimentos
//==============================================================================
void env_out(int8 a){
if(bit_test(a,7)) seg_a=1; else seg_a=0;
if(bit_test(a,6)) seg_b=1; else seg_b=0;
if(bit_test(a,5)) seg_c=1; else seg_c=0;
2

C:\Users\lcfon\Downloads\PIC_VOLT_C\VOLTIMETRO COM 3 DIGITOS_628_c.c


if(bit_test(a,4)) seg_d=1; else seg_d=0;
if(bit_test(a,3)) seg_e=1; else seg_e=0;
if(bit_test(a,2)) seg_f=1; else seg_f=0;
if(bit_test(a,1)) seg_g=1; else seg_g=0;
}
//==============================================================================
//
Rotina de interrupo do timer 0
//==============================================================================
#INT_TIMER0
void int_tmr0_isr(){
static int8 vez,vez1;
int8 aux;
timer0=200;//carga do timer para 55 useg
flag_ds=!flag_ds;//sinaliza para o conversor delta_sigma
if(++vez1>64) { // verifica se deve mudar digito do display (multiplexao)
vez1=0;//zera contador auxiliar de multiplexao
k0=0;//desliga anodos (apagar displays)
k1=0;
k2=0;
if(++vez>2) vez=0;//incrementa e limita a 3 digitos
switch (vez){
case 0: {//seleciona digito '1'(lsb) para apresentar
aux=resc0;//pega valor
aux=swap(aux)&0x0f; //inverte e limita a um nibble
aux=c7seg[aux];//converte para 7 seguimentos
env_out(~aux); //envia para sadas dos seg. invertendo p/ anodo comum
k0=1;//liga anodo do 1 digito
break;
}
case 1: {//seleciona digito '2' para apresentar
aux=resc1&0x0f;
aux=c7seg[aux];
env_out(~aux);//envia para sadas dos seg. invertendo p/ anodo comum
k1=1;//liga anodo do 2 digito
break;
}
case 2: {//seleciona digito '3' (msb) para apresentar
aux=resc1;
aux=swap(aux)&0x0f;
if(!aux)break;
aux=c7seg[aux];
env_out(~aux);//envia para sadas dos seg. invertendo p/ anodo comum
k2=1;//liga anodo do 3 digito
break;
}
}
}
}
//==============================================================================
//
Rotina do conversor Delta Sigma
//
obs. usa o timer 0 para produzir tempos iguais entre ciclos
//==============================================================================
int16 get_adc_ds(){
int16 ciclo=0x1000; //12 bits de resoluo
int16 val=0;//zera resultado
3

C:\Users\lcfon\Downloads\PIC_VOLT_C\VOLTIMETRO COM 3 DIGITOS_628_c.c


for(;;){
while(flag_ds);//aguarda momento correto
while(!flag_ds);//aguarda momento correto
if(c2_out){desc=1; } else {desc=0; val++;}//testa sada do comparador
if(!--ciclo){desc=0; return(val); }//testa fim da converso adc delta-sigma
}
}
//==============================================================================
//Converte hex 2 bytes para decimal 3 bytes
//==============================================================================
void bin2_dec(int16 a){
int8 cont,aux;
res.c0=make8(a,0);//carrega valor a converter
res.c1=make8(a,1);
res.res0=0;//zera resultados
res.res1=0;
res.res2=0;
cont=16;//numero de vezes da converso
for(;;){//loop continuo
shift_left(&res,5,0);//desloca 5 bytes p/ esquerda
if(!--cont){//testa se chegou ao fim da converso
resc0=res.res0;//copia para o buffer de apresentao
resc1=res.res1;
return;//fim da converso
}
aux=res.res2;
if((aux+0x03)&0x08) res.res2+=0x03;//testa bit 3
aux=res.res2;
if((aux+0x30)&0x80) res.res2+=0x30;//testa bit 7
aux=res.res1;
if((aux+0x03)&0x08) res.res1+=0x03;//testa bit 3
aux=res.res1;
if((aux+0x30)&0x80) res.res1+=0x30;//testa bit 7
aux=res.res0;
if((aux+0x03)&0x08) res.res0+=0x03;//testa bit 3
aux=res.res0;
if((aux+0x30)&0x80) res.res0+=0x30;//testa bit 7
}
}
//==============================================================================
//
Rotina Principal
//==============================================================================
void main() {

setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
vrcon=0b11101100;//ajusta vref para 2,5 volts
cmcon=5;//usando um comparador apenas
trisa=0b00100110;
trisb=0b00000000;//TUDO SADA
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
//==============================================================================
4

C:\Users\lcfon\Downloads\PIC_VOLT_C\VOLTIMETRO COM 3 DIGITOS_628_c.c


//
Loop Principal
//==============================================================================
while(1){
bin2_dec(get_adc_ds());// obtem converso delta-sigma/ converte para hex e
// apresenta nos displays de 7 seg. multiplexados
}
}
//==============================================================================
//
Fim do Programa
//==============================================================================