Adc 8 bits + eeprom ext I2C + Rs232 al Pc con PIC16F873 CCS

Hola a todos! Tengo unos cuantos problemas programando en CCS.
He de coger una señal analogica por el puerto A0, configurado con set_tris_a (...), pero luego con el read_adc() para ponerlo en una variable, no se como enfocarlo.

he visto cosas del estilo valor=read_adc(); con algun bucle para que vaya cogiendo valores. Tengo que hacer unos 16000 samples de 8 bits ( a lo mejor he de hacer un for o do_while de 0 a 16000?), y pasarlos despues auna eeprom externa de 8 x 16000 = 128Kbits diria, para que me guarde todos los datos...

Tambien hay un tema de retardos (adc, r/w eeprom, buffers), definicion de #rom...

No se si he de hacer funciones por separado, o todo dentro del main()

Desde ya mismo, gracias por vuestra ayuda, porque la necesito urgente! Se q son muchos bloques por separado y despues de saber como hacerlos, he de encajar todos los bloques en conjunto.

Gracias!
 
como andas , mira lo que queres hacer es un datalogger segun veo pero en vez de hacer 16000 samples con un bucle for podrias tomar una muestra cada cierto tiempo por ejemplo cada 2 a 4 segundos y guardar el resulatdo en una eeprom externa
 
Tengo que tomar minimo 1000 muestras por segundo, o sea frec de muestreo = 1KHz.

Primero que el ADC interno de 10 bits, se puede configurar a 8 bits y su frec muestreo minima es de 1,25 MHz.

Pondre algo de codigo a ver si voy bien encaminado. Gracias...


//Codigo del ADC como programa, no como funcion a llamar desde el main//

#include <16f873.h>
#device ADC=8 // ADC devuelven 8 bits
#fuses NOPROTECT,NOCPD,NOLVP,NOWDT,XT //Configuracion de timers, reloj, proteccion de datos...


#use fast_io (A) //Input y output sin reprogramar los pines, como lo haria el #use standard_io
#use fast_io (B)
#use delay(clock=4000000) //Reloj de 4MHz

int8 resultado; //Variable para el resultado de la conversión AD

main() //main o void main()?
{

//Se activa el ADC y se selecciona el canal RA0/AN0. Frecuencia de trabajo Fosc/32

setup_adc(adc_clock_div_32); //Ajusta frecuencia de muestreo del ADC

while(input(PIN_A1)) // Cuando pulse el boton...(activo por 1)
{
delay_ms(10000); // Esperar 10 segundos para encender el cohete

while(1)
{
setup_adc_ports(AN0); //RA0 entrada analógica
set_adc_channel(0); //Selección del canal 0 (RA0)
delay_us(10); //Temporiza 10uS
resultado=read_adc(); //Inicia la conversión y lee el resultado
}
}
}
 
//Funcion de interrupcion de eeprom:ejemplo


#int_eeprom

void interrupt_service_rutine_eeprom(void)
{
flag_Writing_INTERNAL_EEPROM=0;
}

void writeByteINTEEPROM(int8 memAddress, int8 data) //funcion de escritura y puesta de flags para escribir Byte de dato
{

flag_Writing_INTERNAL_EEPROM=1;
enable_interrupts(int_eeprom);
write_eeprom (memAddress, data);

while(flag_Writing_INTERNAL_EEPROM==1){/*Wait for write finish*/}
disable_interrupts(int_eeprom);
}


//Funciones read_eeprom(address) y write_eeprom(address, byte) para datos de 16 bits, aunque yo utilizare //de 8 bits

void write_eeprom_16bits(int address, long* val){

int pLow, pHigh;
pLow = val;
pHigh = val>>8;
write_eeprom(address,pHigh);
delay_ms(12);
++address;
write_eeprom(address,plow);
delay_ms(12);
}

long read_eeprom_16bits(int address){

int pLow, pHigh;
long result;
pHigh = read_eeprom(address);
++address;
pLow = read_eeprom(address);
result=(pHigh<<8);
result+=pLow;
return result;


//Pongo todos los codigos a los cuales he podido llegar mas o menos, pero en ningun caso los he probado ni //se como encajar las fichas del puzzle
 
#use fast_io (B)
#use fast_io (C)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#int_rda //Vector de interrupción al recibir por el UART

//Función de tratamiento de la interrupción al recibir

tratamiento()
{
int dato; //Variable para almacena el dato recibido
dato=getc(); //Lee el dato recibido
output_b(dato); //Lo saca por la puerta B
putc(dato); //Lo transmite vía RS232
}

main()
{
output_b(0x00); //Borra las salidas
set_tris_b(0x00); //Puerta B salida
set_tris_c(0b10111111); //RC7/Rx entrada, RC6/Tx salida
enable_interrupts(INT_RDA); //Activa interrupción en la recepción
enable_interrupts(global); //Habilita interrupciones

while(1)
{

}

// Solo envio de datos, sin ningun tipo de interrupcion.

main()
{
set_tris_c(0b10111111); //RC7/Rx entrada, RC6/Tx salida

while(1)
{
putc('A'); //Transmite el caracter
delay_ms(1000); //Temporiza 1 segundo
}
}


Desde ya muchas gracias!
 
Vos decis que tenes que tomar 1000 muestras por segundo , pero cada vez que el adc toma un valor la variable resultado cambia por lo que solo te puede almacenar un valor por vez en la memoria eeprom y ademas tarda aproximadamente 10ms guardar cada dato en (asm) por lo que en 1 seg podrías guardar 100 valores max .

Otra cosa que me parece que tendrías que tener en cuenta es el tiempo que le toma al adc realizar la conversión del dato analógico al digital. eso lo dice en la hoja de datos . entonces dividis 1 seg por el tiempo de conversion y te a dar la cantidad de veces que se puede leer el adc en 1 seg.

Cualquier cosa que este metiendo la pata decime en caso contrario , espero que te ayude
 
yo tengo un problema algo similar, usando un 16f87x necesito tomar el dato analogo cada 20s e irlo almacenando para que al paso de 4 minutos (12 datos almacenados) sacar un promedio de los datos almacenados, la verdad soy nuevo en este cuento de los pics, se me habia ocurrido segun lo que he leido en no almacenar cada dato leido en una variabel diferente sino ir sumando al anterior el dato nuevo que se lea y despues divir esto por 12 para sacar el valor promedio y despues si mostrar este en la salida ya digitalizado.

Si alguien me puede dar luces al respecto les agradeceria mucho.
 
hola yo estoy unsando un pic18f4553, y deseo realizar el muestreo de una señal de 2kh de frcuencia,, pero al implementarlo en mi pic, no logro visualizarla correctamente en mi PC, estoy usando una comunicacion USB,, grax espero me ayuden
 
Atrás
Arriba