Skip to content

Instantly share code, notes, and snippets.

@jerivas
Last active December 25, 2015 11:29
Show Gist options
  • Select an option

  • Save jerivas/6969811 to your computer and use it in GitHub Desktop.

Select an option

Save jerivas/6969811 to your computer and use it in GitHub Desktop.
// Muestreador de audio: digitaliza y guarda una señal analógica en EEPROM
// Se muestrean 128 datos de 10 bits, lo que se convierte en 256 datos de 8
// bits al moverlos a EEPROM. Luego se muestra en la LCD los datos capturados.
// Ángel Moreno
// David Escobar
// Eduardo Rivas
#include "xc.h"
#include "stdlib.h"
#include "../utils/delays.h" //Incluir cabeceras de retardos
#include "../utils/lcd.h" //Incluir cabeceras para manejo de LCD
//Directivas para activar los bits de configuracion
#pragma config FOSC = INTOSCIO_EC //Oscilador Interno, Puerto A RA6 activo,
#pragma config WDT = OFF //Watchdog timer apagado
#pragma config PBADEN = OFF //Parte baja del puerto B digitales
#pragma config MCLRE = ON //MCLRE Disponible
#pragma config DEBUG = ON //Modo de depuracion disponible
#pragma config LVP = OFF //Fuente de ISCP apagada
//Variables globales
unsigned char adc_count = 0; //Cuenta cuantas conversiones se han realizado
unsigned int adc_results[128] = 0; //Arreglo de 128 datos de 16 bits
unsigned int ee_buffer = 0; //Temporal para los datos leídos de EEPROM
char ascii_buffer[5] = 0; //Representación ASCII de un número para la LCD
//Configuracion
void config() {
IRCF0 = 1; //configuracion del OSCCON F=8MHz
IRCF1 = 1;
IRCF2 = 1;
//Inicializar el ADC
ADCON0 = 0; //ADC en canal 0, apagado
ADCON1 = 0b00001110; //RA0 como entrada angalógica
ADCON2 = 0b10000000; //Tiempo de adquisición de 0TAD y velocidad de Fosc/2
ADIF = 0; //Limpiar la bandera del ADC
ADIE = 1; //Habilitar la interrupción por ADC
PEIE = 1; //Habilitar interrupción por periféricos
//Inicializar los puertos
PORTA = 0; //Limpiar PORTA
LATE = 0; //Limpiar PORTE
LATD = 0; //Limpiar PORTD
TRISA0 = 1; //PORTA0 como entrada
TRISE = 0; //PORTE como salida
TRISD = 0; //PORTD como salida tambien
//Inicializacion de los perifericos externos
LCD_Inicializar(); //Inicializa la pantalla LCD
}
void main() {
config(); //Ejecutar configuración
LCD_Posicion(0, 0);
LCD_Cadena("Capturando..."); //Mensaje que se muestra durante la captura
GIE = 1; //Habilitar interrupciones
ADON = 1; //Encender ADC
GO = 1; //Iniciar primera conversión
//Se realizan 128 (no 256) conversiones porque cada una es de 16 bits
while (adc_count < 128){
if (GO) {Nop();} else {GO = 1;} //Realizar una conversión tras otra
}
//FIN DE LA CAPTURA
//INICIO DE LA ESCRITURA EN EEPROM
ADON = 0; //Apagar el ADC, ya que no se usará más
LCD_Posicion(0, 0);
LCD_Cadena("Datos capturados"); //Mensaje que indica el fin de la captura
Delay10KTCYx(200); //Mostrar el mensaje durante cierto tiempo
for (unsigned int i = 0; i < 256; i += 2){ //Mover de RAM a EEPROM
eeprom_write(i, LOW_BYTE(adc_results[i/2])); //Guardar el byte bajo
eeprom_write(i+1, HIGH_BYTE(adc_results[i/2])); //Guardar el byte alto
}
LCD_Limpiar();
/*
FIN DE LA ESCRITURA EN EEPROM
INICIO DE LA LECTURA DE EEPROM Y DESPLIEGUE EN LCD
Bucle que muestra las 256 localidades de EEPROM de 8 a la vez, concatenando
las localidades continuas para mostrarlas como 4 datos de 10 bits.
*/
for (unsigned int ee_adr = 0; ee_adr < 256; ee_adr += 8) {
LCD_Posicion(0, 0);
LCD_Cadena("EEPROM #"); //Mensaje de la localidad actual
LCD_Cadena(itoa(ascii_buffer, ee_adr, 10)); //Mostrar la dirección que se esta leyendo
LCD_Posicion(0, 0x40);
for (char i = 0; i < 8; i += 2) { //Mostrar 4 datos de 10 bits por vez
ee_buffer = eeprom_read(ee_adr+i+1);
LCD_Cadena(itoa(ascii_buffer, ee_buffer, 16)); //Mostrar parte alta
ee_buffer = eeprom_read(ee_adr+i);
if (ee_buffer < 0x10) LCD_Caracter('0'); //Rellenar la parte baja con 0 si es menor que 16
LCD_Cadena(itoa(ascii_buffer, ee_buffer, 16)); //Mostrar parte baja
LCD_Caracter(' ');
}
Delay10KTCYx(255); //Esperar antes de mostrar el siguiente dato
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
}
while(1);
}
//Rutinas de interrupcion
//Guarda 128 datos de 10 bits desde el ADC en RAM
void interrupt service(void) {
GIE = 0; //Deshabilitar interrupciones y evitar anidamiento
if (ADIF && adc_count < 128) { //Guardar solo 128 conversiones en RAM
adc_results[adc_count] = ADRES; //Mover el resultado del ADC a RAM
adc_count++; //Aumentar el contador de conversiones
ADIF = 0; //Bajar la bandera del ADC
}
GIE = 1; //Rehabilitar interrupciones
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment