Hallo Leute! Ich versuche gerade mit einem Atmega16 mit dem ADC einen Wert auszulesen und diesen einfach so wie er ist als 16bit Variable an den Rechner zu schicken. Leider beißt sich irgendwie mein UART Code mit dem ADC Code. Einzeln funktionieren sie wunderprächtig, aber sobald ich im angehängten Code in der "main" Funktion das "ADC_Enable();" wieder hinnehme (ist auskommentiert) Funktioniert gar nichts mehr (heißt ich kann am terminal nichts mehr empfangen - da kommt nix mehr an). Was ist da los? beißt sich da irgenwas und ich sehs nicht? ist ein Atmega16 mit externem Chrystal 10.000 MHz also liegts nicht am internen RC-Oszillator - wie gesagt, sobald ich mit dem ADC_Enable(); den ADC in den Free Running Mode versetze gehts nichtmehr. Darf ich das nicht!? CODE: #include <avr/io.h> #ifndef USART_H #define USART_H #define BAUD 9600UL //Hier Baudrate angeben: 57600UL #define UBRR_BAUD ((F_CPU/(16UL*BAUD))-1) #endif // USART initialisieren void uart_init(void) { // Baudrate einstellen (Normaler Modus) UBRRH = (uint8_t) (UBRR_BAUD>>8); UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff); // Aktivieren von transmitter //(1<<RXEN) UCSRB = (1<<TXEN) | (1<<RXEN); // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit, Even Parity UCSRC = (1<<URSEL) | (1<<UPM1)|(1<<UCSZ1)|(1<<UCSZ0); // Einstellen des Datenformats: 8 Datenbits, 2 Stoppbit //UCSRC = (1<<USBS)|(1<<USBS)|(3<<UCSZ0); // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) do { UDR; } while (UCSRA & (1 << RXC)); } char uart_getc(void) { while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben } void uart_putc(const char c) { while (!(UCSRA & (1<<UDRE))) //auf Sendebereitschaft warten { } UDR = c; //Zeichen Senden } void uart_puts (const char *s) { do { uart_putc (*s); //Ein Zeichen des strings senden } while (*s++); //So lange bis der String zu ende ist und gleich ein Zeichen weiterspringen } void uart_puti(const int16_t var) { char cache[7]; uart_puts (itoa(var, cache, 10)); } void ADC_Enable() { // Set ADC ADCSRA |= (1 << ADPS1) | (1<< ADPS2); // Prescaler // Set reference Voltage ADMUX |= (1 << REFS1) | (1 << REFS0) ; // Internal 2,56 V reference chosen // Set ADLAR = 1 to left adjust results ADMUX |= (1<< ADLAR); // Input Channel is ADC0 - so no changes in MUX! // Adjust Conversion mode ADCSRA |= (1 << ADATE); // Set ADC to Free-Running Mode // Datasheet p 221 //SFIOR = 0x00; // For Free Running Mode ADCSRA |= (1 << ADEN); // Enable ADC ADCSRA |= (1 << ADSC); // Start A2D Conversions } int main (void) { //ADC_Enable(); uart_init(); while (1) { uart_puts("TEST"); } } Ach hier kommt dann natürlich statt dem "TEST" das ADC register mit der entsprechenden uart_puti(ADCW); funktion rein. Hoffe mir kann jemand helfen !? Danke :)
Was hast du am AREF-Pin angeschlossen, nicht etwa Vcc/AVcc? Eine LED-Ansteuerung am Anfang von main() hilft, um beim Debuggen zu sehen, ob der AVR laufend resettet (Brownout, fehlende ISR).
Am AREF pin ist nichts angeschlossen. Verwende die interne Referenzspannung. Wenn ich ADCH auf PORTB ausgebe und mit einem Poti-Spannungsteiler die Spannung von 0 bis 2,56 V durchfahre funktioniert das ganze auch, solange ich das ganze UART geraffel rauslasse. Habe jetzt bemerkt, dass evtl. der Free Running MOde ein Problem sein könnte und habe das ganze auf Single Conversation umgeschrieben. Geht auch nicht besser. Drücke ich auf Reset bekomme ich einen fehlerhaften wErt ausgegeben: 25" statt 255 für V > Vref. Die irgendwas hängt da .. Brownout sollte nicht möglich sein, das ganze klemmt auf einem STK500, das ist doch spannungsstabilisiert, glaube ich? Wo steckt da der Fehler? Vielleicht ein Delay?
Du solltest deinen UART interruptgesteuert laufen lassen.
B.B. schrieb: > Am AREF pin ist nichts angeschlossen. In jedem Fall macht sich da aber ein Kondensator nicht schlecht (s. DS).
Hm, der Kondensator ändert gar nichts. Auf jeden Fall bleibt das Problem bestehen und ich komme da nicht weiter. Ich Verstehe nicht wo das Problem ist. Wenn ich auf dem STK500 auf "RESET" drücke bekomme ich einen kleinen wert - "51r" - in ZTerm zu sehen, danach gar nichts mehr, bis ich wieder auf Reset drücke. Ist meine Hardware hinüber? Also ist das STK500 vllt. im Eimer? Aber an den LEDs kann ich ganz eindeutig mit dem aktuellen code die 8LSB sehen ... und wenn ich den ADC deaktiviere dann kann ich super Zeichen senden ... Keine Ahnung?
1 | |
2 | |
3 | #include <avr/io.h> |
4 | #include <stdlib.h> |
5 | #include <util/delay.h> |
6 | |
7 | |
8 | |
9 | #ifndef USART_H
|
10 | #define USART_H
|
11 | |
12 | |
13 | |
14 | #define BAUD 9600UL // Baudrate
|
15 | #define UBRR_BAUD ((F_CPU/(16UL*BAUD))-1)
|
16 | |
17 | |
18 | |
19 | #endif
|
20 | |
21 | |
22 | |
23 | |
24 | // init UART
|
25 | void uart_init(void) |
26 | {
|
27 | |
28 | // Set Baudrate
|
29 | UBRRH = (uint8_t) (UBRR_BAUD>>8); |
30 | UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff); |
31 | |
32 | // activate
|
33 | UCSRB = (1<<TXEN) | (1<<RXEN); |
34 | |
35 | // 8 bit data, no parity, 1 stopbit
|
36 | UCSRC = (1<<URSEL) |(1<<UCSZ1)|(1<<UCSZ0); |
37 | |
38 | // 8 Datenbits, 2 Stoppbit
|
39 | //UCSRC = (1<<USBS)|(1<<USBS)|(3<<UCSZ0);
|
40 | |
41 | // Flush Receive-Buffer (remove wrong values)
|
42 | do
|
43 | {
|
44 | UDR; |
45 | }
|
46 | while (UCSRA & (1 << RXC)); |
47 | |
48 | }
|
49 | |
50 | |
51 | void uart_putc(const uint8_t c) |
52 | {
|
53 | while (!(UCSRA & (1<<UDRE))) // wait until ready to send |
54 | {
|
55 | }
|
56 | |
57 | UDR = c; // send charakter |
58 | }
|
59 | |
60 | void uart_puts (const char *s) |
61 | {
|
62 | |
63 | do
|
64 | {
|
65 | uart_putc (*s); //send one char of string |
66 | }
|
67 | while (*s++); //next char of string until end of string sign |
68 | |
69 | |
70 | }
|
71 | |
72 | void uart_puti(const uint16_t var) { |
73 | |
74 | char cache[7]; |
75 | uart_puts (utoa(var, cache, 10)); |
76 | |
77 | }
|
78 | |
79 | void ADC_Enable() { |
80 | |
81 | // Set ADC
|
82 | |
83 | ADCSRA |= (1 << ADPS1) | (1<< ADPS2); // Prescaler |
84 | |
85 | // Set reference Voltage
|
86 | ADMUX |= (1 << REFS1) | (1 << REFS0) ; |
87 | // Internal 2,56 V reference chosen
|
88 | |
89 | // Set ADLAR = 1 to left adjust results
|
90 | ADMUX |= (1<< ADLAR); |
91 | |
92 | // Input Channel is ADC0 - so no changes in MUX!
|
93 | |
94 | // Adjust Conversion mode
|
95 | |
96 | //ADCSRA |= (1 << ADATE); // Set ADC to Free-Running Mode
|
97 | // Datasheet p 221
|
98 | //SFIOR = 0x00; // For Free Running Mode
|
99 | |
100 | ADCSRA |= (1 << ADEN); // Enable ADC |
101 | ADCSRA |= (1 << ADSC); // Start A2D Conversions |
102 | |
103 | while (ADCSRA & (1 << ADSC)) {} // WArten bis initialmessung abgeschlossen ist |
104 | |
105 | |
106 | }
|
107 | |
108 | uint16_t ADC_Read( uint8_t channel ) |
109 | {
|
110 | // Choose ADC-Channel
|
111 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); |
112 | ADCSRA |= (1<<ADSC); // "single conversion" |
113 | while (ADCSRA & (1<<ADSC) ) {} // wait for conversion |
114 | return ADCW; // return result |
115 | }
|
116 | |
117 | int main (void) { |
118 | ADC_Enable(); // Enable ADC |
119 | |
120 | |
121 | uart_init(); // Enable UART |
122 | DDRB=0xFF; |
123 | |
124 | |
125 | while (1) { |
126 | |
127 | uart_puti(ADC_Read(0));// DO IT ! |
128 | uart_puts("\n"); |
129 | _delay_ms(1000); |
130 | |
131 | PORTB=(uint8_t)(ADC_Read(0) >>8 ); |
132 | |
133 | }
|
134 | }
|
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.