Forum: Mikrocontroller und Digitale Elektronik C programm


von espoir (Gast)


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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

"count" solltest Du als "volatile" deklarieren.

von Karl heinz B. (kbucheg)


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.

von Wolfram (Gast)


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.

von espoir (Gast)


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

von Karl heinz B. (kbucheg)


Lesenswert?

Wie testest du?
Welche Spannung führst du dem ADC von aussen zu?

von espoir (Gast)


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.

von Karl heinz B. (kbucheg)


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.

von espoir (Gast)


Lesenswert?

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

von Karl heinz B. (kbucheg)


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.

von espoir (Gast)


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

von Karl heinz B. (kbucheg)


Lesenswert?

Hmm.
Dann hab ich auch keine Idee mehr.

von espoir (Gast)


Lesenswert?

ok Danke dir für deinen Mühe

von Michael Wilhelm (Gast)


Lesenswert?

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

MW

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.