Estoy utilizando el ADC de ATMega8 para leer las formas de onda de carga y descarga de un condensador. Sin embargo, estoy obteniendo una gran cantidad de errores cuando veo los datos que obtengo en mi computadora portátil. Estoy enviando los datos muestreados a la computadora portátil a través de un convertidor de USB a TTL a 9600 bps. La frecuencia de muestreo es de 15000 muestras por segundo, por lo que probablemente hay muchas muestras que se pierden debido a la diferencia de velocidad. Estoy usando el reloj predeterminado de ATMEGA8. Los datos transmitidos en serie se reciben en MATLAB y se muestra el gráfico:
Laversiónampliadadeunodeestosciclosdedescargadecargasemuestraacontinuación:
Como puede ver, hay una gran cantidad de errores, pero podemos distinguir la forma de onda real. que esta causando este problema? ¿Cómo puedo corregir esto?
También, tengo un problema con las lecturas de ADC. He establecido la referencia del ADC SAR como el valor interno por defecto de 2.56 V. Como lo entiendo, se supone que el ADC de 8 bits me da 0 (Ox00) a 0 V y 255 (OxFF) a 5 V. Pero aquí obtengo 124 para 0 V y 255 para 5 V. ¿Por qué sucede esto? Como se muestra, multiplicar los valores obtenidos en el ADC por 5/255 no me da los valores de voltaje originales. El 'offset' de 2.5 V que se muestra se debe a este error de reconocer 0 V como 124. Pero no sé por qué sucede esto.
Se muestra el código C en el extremo del microcontrolador. El programa también genera dos pulsos que se utilizan para activar los ciclos de carga y descarga del condensador (los pulsos se envían a la puerta de dos interruptores MOS).
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) //Calculating prescaler for serial communication
int main(void)
{
uint32_t i;
UCSRB |= (1 << RXEN) | (1 << TXEN); //Enable serial transmission and reception
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); //Set character size (8 bits). When URSEL is 1, we can write data to UBRRH register.
UBRRH = (BAUD_PRESCALE >> 8); \Setting the prescale
UBRRL = BAUD_PRESCALE; //Set prescale value
//DDRD = 0xff; \Set port D as output (for pulses)
ADMUX = (1<<REFS0) |(1<<ADLAR)|(1<<REFS1); \Set reference voltage to internal and left adjust result (out of 10 bit result, 8 bits are moved to ADCH register).
ADCSRA = (1<<ADEN)|(1<<ADFR); \Enable ADC in free running mode
//|(1<<ADPS2) |(1<<ADPS1) |(1<<ADPS0);
//
ADCSRA|=(1<<ADSC); \Start conversion
DDRB = 0xff; \Set port B as output (for pulses)
while(1)
{
for (i = 0; i< 200; ++i)
{
PORTB = 0x01; \First bit of port B will be high pulse for duration of loop.
// ADCSRA|=(1<<ADSC);
while ((UCSRA & (1 << UDRE)) == 0) {}; \a while loop (with no body) that continues as long as the UDRE bit is set. UDRE is set when it is ready to send data
UDR = ADCH; \Read ADC data
// PORTB = 0x01;
}
PORTB = 0x00; \Set all ports off for a brief interval (for nonoverlapping of charge and discharge cycles)
_delay_ms(5);
for (i = 0; i<400; ++i)
{
PORTB = 0x02; \Setting second bit of port B high. To activate discharge cycle.
// ADCSRA|=(1<<ADSC);
while ((UCSRA & (1 << UDRE)) == 0) {}; \a while loop (with no body) that continues as long as the UDRE bit is set. UDRE is set when it is ready to send data
UDR = ADCH;
// PORTB = 0x02;
}
}
return 1;
}