www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C programm


Autor: espoir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo leute,
ich brauche eure Hilfe.
ich habe ein C-code für ATtiny45 geschrieben, dies code hat dies
funktionalität:
AD-Wandler wird intialisiert und gibt den Messwert wiederzurück.
in ein Feld wird das Ergebniss gespeichert.
mein Ziel ist so:wird AD-Wandler gelesen, und in erste Element
gespeichet, dann wartet einger zeit wirdi erhöht und messt wieder.
mein Problem: wenn ich ein Breackpoint setze  krige ich schon die
gewünschte Messungen( d.h. unterschiedliche werte werden im Feld
gespeichert), abet wenn ich das Programm laufen lasse(ohne
Breack-point), wird im Feld die gleiche wert gespeichert.
ich habe das 20 mal durchgelesen, aber finde die lösung nicht.
hier das code

/**************main.c*************************/

#include <iot45v.h>
#include "adc.h"
#include "timer.h"
//void int_timer0(void);
//#pragma interrupt_handler int_timer0:iv_TIMER0_OVF

//int Ergebnis;
//void get_sensor(void);
unsigned int digital_wert,i;
unsigned int test[20];


void main()
{

  Adc_Init();
  DDRB=0x17;
  PORTB=0x00;
  //while(1)


   for(i=0; i<=20; i++)
   {
        test[i]= umsetzen_Spannung();
        wait_10ms(2);
    PORTB=0x17;
    wait_10ms(2);
    PORTB=0x00;
    //PORTB=0x17;
  }


  //PORTB=0x17;
    while(1);

}

/******************Timer.c***************************/
#include "timer.h"
#include <iot45v.h>
#pragma interrupt_handler int_timer0:iv_TIMER0_OVF

unsigned int count=0;
void wait_10ms(unsigned char time)
{
  TCNT0 = 173;
  SREG |= (1<<7);       //SREG:Bit 7 – I: Global Interrupt Enable
  TIMSK = (1<<TOIE0);//Timer0 Int. Enable
  TCCR0B = (1<<CS02)|(1<<CS00);
  while(count<time)  {};
  count=0;
}

void int_timer0(void)
{
  //PORTB=0x17;
  count++;
  TCNT0 = 173;
  TCCR0B = (1<<CS02)|(1<<CS00);
}


void get_sensor(void)
{
 //Adc_Init();
 //umsetzen_Spannung();
 }

/******************adc.c*******************************/

#include "adc.h"
#include <iot45v.h>

unsigned int Ergebnis;

void Adc_Init(void)
   {
     ADCSRA = 0x80;           //Durch das setzen von Bit ADEN schaltet
Der AD-Umsetzer ein
   ADMUX = 0x03;           //wählt der Kanal(ADC3) und setzt die
Rferenzspannung auf 5v
  }

unsigned int umsetzen_Spannung(void)
  {
    ADCSRA = 0xC3;                  //AD-Umsetzer Starten und Prescaler
auswählen
  while ( ADCSRA & (1<<ADSC));      //Warte-Schleife bis Ende der
Umsetzung
  Ergebnis=(ADCL+ADCH*256);
  return Ergebnis;       // Im ADCL sind die ersten 8 bits des
Ergebnisses
                         // Im ADCH sind die restlichen 2 Bits
gespeichert
  }



Danke euch

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"count" solltest Du als "volatile" deklarieren.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du ein Array erzeugst:

unsigned int test[20];


dann hat dieses Array 20 Elemente. Dies sind die Elemente

0, 1, 2, 3, ..., 17, 18, 19

Zähl sie mit den Figern ab: sind genau 20

Dann aber machst du:

   for(i=0; i<=20; i++)
   {
        test[i]= umsetzen_Spannung();

Hier wird i irgendwann den Wert 20 kriegen. Das heist aber
auch du weist einem test[20] einen Wert zu. Das Array hat
aber keine Element test[20]. Das höchste zulässige ist
test[19]! Das heist aber auch, dein Program versucht in
einen Speicherbereich zu schreiben, der irgendwo liegt.
Spätestens jetzt ist Funktionalität deines Programmes völlig
undefiniert, alles mögliche kann passieren.

for-Schleifen, die über Arrays laufen, schauen eigentlich
immer so aus:

   for( i = 0; i < 20; i++ )

Beachte: 'Kleiner', nicht 'Kleiner gleich'.

Profis machen das übrigens anders. Die stört nämlich, dass da
im Code, die Zahl 20 explizit vorkommt. Ein Profi schreibt
das ganze zb. so

  for( i = 0; i < sizeof(test)/sizeof(*test); i++ ) {
    test[i] = unsetzen_Spannung();
    ...

oder er macht folgendes:

unsigned char test[20];
#define NR_TEST  (sizeof(test)/sizeof(*test))

....


   for( i = 0; i < NR_TEST; i++ ) {
     test[i] =
     ...

ist aber im Grunde dasselbe, nur besser lesbar. Das Prinzip
ist aber immer das Gleiche: Der Compiler soll die Anzahl
aus der eigentlichen Array-Dekleration ausrechnen anstatt
sich darauf zu verlassen, dass der Programmierer schon an allen
Stellen die richtigen Zahlen benutzt.

Weiter hab ich mir im Übrigen dein Pgm noch nicht angesehen.

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder
#define NR_TEST  20 // Beschreibung /Grenzen?
unsigned char test[NR_TEST];


....


   for( i = 0; i < NR_TEST; i++ ) {
     test[i] =
     ...

hat den Vorteil das man das #define in eine zentrale
Konfigurationsdatei legen kann.

Autor: espoir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
das war nicht das problem,mit 20 war nur falsche eingetippt, die for
Schleife läuft von 0 bis 19 ist schon Klar.
ich habe auch den count als Volatile deklariert ich kriege das gleiche
Ergebnis

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie testest du?
Welche Spannung führst du dem ADC von aussen zu?

Autor: espoir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
als Rferenzspannung 5v, um das zu testen das geht alles so.
auf mein Plattine befindet sich ein drucksensor, ich ändere den druck,
und klar wird am AD-Wandler eine Spannung, die umgewandelt wird.
ich arbeite mit AVR studio dann lese ich die ausgegebene werte.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dir ist aber schon klar, dass die ganze Schleife
noch nicht mal 1 Sekunde dauert?
Ändert sich das Drucksignal entsprechend schnell?

Vorausgesetzt natürlich, dass die wait_10ms Funktion
richtig ist.

Autor: espoir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe nicht verstanden was du meinst, kannst di vieleicht etwas klar
sein.ich glaube mein gehirn ist schon verstoppft

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Worauf ich hinaus will:
Wenn sich der ADC Input nur langsam ändert, dann wirst
du das in deinem Pgm nicht feststellen können, da
das Pgm gerade mal knapp 1 Sekunde den ADC misst.

Setzt du einen Breakpoint in die Schleife, dann sieht
die Sache anders aus, da du ja als Benutzer sehr
viel länger brauchst um das Pgm weiterlaufen zu lassen.

Daher kann es sein, dass mit dem Breakpoint in der Schleife
du verschiedene Werte siehst. Gibst du den Breakpoint weg,
dann sieht alles gleich aus, weil das Pgm einfach zu schnell
ist um irgendwelche Änderungen messen zu können.

Autor: espoir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
d.h soll ich  mit  wart-fkt länger warten? so wart_10ms(200)z.bp.
so meinst du oder?
wenn so ich habe mit eine min ausprobiert aber immer die gleiche

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm.
Dann hab ich auch keine Idee mehr.

Autor: espoir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok Danke dir für deinen Mühe

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du das while(1) denn wieder aktiviert? ansonsten setzt die Software
jedesmal neu auf.

MW

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.