Attiny13A Atmel Studio6 Simulation überspringt Code

Gast #3998306
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
}
#3998367
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;
#3998375
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.
Gast #3998409
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!
#3998423
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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren