Forum: Mikrocontroller und Digitale Elektronik Attiny13A Atmel Studio6 Simulation überspringt Code


von Flo (Gast)


Lesenswert?

Hallo,
ich lasse geade eine Atmel Studio 6 ATtiny13A Simulation laufen und ich 
drehe langsam durch....
Das Prgramm überspringt immer die unten im code mit "#!#" makierten 
Zeilen!
( #!# sind nicht im Code vorhanden)
Ich bekomme es nicht hin, dass die ausgeführt werden. Schritt für 
schritt ausführen springt immer über die beiden zeilen und durchlaufen 
lassen zeigt auch keine wirkung.
Wisst ihr was da los ist?

LG,
Florian
1
uint16_t readVccVoltage(void) {
2
  // Returns the current Vcc voltage as a fixed point number with 3 implied decimal places, i.e.
3
  // 5000 = 5.000 volts, 2500 = 2.500 volts, 1900 = 1.900 volts
4
  
5
  V_DEV_ON; //turning on the voltage divider by setting PB0 low
6
  
7
  // Select ADC input PB2 and 1.1V (Internal Ref) 
8
  ADMUX = (1<<REFS0)|(1<<MUX0);
9
  
10
  // Enable ADC, set prescaller to /8 which will give a ADC clock of 1.2Mhz/8 = 150kHz
11
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0) ;
12
  
13
  _delay_ms(1);
14
15
  ADCSRA |= (1<<ADSC); // Start a conversion
16
  while( ADCSRA & (1<<ADSC) ) ; // Wait for 1st conversion to be ready...
17
  //..and ignore the result
18
  uint8_t dummy = ADCH;
19
  
20
  ADCSRA |= (1<<ADSC); // Start a conversion
21
  while( ADCSRA & (1<<ADSC) ) ; // Wait for conversion to be ready...
22
  V_DEV_OFF;  // turning PB0 high to save voltage at the voltage divider
23
  
24
  uint8_t low = ADCL;
25
  uint8_t high = ADCH;
26
  
27
#!#  uint16_t adcVal = (high << 8) | low; // 0<= result <=1023
28
  
29
#!#  uint16_t Vin = (uint16_t)((uint16_t)4100*adcVal)/1000;
30
  
31
  ADCSRA &= ~(1<<ADEN ); // Disable ADC to save power
32
  return(Vin);
33
}

von chris (Gast)


Lesenswert?

Da die beiden Variablen nicht benutzt werden, werden die beiden Zeilen 
wohl wegoptimiert.

von Flo (Gast)


Lesenswert?

Aber die variablen werden doch benutzt. adcVal wird in der Vin Rechnung 
genutzt und Vin wird aus der Funktion retruned.

von chris (Gast)


Lesenswert?

ups das habe ich übersehen :(
dann vergiss meine Bemerkung von oben^^

von Christian K. (the_kirsch)


Lesenswert?

Der Compiler hat wohl einfach den Code bei optimiert, deswegen 
überspringt der Simulator die Zeilen.

statt

uint8_t low = ADCL;
uint8_t high = ADCH;
uint16_t adcVal = (high << 8) | low;

kann man auch

uint16_t adcVal = ADCW;

schreiben.


warum rechnest du hier nicht einfach mal 41 und dann durch 10, das 
reicht doch, oder willst du absichtlich einen integer Überlauf 
provozieren?

uint16_t Vin = (uint16_t)((uint16_t)4100*adcVal)/1000;

von Peter II (Gast)


Lesenswert?

Christian K. schrieb:
> uint16_t Vin = (uint16_t)((uint16_t)4100*adcVal)/1000;

so mal die ganze cast nicht notwendig sind. denn adcVal ist ja schon 
uint16_t

von Thomas E. (thomase)


Lesenswert?

Flo schrieb:
> Aber die variablen werden doch benutzt. adcVal wird in der Vin Rechnung
> genutzt und Vin wird aus der Funktion retruned.

Aber weiter werden sie nicht genutzt. Deshalb schmeisst der Compiler das 
gnadenlos raus und berechnet das in den Registern.

Deklariere die beiden Variablen zum Debuggen global und volatile, dann 
kriegst du auch einen Breakpoint darauf.

1
  return(4100* (high << 8) | low) / 1000);
2
3
//besser:
4
  return(41* ADC / 10);

Mehr wird da doch nicht gemacht. Was glaubst du, wozu ein Optimierer da 
ist?


mfg.

von Flo (Gast)


Lesenswert?

Hallo Leute,
vielen Dank für eure Hilfe! Ich habe da eindeutig was dummes gemacht und 
das ACDW kannt ich noch nicht.
1
uint8_t low = ADCL;
2
uint8_t high = ADCH;
3
uint16_t adcVal = (high << 8) | low; // 0<= result <=1023
4
uint16_t Vin = (uint16_t)((uint16_t)4100*adcVal)/1000;
5
wurde durch
6
uint16_t Vin = (41*ADCW)/10;
7
ersetzt

Klappt wunderbar und spart Speicher. Vielen Dank!

von Bernd K. (prof7bit)


Lesenswert?

Flo schrieb:
> uint8_t low = ADCL;
> uint8_t high = ADCH;
>
> uint16_t adcVal = (high << 8) | low; // 0<= result <=1023

Du kannst auch direkt:
1
uint16_t adcVal = ADC
16 bit in einem Rutsch auslesen (oder besser gesagt vom Compiler in 2 
8bit Zugriffe aufteilen und zusammenführten lassen, sieht aufgeräumter 
aus)


>> uint16_t Vin = (uint16_t)((uint16_t)4100*adcVal)/1000;

Das wird bei der Multiplikation überlaufen, probiers stattdessen mal so:
1
uint16_t Vin = (uint16_t)((uint32_t)4100*adcVal)/1000;

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.