Forum: Mikrocontroller und Digitale Elektronik Mein ADC-Code beißt sich mit dem UART? Atmega16


von B.B. (Gast)


Lesenswert?

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 :)

von Krapao (Gast)


Lesenswert?

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).

von B.B. (Gast)


Lesenswert?

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?

von ... (Gast)


Lesenswert?

Du solltest deinen UART interruptgesteuert laufen lassen.

von Wolfgang (Gast)


Lesenswert?

B.B. schrieb:
> Am AREF pin ist nichts angeschlossen.

In jedem Fall macht sich da aber ein Kondensator nicht schlecht (s. DS).

von B.B. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.