Forum: Mikrocontroller und Digitale Elektronik Ringpuffer mit ADC Werten füllen und versetzt ausgeben


von Wasir (Gast)


Lesenswert?

Hallo liebe Mikrocontroller Gemeinde,
ich habe folgendes Problem: ein Ringpuffer soll 40 ADC Werte speichern 
und anschließend wieder ausgeben. Verwendete µC ist ein ATMEGA16 
programmiert in c.
Zur Ausgabe der Werte verwende ich ein USB Monitor Tool. Probleme habe 
ich nur, die ADC Werde in den Ringpuffer zu bringen und auch wieder 
heraus.


Hier mein bisheriger Code:
1
int main(void)
2
{
3
  char line[101];
4
     init ();  
5
  DDRC=0xFF;
6
  usbInit();                  // init USB stack
7
  sei();                    // set enable interrupt on
8
  for(;;)                  // the main event loop
9
  {
10
            static unsigned char ringbuffer[ 256 ];
11
      static unsigned short getindex = 0;
12
      static unsigned short putindex = 0;
13
      static unsigned short buffersize = 20;
14
15
      int putring( int uin )
16
      {
17
        //if ( buffersize >= sizeof ringbuffer )
18
        //  return -1;
19
        
20
        uin = read_ADC(5);
21
           uin=uin;
22
23
        ringbuffer[ putindex ] = uin;
24
        putindex++;
25
        if ( putindex >= sizeof ringbuffer )
26
          putindex = 0;
27
        buffersize++;
28
        return 0;
29
      }
30
31
      int getring( void )
32
      {
33
        //if ( !buffersize )
34
        //  return -1;
35
        {
36
        buffersize--;
37
        c = ringbuffer[ getindex ];
38
        getindex++;
39
        if ( getindex >= sizeof ringbuffer )
40
        getindex = 0;
41
        return c;
42
        }
43
      }
44
      
45
          PORTC = uin;     
46
      sprintf(line,"Wert = %4d \n", c);
47
      outprint(line);
48
  }
49
  return 0;
50
}

Nochmals zur Verständlichkeit: Die ADC Wandlung an sich funktioniert. 
Ohne den Ringpuffer kann ich die ADC Werte wunderbar über USB anzeigen 
lassen. Nur in Zusammenspiel mit dem Ringpuffer klappts nicht.


Danke für eure Hilfe!!
MfG

von Matthias (Gast)


Lesenswert?

Vermutlich scheitert das schon daran, dass der Compiler deinen Quellcode 
nicht schluckt, oder?

Tip: "sizeof" ist eine Funktion

von Wasir (Gast)


Lesenswert?

Auch wenn ich das "sizeof ringbuffer" einfach durch 256 ersetze komme 
ich nicht ans ziel.

Die Ausgabe von "c" mittels sprintf ergibt immer 0.

von Guru (Gast)


Lesenswert?

Gehe zurück auf "Los". Ziehe keine 4000 Euro ein.

Dir fehlen massiv C-Grundlagen.

Ausserdem nimmst Du die Situation nicht ernst genug. Der vorliegende 
Code lässt sich nicht kompilieren. Statt uns aber entweder den 
kompletten Code zu zeigen oder die Fehlermeldungen zu nennen, schreibst 
Du nur "Geht nicht".
So können wir Dir nicht helfen.

von Wasir (Gast)


Lesenswert?

Entschuldigt bitte, wenn ich euch zu wenig Infos gegeben habe. Hier ist 
nun das komplette Projekt zum downloaden:

http://dl.dropbox.com/u/6671425/Projekt.zip

von Guru (Gast)


Lesenswert?

>Entschuldigt bitte, wenn ich euch zu wenig Infos gegeben habe.
Die Entschuldigung kannst Du Dir in die Haare schmieren. ;-)

Was fehlt sind Infos, Fehlermeldungen und Problembeschreibungen.

Und so ein Archiv zu entpacken ist erstmal unnötig aufwendig für uns 
(wenn es auch einige gibt die das machen), wenn man den kompletten 
Quellcode direkt lesen kann.

von Guru (Gast)


Lesenswert?

Es geht ja nicht primär darum, das wir zuwenig Informationen haben, 
sondern darum, das Du lernen musst ein Problem zu analysieren. Dazu 
gehört ersteinmal es zu beschreiben : Das Du es dann oft trotzdem noch 
nicht allein lösen kannst liegt an einem fehlenden weiteren Lernschritt. 
Aber die Beschreibung einer Situation ist der ersten Schritt.

"Nomen est Omen", "Am Anfang war das Wort und das Wort war Geist" etcpp.

von Uwe (Gast)


Lesenswert?

uin=uin ???
Hä ??
Weißt du eigentlich was ein Ringpuffer ist ??
Man benutzt ihn so : Wenn er am Ende angekommen ist dann soll er zum 
Anfang gehen ! (Das machst du zwar aber danach machst du den Buffer 
Größer, also jedesmal wenn du durchgelaufen bist solange bis kein 
Speicher mehr da ist bzw. er den Stack oder deine Variablen 
überschreibt)
und wo zum Teufel sind eigentlich die Aufrufe für getring und putring.
Also wenn du die nicht aufrufst werden die auch nichts machen außerdem 
dürfen die nicht ind der main funktion stehen (Funktionen die Funktionen 
enthalten ?!?!!!!)
also
1.verstehen wie nen Ringbuffer funktioniert
2.verstehen was Pointer,Adressen,FIFOs ,stack,usw sind
3.Sich ne Einfürung in C durchlesen (für so ein programm solte ne 
einführung schon reichen)
4. loslegen
is noch kein Meister vom Himmel gefallen

von Wasir (Gast)


Lesenswert?

Hier das komplette main.c
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include <stdlib.h>
5
#include "usbdrv/usbdrv.h"
6
#include "printf.h"
7
#include "usbsend.h"
8
9
10
volatile unsigned int count;
11
12
13
unsigned char b[] = {0x00, 0x01, 0x03, 0x07,
14
                     0x0F, 0x1F, 0x3F, 0x7F};
15
int uin;
16
int c;
17
18
19
/************************************************************/
20
void init (void)
21
{
22
  DDRA  = 0x00;   // Eingang
23
    DDRC  = 0xFF;   // Port C.0-7 = Ausgang
24
   PORTC = 0x00;   // LEDs loeschen
25
}
26
27
unsigned int read_ADC(unsigned char chanel)
28
{
29
   unsigned int ADC_value=0;
30
31
        ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler / 8
32
  ADMUX = chanel & 0b11000111;
33
34
  
35
  ADCSRA |= (1<<ADSC);              // ADC aktivieren
36
     while(!(ADCSRA & (1<<ADIF)));     // auf Abschluss der Konvertierung warten (ADIF-bit)
37
38
     ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren
39
     ADC_value = ADC;
40
41
     return ADC_value;
42
  }
43
44
int main(void)
45
{
46
  char line[101];
47
     init ();  
48
  DDRC=0xFF;
49
  usbInit();                  // init USB stack
50
  sei();                    // set enable interrupt on
51
  for(;;)                    // the main event loop
52
  {
53
          //uin = read_ADC(5); // Port A.5
54
        //uin=uin;
55
      
56
      // Kontroll LED
57
      //if(uin > 500)
58
      //  PORTC=0xFF;
59
      //else
60
      //   PORTC=0x00;
61
62
      static unsigned char ringbuffer[ 40 ];
63
      static unsigned short getindex = 0;
64
      static unsigned short putindex = 0;
65
      static unsigned short buffersize = 0;
66
67
      int putring( int uin )
68
      {
69
        //if ( buffersize >= sizeof ringbuffer )
70
        //  return -1;
71
        
72
        uin = read_ADC(5);
73
           uin=uin;
74
75
        ringbuffer[ putindex ] = uin;
76
        putindex++;
77
        if ( putindex >= 40 )
78
          putindex = 0;
79
        buffersize++;
80
        return 0;
81
      }
82
83
      int getring( void )
84
      {
85
        //if ( !buffersize )
86
        //  return -1;
87
        {
88
        buffersize--;
89
        c = ringbuffer[ getindex ];
90
        getindex++;
91
        if ( getindex >= 40 )
92
        getindex = 0;
93
        return c;
94
        }
95
      }
96
      
97
          PORTC = uin;     
98
      sprintf(line,"Wert = %4d \n", c);
99
      outprint(line);
100
  }
101
  return 0;
102
}

Beim Build kommen keine Fehlermeldungen. Mein Problem ist es, dass ich 
die Werte, die ich mittels read_ADC() auf uin gebe nicht in den 
Ringpuffer gespeichert werden. Nach dem auslesen des Ringpuffers bekomme 
ich nur 0 zu sehen. Also wird dieser wohl leer sein.
Soll heißen, dass ich keine Werte dort hinein bekomme. Ich glaube, dass 
die der Fehler in diesen Zeilen steckt:
1
uin = read_ADC(5);
2
uin=uin;
3
ringbuffer[ putindex ] = uin;

von Guru (Gast)


Lesenswert?

>Mein Problem ist es, dass ich
>die Werte, die ich mittels read_ADC() auf uin gebe nicht in den
>Ringpuffer gespeichert werden.

Woran merkst Du das?

>Nach dem auslesen des Ringpuffers bekomme ich nur 0 zu sehen.
An welcher Stelle im Ablau bekommst Du nur 0 zu sehen? Durch welches 
Mittel?
Simulator? Glaskugel?

> Also wird dieser wohl leer sein.
Aha. Wieder Glaskugel?

>Ich glaube, dass
die der Fehler in diesen Zeilen steckt:
Und nun kommt noch die Religion in's Spiel.

Nun ich will DIch nicht weiter quälen.

Sie Dir mal die Ausgabe der Variable von c am Ende von main an.
Beantworte mir folgende Frage? Welchen Wert soll c haben und durch 
welche Zuweisung? Qual Dich nicht. Ich weiss.
Aber frage Dich folgendes "Wird durch die Definition einer Funktion auch 
gleichzeitig bewirkt, das die Funktion an der Stelle aufgerufen wird"?

Irgendwas solltest Du mal selbst beantworten.

von Matze (Gast)


Lesenswert?

Wenn du eine Compileroptimierung eingeschaltet hast, gibt es deine 
Funktionen putring() und getring() wahrscheinlich gar nicht in 
übersetzten Code.

von AVerr (Gast)


Lesenswert?

Um dich mal auf den richtigen Weg zu bringen ...
Weisst du, worin sich eine Funktionsdefinition von einem Funktionsaufruf 
unterscheiden ?

Eine Funktionsdefinition sieht folgendermaßen aus:
1
uint8_t funktion(uint8_t variable) {
2
  return variable + 1;
3
}

Ein Aufruf dieser Funktion eher so:
1
funktion(2);

Dein Problem liegt darin, dass du innerhalb der main-Funktion deine 
Funktionen getring und setring definierst, aber nicht aufrufst.
Eine Funktionsdefinition innerhalb einer Funktion sollte soviel ich weiß 
direkt zu einem Compilerfehler führen ( darum auch die vielen Nachfragen 
deswegen hier ).

getring und setring werden in der jetzigen Version gar nicht aufgerufen, 
daher wird auch nichts am Puffer geändert und auch gar nichts mit dem 
ADC gemessen.

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.