- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 10

Thema: ADC für ATXmega128A1

  1. #1

    Unglücklich ADC für ATXmega128A1

    Anzeige

    Powerstation Test
    Hallo,

    ich ein Fehler in dem Code. Wenn Spannung am ADC fehlt runter, LEDs zeigen das. Aber wenn es steigt, LEDs sind immer aus. Ich nutze CodeVisionAVR und arbeite mit dem Xmega128-A1 Xplained board.

    Code:
    #include <xmega128a1.h> //Xmega-A1-Xplained development board
    
    #define LED PORTE// LED as PORT E.
    
    volatile int Result;
    
    void main()
    {
    LED.DIR = 0b00001111;  //E0 - E3 - outputs.
    
    PORTA.DIR = 0;                                  // configure PORTA as input
    ADCA.CTRLA |= 0x1;                              // enable adc
    ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;           // 12 bit conversion
    ADCA.REFCTRL = ADC_REFSEL_VCC_gc | 0x02;        // internal 1V bandgap reference
    ADCA.PRESCALER = ADC_PRESCALER_DIV8_gc;         // peripheral clk/8 (2MHz/16=250kHz)
    ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;// single ended
    ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc; 	    // PORTA:0 
    
        while(1)  // cycle
        { 
            ADCA.CH0.CTRL |= ADC_CH_START_bm; // start conversion on channel 0
            while(!ADCA.CH0.INTFLAGS);
            Result = ADCA.CH0RES;
            
            if (Result > 1000) //
            {
                LED.OUTSET = (1 << 0); // output E0 High.
            } //if
            if (Result > 2000) //
            {
                LED.OUTSET = (1 << 1); // output E1 High.
            } //if        
            if (Result > 3000) //
            {
                LED.OUTSET = (1 << 2); // output E2 High.
            } //if        
            if (Result > 4000) //
            {
                LED.OUTSET = (1 << 3); // output E3 High.
            } //if
           }//while(1)
    }//main
    Geändert von Fogtech (29.01.2013 um 11:25 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    ich programmiere zwar nicht mit C, hätte aber einen Vorschlag.
    Als erstes würde ich zu debug-Zwecken ein Delay in die Mainloop einfügen, um zu sehen, was passiert. Außerdem würde ich die If-Abfragen besser eingrenzen, den angenommen dein Wert ist 3100, dann trifft das auf 3 Ifs zu:
    if (Result > 1000)
    if (Result > 2000)
    if (Result > 3000)
    Stattdessen könntest du schreiben:
    if (Result >= 1000 && Result < 2000)
    if (Result >= 2000 && Result < 3000)
    usw...

    Ein >= ist übrigens besser als ein >, da der µC nur das >= kennt, nicht jedoch das >. Somit sparst du ein paar Takte (auch wenns bei dieser Anwendung egal sein sollte).

    Gruß
    Chris

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.11.2004
    Beiträge
    451
    liegt daran, dass du die LEDs nicht wieder ausschaltest.

    Entweder bei jeder if-schleife ein:
    else
    LED.OUTCLR = ...

    oder alles in eine Variable und am ende erst die leds an bzw. aus machen.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    durch die Zuweisung sollten doch die nicht gebrauchten LEDs wieder ausgeschaltet werden, oder irre ich mich da?
    LED.OUTSET = (1 << 1);
    bedeutet doch:
    PORTE = &B00000010

    Gruß
    Chris

  5. #5
    Hi,
    LED.OUTSET = (1 << 1); - das ist richtig
    Die Sache ist die, das die LEDs lassen sich ausschalten, aber nicht wieder leuchten, wenn aber Result wieder steigt.


    Gruß
    Max

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    hast du den die Möglichkeit, die Daten irgendwie zu visualisieren, also z.b. über UART an den PC senden? Dann könntest du dir Result ausgeben lassen.

    Gruß
    Chris

  7. #7
    Ich bin noch Anfänfer, und so weit nicht gekommen. Aber wenn ich am Ende meiner Schleife LED.OUTCLR = 0b00001111; setze, dann funktioniert es irgendwie. Alle LEDS leuchten und die, die eigentlich leuchten sollten, sind dunkler.

    Gruß
    Max

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    ok, alles klar!
    die, die eigentlich leuchten sollten, sind dunkler.
    Wieso schreibst du in der Mehrzahl? Schreibfehler?

    Dass manche LEDs "dunkler" leuchten, liegt wohl daran, dass sie erst eingeschaltet werden und dann durch dein LED.OUTCLR = 0b00001111; wieder ausgeschaltet.

    Gruß
    Chris

    EDIT:
    Sind die LEDs gegen Masse oder gegen VCC geschaltet?
    Geändert von Che Guevara (29.01.2013 um 12:32 Uhr)

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.11.2004
    Beiträge
    451
    Mit OUTSET werden nur die bits an den entsprechenden Stellen im OUT Register gesetzt. Sie Werden aber nicht gelöscht, wenn da eine 0 steht!
    Mit OUTCLR werden die bits entsprechend gecleared, wenn da eine 1 steht. 0 macht wiederum nichts.

    Entweder du greifst auf das LED.OUT zu, beschreibst aber dann den kompletten PORT.
    Daten können überschrieben werden, bzw. müssen erst geladen, dann manipuliert und wieder gespeichert werden. (ist in C mit einem "|=" bzw. "&=" anstelle des normalen "=" gelöst)
    Hier können Daten verloren gehen, wenn gerade ein Interrupt einspringt und den selben Port manipulieren will. (passiert eher selten, gibt aber lustige Fehler )

    Oder aber du arbeitest mit den SET und CLR Registern.

    Kommt aber auch immer darauf an, was der PORT machen soll, mal ist das eine dann das andere besser geeignet. Beides hat seine Vor- und Nachteile.

  10. #10
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Wieso schreibst du in der Mehrzahl? Schreibfehler?
    weil z.B. wenn Result liegt zw. 2000 und 3000 soll es LED0 , LED1 und LED2 leuchten.

    Code:
        while(1)  // cycle
        { 
            ADCA.CH0.CTRL |= ADC_CH_START_bm; // start conversion on channel 0
            while(!ADCA.CH0.INTFLAGS);
            Result = ADCA.CH0RES;
            
            if (Result > 1000) //
            {
                LED.OUTSET = (1 << 0); // output E0 High.
            } //if
            if (Result > 2000) //
            {
                LED.OUTSET = (1 << 1); // output E1 High.
            } //if        
            if (Result > 3000) //
            {
                LED.OUTSET = (1 << 2); // output E2 High.
            } //if        
            if (Result > 4000) //
            {
                LED.OUTSET = (1 << 3); // output E3 High.
            } //if
            LED.OUTCLR = 0b00001111;
           }//while(1)
    }//main
    Wenn ich aber anderes code verwende, dann bleibt nur ein aktuelles LED dunkler.

    Code:
      while(1)  // cycle
        { 
            ADCA.CH0.CTRL |= ADC_CH_START_bm; // start conversion on channel 0
            while(!ADCA.CH0.INTFLAGS);
            Result = ADCA.CH0RES;
            
            if (Result >= 0 && Result < 1000) //
            {
                LED.OUTSET = (1 << 0); // output E0 High.
            } //if
            if (Result >= 2000 && Result < 3000) //
            {
                LED.OUTSET = (1 << 1); // output E1 High.
            } //if        
            if (Result >= 2000 && Result < 3000) //
            {
                LED.OUTSET = (1 << 2); // output E2 High.
            } //if        
            if (Result >= 3000 && Result < 4096) //
            {
                LED.OUTSET = (1 << 3); // output E3 High.
            } //if
            LED.OUTCLR = 0b00001111;
           }//while(1)
    }//main
    - - - Aktualisiert - - -

    @robin, @Che Guevara

    Danke euch beiden! Ihr habt mir wirklich geholfen! So sieht es jetzt aus:

    Code:
    //I/O Registersdefinition:
    #include <xmega128a1.h> //Xmega-A1-Xplained development board
    #include <delay.h>
    
    #define LED PORTE// LED as PORT E.
    
    volatile int Result;
    
    void main()
    {
    LED.DIR = 0b00001111;  //E0 - E3 - outputs.
    
    PORTA.DIR = 0;                                  // configure PORTA as input
    ADCA.CTRLA |= 0x1;                              // enable adc
    ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;           // 12 bit conversion
    ADCA.REFCTRL = ADC_REFSEL_VCC_gc | 0x02;        // internal 1V bandgap reference
    ADCA.PRESCALER = ADC_PRESCALER_DIV8_gc;         // peripheral clk/8 (2MHz/16=250kHz)
    ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;// single ended
    ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc; 	    // PORTA:0 
    
        while(1)  // cycle
        { 
            ADCA.CH0.CTRL |= ADC_CH_START_bm; // start conversion on channel 0
            while(!ADCA.CH0.INTFLAGS);
            Result = ADCA.CH0RES;
            
            if (Result >= 0 && Result < 1000) //
            {
                LED.OUTCLR = (1 << 0); // output E0 High.
            } //if
            if (Result >= 1000 && Result < 2000) //
            {
                LED.OUTCLR = (1 << 1); // output E1 High.
            } //if        
            if (Result >= 2000 && Result < 3000) //
            {
                LED.OUTCLR = (1 << 2); // output E2 High.
            } //if        
            if (Result >= 3000 && Result < 4096) //
            {
                LED.OUTCLR = (1 << 3); // output E3 High.
            } //if
            delay_ms(50);
            LED.OUTSET = 0b00001111;
           }//while(1)
    }//main

Ähnliche Themen

  1. ATXmega128A1 Rev. H unerklärliches ADC-Phänomen
    Von Oreas im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 28.11.2012, 12:24
  2. Mikrocontroller ATXmega128A1 Programmier-Problem
    Von Drazhoath im Forum AVR Hardwarethemen
    Antworten: 6
    Letzter Beitrag: 08.05.2012, 17:48
  3. Spannugsteiler für ADC
    Von kurzwelle im Forum Elektronik
    Antworten: 8
    Letzter Beitrag: 12.01.2010, 19:04
  4. BASCOM und ATxmega128A1
    Von Hellmut im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 7
    Letzter Beitrag: 07.10.2008, 10:31
  5. klassse für adc
    Von timfri im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 06.02.2007, 11:11

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress