#include <12F675.h> //Dispositivo a programar
#device adc=10 // numero de bits de conversion A/D 1023 conteos
#fuses INTRC_IO,NOWDT,PUT,NOPROTECT,NOCPD,NOMCLR,BROWNOUT
#use delay(clock=4000000)//Reloj a 4Mhz
#ROM 0x3ff = {0x3478} //valor registro osccal
#define GP0 PIN_A0 // Pin del canal cero del ADC
#define GP1 PIN_A1 // Pin del canal uno del ADC
#define GP2 PIN_A2 // pin DATA
#define GP3 PIN_A3 // Pin reset pic MCLR (solo entrada)mclr externo desactivado
#define GP4 PIN_A4 // Pin de reloj CLK
#define GP5 PIN_A5 // Pin de strobe
#define dato PIN_A2 //pin de datos Data
#define clock PIN_A4 //pin de reloj o Clk
#define strobe PIN_A5 //pin de strobe transfiere los datos a la salida del 4094
#ZERO_RAM //pongo memoria Ram a ceros
/***************************Declaración Global de variables*******************/
int8 bcd_dato[5]; // arreglo de 5 elementos para almacenar los digitos bcd
int32 j; //Aqui se guarda conversión de las variables a,b,c int8 en Int32
int16 t; //variable ADC, de 1023 conteos
int8 a,b,c,d; //Variables donde se almacenan los dig del display de 7seg
float const res=5000.0/1023.0; //resolución como const 5v/1023 16bits 5v=5000.0 por fuct BCD
/******************************************************************************
Array para formar los digitos de 0 a 9 en Formato 7 segmentos
para ser mostrados en los display de cátodo común
******************************************************************************/
byte const DISPLAY[16] = {0b11111100, //contiene los digitos
0b01100000, //0,1,2,3,4,5,6,7,8,9
0b11011010, // en formato para ser
0b11110010, // mostrados en display de 7segmentos
0b01100110,
0b10110110,
0b10111110,
0b11100000,
0b11111110,
0b11110110,};
/**************************************************************************
FUNCION QUE CONVIERTE A 5 DIGITOS DE BINARIO long int A BCD
****************************************************************************/
void bin16_bcd5(int16 n)// el numero a convertir es un entero largo
{
int i; // indice del arreglo unidades=bcd_dato [0],d=[1],...m=[5]
for(i=0;i<5;i++)// llena el arreglo con los valores uni,dec,cen,mil,diezm
{
bcd_dato[i]=n%10;// mediante la operacion modulo se obtiene el, i digito decimal
n=n/10; // n dividido 10 para cada i y tomamos su valor entero:
} // por ejemplo para i=0, 4358 mod 10 =8, luego 4358/10 =435
} // para i=2, 435 mod 10=5,435/10=43 luego 43 mod 10=3
/********************************************************************************
Esta función Muestra el valor de j en el registro de desplazamiento 4094
*********************************************************************************/
void escribir_byte(int32 datob){//funcion que carga el registro CD4094 con dato j
int contador; // variable contador como entero cuenta los bits a sacar por el pin
output_low
(clock); // EL pin clk se pone en bajo antes de enviar bits // delay_cycles(1); // espera 1 ciclo de instrucción?????
output_low(strobe); // strobe en bajo
for(contador=0;contador<32;contador++){ //el dato a sacar serialmente es de 16 bits
output_bit(dato,(datob & 0x01)); // operación and para sacar bit a bit
datob>>=1; //desplazo un bit a la derecha a datob y lo almaceno en dato
output_high
(clock);// saca un pulso de reloj delay_cycles(1); // de un periodo en alto de 1 ciclo de instrucción
}
output_high(strobe); // transfiere los datos a las salidas del registro 4094
delay_cycles(1); // al terminar de enviar el dato, enviando
output_low(strobe); // un pulso de strobe
}
/********************************************************************************/
void escribir_byte(int32 datob); //llamo a la funcion antes de entrar en el main
/********************************************************************************
Programa Principal
*********************************************************************************/
void main(){
SET_TRIS_A(0b001011); // Configuro GP0-GP1 Como Entradas análogas el resto salidas
SETUP_COMPARATOR(NC_NC_NC_NC);//Desactivo comparadores
SETUP_ADC(ADC_CLOCK_INTERNAL);//Reloj para el ADC interno
SETUP_ADC_PORTS(AN0_ANALOG|VSS_VDD);//AN0 entrada análoga, con rango de 0 a Vdd
/**********************************************************************************
Bucle infinito Lee constantemente el Canales 0 y 1 AN0 AN1 del pic (ADC)
***********************************************************************************/
while(true){
if (input(pin_A3)) //muestra dos lecturas sen el mismo display
set_adc_channel(0);//Selecciono el canal cero del ADC
else //si no
set_adc_channel(1);//Selecciono el canal uno del ADC
delay_us(10); //Espera 10us
t = read_adc()*res;//lee el ADC y guarda el valor leido en t
bin16_bcd5(t); //Conversión de la cifra t int16 a BCD
//para posicionar el punto decimal
a=display[bcd_dato[3]]|0x01;
b=display[bcd_dato[2]];//muestra los datos decodificados
c=display[bcd_dato[1]];//en los display de 7segmentos
d=display[bcd_dato[0]];//en unidades decenas y centenas
j= make32(a,b,c,d);//conversion de los 3 bytes int8 de las variablesa,b,c
escribir_byte(j);//a int32,saco los tres bytes juntos hacia el reg de dezplazamiento
delay_ms(100); //Muestreo de la señal cada 100ms
}
}
/*******************fin programa ppal ********************************************/