Hallo
Mein 8MHz-ATMega32 (auf dem RP6) liest mit dem ADC ein Audiosignal vom PC/MP3-Player und gibt den Pegel (2-bit) mit LEDs aus. Gleichzeitig wird das Signal noch an zwei DA-Pins ausgegeben. Noch in der Entwicklung mit miesem Sound, als Anregung gedacht:
Code:
//RP6 als Tonband Ohne Library Aufnahme: PortA4 Wiedergabe: PortC0 2.1.2008 mic
#include <avr/io.h> // I/O Port definitions
#include <avr/interrupt.h> // Interrupt macros
#ifndef F_CPU
#define F_CPU 8000000
#endif
// Einstellungen für UART und LEDs aus der RP6-Lib
#define BAUD 38400 // 38400 Baud
#define UBRR_BAUD ((F_CPU/(16*BAUD))-1)
#define SL1 (1 << PINC4)
#define SL2 (1 << PINC5)
#define SL3 (1 << PINC6)
#define SL4 (1 << PINB7)
#define SL5 (1 << PINB1)
#define SL6 (1 << PINB0)
// A shadow register that simplifies usage of status LEDs:
union {
uint8_t byte;
struct {
unsigned LED1:1;
unsigned LED2:1;
unsigned LED3:1;
unsigned LED4:1;
unsigned LED5:1;
unsigned LED6:1;
unsigned reserved1:1;
unsigned reserved2:1;
};
} statusLEDs;
void updateStatusLEDs(void)
{
DDRB &= ~0x83;
PORTB &= ~0x83;
if(statusLEDs.LED4){ DDRB |= SL4; PORTB |= SL4; }
if(statusLEDs.LED5){ DDRB |= SL5; PORTB |= SL5; }
if(statusLEDs.LED6){ DDRB |= SL6; PORTB |= SL6; }
DDRC &= ~0x70;
PORTC &= ~0x70;
DDRC |= ((statusLEDs.byte << 4) & 0x70);
PORTC |= ((statusLEDs.byte << 4) & 0x70);
}
inline void setLEDs(uint8_t leds)
{
statusLEDs.byte = leds;
updateStatusLEDs();
}
void Init(void)
{
cli();
// UART:
UBRRH = UBRR_BAUD >> 8; // UART 38400 Baud
UBRRL = (uint8_t) UBRR_BAUD;
UCSRA = 0x00;
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE);
// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR) | 4;
// setzte free running triggern
SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// interupt, Wandler einschalten, prescaller /128 (62500Hz)
ADCSRA = (1<<ADIE) | (1<<ADEN) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
// Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
ADCSRA |= (1<<ADATE) | (1<<ADIF);
// Initialisierung starten
ADCSRA |= (1<<ADSC);
// und noch die wohl eher unnötige Initiallesung
while (!(ADCSRA & (1<<ADIF)));
ADCSRA |= (1<<ADIF);
DDRC |= 3;
sei();
}
int main(void)
{
uint8_t i;
Init();
setLEDs(1);
for (i='a'; i<='z'; i++)
{
while (!(UCSRA & (1<<UDRE)));
UDR = i;
}
while (!(UCSRA & (1<<UDRE)));
UDR = '\n';
while (!(UCSRA & (1<<UDRE)));
UDR = '\r';
while(1);
return(0);
}
ISR(ADC_vect)
{
static uint8_t adc_temp=0, count=0;
adc_temp=(ADCH & 3);
setLEDs(1);
if (adc_temp >0) setLEDs(8);
if (adc_temp >1) setLEDs(16);
if (adc_temp >2) setLEDs(32);
if (adc_temp == 0)
{
DDRC |= 3;
PORTC &= ~3;
}
else if (adc_temp == 1)
{
DDRC |= 3;
PORTC |= 1;
PORTC &= ~2;
}
/*
if (adc_temp == 2)
{
DDRC |= 1;
PORTC |= 1;
DDRC &= ~2;
PORTC &= ~2;
}
*/
else if (adc_temp > 1)
{
DDRC |= 3;
PORTC |= 3;
}
if (count++ == 3) count=0;
//UDR = adc_temp + '0';
//UDR = '\n';
}
Das Programm verwendet den ADC-Interrupt und gibt den gemessenen Wert in der ISR wieder aus. Die Samplerate ist der prescaler des ADC. Der Eingang hat einen 10K PullUp und das Eingangssignal sollte nicht höher als 5V sein. Ein Kopfhörerausgang sollte genügen, Lautstärke von 0 langsam steigern!
Gruß
mic
Lesezeichen