AVR(ADC)
AVR(ADC)
Jag håller på och leker med en Mega8 och ADC-biten.
Eftersom jag är intresserad av musik, och då främst elektronisk sådan, så har jag slängt ihop en enkel krets för att få inkommande signal mellan 0-5V och centrerad runt 2.5 V. Aref ligger på 5 V. En stycken DAC0830 sitter på en port, dac:n är konfigurerad för "flow-through". 8bitar kör jag med.
Så allt det ska fungera.. och det gör det. Får snuskigt skitigt ljud ut. Det kan ju vara trevligt ibland.
Egentligen en rätt meningslös krets/effekt men den ger ju lite mer crunch/8bitars-känsla i ljudet. Blir mer vettig när man blandar orginalljudet med det "destruerade" ljudet.
Men så började man fundera....
Hur ska man egentligen göra för att få bästa möjliga kvalité ur denna uppkoppling?
Kan man göra interna inställningar i AVR:en mer än sleep-funktionerna(stänga av CPU under konverteringen) och matcha in skalningen så samplingsfrekvensen blir lämplig osv?
Min ingångkrets består egentligen bara av en spänningsdelning, sedan två lika motstånd som lyfter signalen till mitten av matningspänningen. Efter den två dioder som skyddar för negativa och för höga spänningar. En OPamp(spänningsföljare) ska kopplas in också..
Tacksam för alla svar.
Eftersom jag är intresserad av musik, och då främst elektronisk sådan, så har jag slängt ihop en enkel krets för att få inkommande signal mellan 0-5V och centrerad runt 2.5 V. Aref ligger på 5 V. En stycken DAC0830 sitter på en port, dac:n är konfigurerad för "flow-through". 8bitar kör jag med.
Så allt det ska fungera.. och det gör det. Får snuskigt skitigt ljud ut. Det kan ju vara trevligt ibland.
Egentligen en rätt meningslös krets/effekt men den ger ju lite mer crunch/8bitars-känsla i ljudet. Blir mer vettig när man blandar orginalljudet med det "destruerade" ljudet.
Men så började man fundera....
Hur ska man egentligen göra för att få bästa möjliga kvalité ur denna uppkoppling?
Kan man göra interna inställningar i AVR:en mer än sleep-funktionerna(stänga av CPU under konverteringen) och matcha in skalningen så samplingsfrekvensen blir lämplig osv?
Min ingångkrets består egentligen bara av en spänningsdelning, sedan två lika motstånd som lyfter signalen till mitten av matningspänningen. Efter den två dioder som skyddar för negativa och för höga spänningar. En OPamp(spänningsföljare) ska kopplas in också..
Tacksam för alla svar.
- JimmyAndersson
- Inlägg: 26579
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Jag har också försökt mig på något liknande men jag hamnade i annat göra, så det blev inte så mycket av det... Jag han dock få igång sampling i 8kHz, skicka ut det via uart, ta in det igen och "spela upp" det med PWM. Jag han dock inte testa med riktigt ljud utan bara en trimpot och det verkar i alla fall fungera... Tyvärr så orkar jag ju bara "vrida fram" ett par Hz på trimpotten, så frågan är hur det fungerar i höga frekvenser.
Skalning 32 borde ju vara det optimala eftersom det ger en frekvens på 125kHz och varje omvanling tar ca 13 cykler (tror jag). 125kHz/13=9615 omvandlingar per sekund, vilket är strax över 8kHz.
Skalning 32 borde ju vara det optimala eftersom det ger en frekvens på 125kHz och varje omvanling tar ca 13 cykler (tror jag). 125kHz/13=9615 omvandlingar per sekund, vilket är strax över 8kHz.
Om jag fattat dig rätt så kör du alltså "så fort det bara går" med prescaler 32? Det borde bli ca 9,6kHz samplingshastighet. Den kod jag använder utnyttjar en timer för att sampla med 8kHz, den använder även PWM för att skicka ut signalen.. dessutom så tar den omvägen via UART:en, så rx och tx måste byglas om du vill testa exemplet:
Kod: Markera allt
/*********************************************
* Chip type : ATmega8
* Clock frequency : 4,000000 MHz
*********************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdlib.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
volatile unsigned char sendflag = 0;
volatile unsigned char ch = 'a';
void usart_putc(unsigned char c) {
while(!(UCSRA & (1 << UDRE))); //Wait for empty buffer
UDR = c; // send character
}
void init_port(void){
DDRB = 0x01 | _BV(PB3); //1=out, 0=in
DDRC = 0xFE; //Debug Ut
DDRD |= _BV(PD7);
PORTC = 0xFE; //Debug Släck
}
void init_timer(void) {
TCCR1B |= _BV(CS10) | _BV(WGM12); //Start timer with prescaler 1, CTC
OCR1A = 0x01F4;
TIMSK|=(1<<OCIE1A); //timer 1 interrupt source
}
void init_UART(void) {
UBRRH = 0; //Set baudrate
UBRRL = 1;
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); //Enable Rx, Tx and Rx interrupt
}
void init_ADC(void){
ADCSRA |= _BV(ADEN) | _BV(ADPS2) | _BV(ADPS0); //Enable AD
ADMUX |= _BV(ADLAR);
}
void init_PWM(void){
TCCR2 = _BV(COM21) | _BV(WGM20) | _BV(CS20); //Enable AD
OCR2 = 0x80;
}
// Handles Output Compare and turns off Ultrasonic
// waveform after five periods, about 0.125ms
SIGNAL (SIG_OUTPUT_COMPARE1A)
{
sendflag = 1;
}
// Handles incomming bytes on USART
SIGNAL (SIG_UART_RECV)
{
unsigned char c = UDR;
OCR2 = c;
PORTD ^= _BV(PD7); //Toggle green led
}
int main(void)
{
unsigned char val;
cli(); // disable interrupt globaly
init_UART(); // init USART
init_port(); // init I/O
init_timer(); // init timers
init_ADC();
init_PWM();
sei(); // enable interrupt globaly
ADCSRA |= _BV(ADSC); //Start conversion
for(;;) //Run forever...
{
while(!sendflag); //wait for trigger
sendflag = 0;
/* WAIT for ADconverter to finish */
while( !(ADCSRA & _BV(ADIF)) );
ADCSRA |= _BV(ADIF);
ADCSRA |= _BV(ADSC); //Start conversion
usart_putc(ADCH);
PORTB = PORTB ^ 0x01;
}
return 0;
}
Nu är inte jag så slängd på C men får väl ta och bli.
Ok.. aha.. 13.. där det skulle in. Borde ju räcka i "slutlig" samplingsfrekvens.. hmm. vänta.. Nyquist börjar spöka... översta frekvensen blir alltså ca 4 kHz.. hmm..
Ska nog stoppa på ett filter på ingången.. för att undvika aliasing då kanske. Inte helt fel kanske.. Så man får så bra förutsättningar som möjligt att kräma ur saker å ting ur denna lilla mojäng.
Ok.. aha.. 13.. där det skulle in. Borde ju räcka i "slutlig" samplingsfrekvens.. hmm. vänta.. Nyquist börjar spöka... översta frekvensen blir alltså ca 4 kHz.. hmm..
Ska nog stoppa på ett filter på ingången.. för att undvika aliasing då kanske. Inte helt fel kanske.. Så man får så bra förutsättningar som möjligt att kräma ur saker å ting ur denna lilla mojäng.