Hallo Leute, ich hab jetzt schon einige Zeit gesucht aber nix gefunden... Hier mein Problem: Ich habe die ADC Routine aus dem GCC Tutorial genommen aber leider tut die nicht ganz. Ich bekomme folgende Werte: Init done! Systime:0 ms ADC 0: 511 ADC 1: 479 ADC 2: 476 ADC 3: 514 ADC 4: 536 ADC 5: 550 ADC 6: 552 ADC 7: 550 ADC BG: 373 ADC 0V: 0 Systime:520 ms ADC 0: 57 ADC 1: 70 ADC 2: 82 ADC 3: 106 ADC 4: 129 ADC 5: 154 ADC 6: 177 ADC 7: 200 ADC BG: 373 ADC 0V: 0 Systime:1050 ms ADC 0: 1 ADC 1: 0 ADC 2: 0 ADC 3: 1 ADC 4: 1 ADC 5: 0 ADC 6: 2 ADC 7: 3 ADC BG: 373 ADC 0V: 0 wie man sieht fallen die Werte langsam gegen 0, doch das tun sie auch wenn ich VCC anschließe oder die PORTS anschalte (wie in diesem Fall DDRA=0xFF PORTA=0xFF). Die Werte von der BG (MUX=30) und GND (MUX=31) stimmen sofort (373/1,23V*1024 = 3,37V) Hat jemand eine Idee oder einen Link (bitte nicht das Tutorial)?
OK. DU verwendest du Tutorial Routinen. Aber wie sieht dein Programm aus? (und auch wenn wir die Routinen kennen, lass sie trotzdem drinnen). Was passiert eigentlich, wenn du immer nur 1 Kanal sampelst?
Das Board läuft mit 7,273800Mhz und das hier ist es: http://www.chip45.com/AVR-Mikrocontroller-System-Platinen/Savvy128-V1-3-ATmega128-USB-RS232-RS485-Echtzeituhr-SD-Karte.html Hier die Main:
1 | int main() |
2 | {
|
3 | adc_init(); |
4 | timer_init(); |
5 | uart_init(UART_BAUD_SELECT(19200,F_CPU)); |
6 | stdout = &mystdout; |
7 | sei(); |
8 | printf("Init done!\r\n"); |
9 | |
10 | DDRA = 0xFF; |
11 | PORTA= 0x0F; |
12 | |
13 | while(1){ |
14 | printf("Systime:%lu ms\r\n",ulTime); |
15 | _delay_ms(200); |
16 | |
17 | for(uint8_t i= 0 ; i<8 ; i++){ |
18 | uint16_t val = getAdcValueAvg(i); |
19 | printf("ADC %d: %3d ",i,val); |
20 | }
|
21 | printf("ADC BG: %3d ",getAdcValueAvg(30)); |
22 | printf("ADC 0V: %3d\r\n",getAdcValueAvg(31)); |
23 | }
|
24 | }
|
und hier die ADC Routine
1 | void adc_init(){ |
2 | |
3 | uint16_t result; |
4 | |
5 | ADMUX = (0<<REFS1) | (1<<REFS0); // AVcc als Referenz benutzen |
6 | ADCSRA = (1<<ADPS2)|(1<<ADPS1) | (0<<ADPS0);// Frequenzvorteiler |
7 | ADCSRA |= (1<<ADEN); // ADC aktivieren |
8 | |
9 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
10 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
11 | |
12 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
13 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten |
14 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
15 | Wandlung nicht übernommen. */
|
16 | result = ADCW; |
17 | }
|
18 | |
19 | uint16_t getAdcValue(uint8_t bChannel){ |
20 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
21 | ADMUX = (ADMUX & ~(0x1F)) | (bChannel & 0x1F); |
22 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" |
23 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten |
24 | return ADCW; // ADC auslesen und zurückgeben |
25 | }
|
26 | |
27 | |
28 | uint16_t getAdcValueAvg(uint8_t bChannel){ |
29 | uint32_t result = 0; |
30 | for (uint8_t i = 0; i < 128; ++i ) |
31 | result += getAdcValue( bChannel ); |
32 | return (uint16_t)( result / 128 ); |
33 | }
|
Hallo, ich hänge man meinen C Code an. Der läuft ohne Probleme. Ich hoffe es hilft Dir. .
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.