Rechnen ist schwer

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From German to

Threaded View
Hallo,

wie denn das?

Ich stoppel gerade an einem AVR-Prozessor in C und bekomme vom 10-Bit  
AD-Wandler einen int-Wert von 8-Bit heraus, der mir erst mal reicht.

In dummer Weise aber nicht lange:

Wertebereich.



Wie geht das?
Mit 25 Fallunterscheidungen im Integer-Bereich bleiben oder aber
wie, die Betonung liegt auf wie, umstellen auf signed Integer?


peter

Re: Rechnen ist schwer
Wenn Du in der Regelung "signed" arbeitest, solltest Du den Wert in  
signed umwandeln:

10bit unsigned in signed int umwandeln, dann den Offset (127) abziehen.

Gruss Udo

Re: Rechnen ist schwer


Quoted text here. Click to load it



100 abziehen ? Das Ergebnis in C hat dann sowieso 16 bit.

--  
MaWin, Manfred Winterhoff, mawin at gmx dot net
Homepage http://www.oocities.org/mwinterhoff/
We've slightly trimmed the long signature. Click to see the full one.
Re: Rechnen ist schwer
Am 10.02.2017 um 11:54 schrieb MaWin:
Quoted text here. Click to load it

Quoted text here. Click to load it


Quoted text here. Click to load it
Am 10.02.2017 um 11:26 schrieb Udo Pi:
Quoted text here. Click to load it
Hallo,




sign int 16Bit Rechenwert = int 8 Bit AD-WandlerWert

und gut?


Peter

Re: Rechnen ist schwer
Am 10.02.2017 um 11:54 schrieb MaWin:
Quoted text here. Click to load it

Quoted text here. Click to load it


Quoted text here. Click to load it
Hallo,




sign_int_16Bit_Rechenwert = int_8_Bit_AD-WandlerWert

und gut?


Peter

Re: Rechnen ist schwer
Peter Thoms wrote:
Quoted text here. Click to load it

Quoted text here. Click to load it


Quoted text here. Click to load it


Quoted text here. Click to load it

Nimm' doch bitte richtige Typen ohne implizite Annahmen, das oben ist
nur richtig, wenn "int_8_Bit" unsigned ist:

unsigned char AD_Value= Get_ADC() >> 2;    // 10bit als 8bit uchar lesen
signed short int Calc= AD_Value;
    // das ordnet Calc positive Werte von 0..255 zu


char AD_Value= Get_ADC() >> 2;    // 10bit als 8bit char lesen
signed short int Calc= AD_Value;
    // das ordnet Calc positive und negative Werte zu





Re: Rechnen ist schwer
Am 10.02.2017 um 13:17 schrieb Edzard Egberts:

Quoted text here. Click to load it

stdint.h:

int8_t
int16_t
int32_t
uint8_t
uint16_t
uint32_t


Re: Rechnen ist schwer
Heiko Lechner wrote:
Quoted text here. Click to load it

Ich kann nicht davon ausgehen, dass Pter diese typedefs bekannt sind und

nichts hinzu. Was Du nicht ganz ausgeschrieben hast:

typedef unsigned char uint8_t;
typedef signed short int int32_t;
typedef signed char int8_t;

Re: Rechnen ist schwer
On 10.02.2017 15:15, Edzard Egberts wrote:

Quoted text here. Click to load it

Quoted text here. Click to load it

Die zwei sind OK.

Quoted text here. Click to load it

Das ist aber Quatsch:

signed short int x;
_Static_assert(sizeof(x) == 4, "Failed");


x.c:2:1: error: static assertion failed: "Failed"
 _Static_assert(sizeof(x) == 4, "Failed");

Die stdint.h Typen sind immer zu bevorzugen, wenn man eine bestimmte



Johannes

--  
Quoted text here. Click to load it


We've slightly trimmed the long signature. Click to see the full one.
Re: Rechnen ist schwer
Johannes Bauer wrote:
Quoted text here. Click to load it

Stimmt, das sollte so aussehen:

typedef signed short int int16_t;

Quoted text here. Click to load it


Ich benutze stdint.h selber, ich kenne aber auch den Unterschied
zwischen "eingebauten" Typen und Definitionen.


Re: Rechnen ist schwer
Am 10.02.2017 um 15:15 schrieb Edzard Egberts:

Quoted text here. Click to load it

Quoted text here. Click to load it

Solche Definitionen sind compiler- bzw. systemspezifisch, eigene  
typedefs sind keinesfalls portabel. Wie Johannes bereits geschrieben  

sie nicht durch eigene Definitionen ersetzen.

Seit den 64 Bit Prozessoren kann man sich ja nicht mal mehr drauf  



DoDi

Re: Rechnen ist schwer
Peter Thoms wrote:
Quoted text here. Click to load it


Quoted text here. Click to load it


hier, wenn du mit 16Bit weiterrechnen willst, doch sinnvoll alle 10 Bits
auszulesen:

   uint16_t v;
   /* Bit ADLAR in Register ADMUX nicht gesetzt => "right adjusted" */
   v = (uint16_t) ADCL;  /* ADCL muss zuerst gelesen werden */
   v |= (uint16_t) ADCH << 8;

"right adjusted" bedeutet die 8 LSBs in ADCL und die 2 MSBs in ADCH.
In v steht nun das Ergebnis mit vollen 10 Bit (aber noch unsigned).


wegen der "integer promotion" (interne Umwandlung zu int, auf AVR also
16 Bit). Aus z.B. dem 8 Bit Wert -128 (0x80) kann so ungewollt -65408
(0xFF80) werden, da negative Zahlen in Zweierkomplement-Darstellung mit

<https://www.securecoding.cert.org/confluence/display/c/INT02-C.+Understand+integer+conversion+rules

Re: Rechnen ist schwer
Peter Thoms wrote:
Quoted text here. Click to load it


Quoted text here. Click to load it


hier, wenn du mit 16Bit weiterrechnen willst, doch sinnvoll alle 10 Bits
auszulesen:

   uint16_t v;
   /* Bit ADLAR in Register ADMUX nicht gesetzt => "right adjusted" */
   v = (uint16_t) ADCL;  /* ADCL muss zuerst gelesen werden */
   v |= (uint16_t) ADCH << 8;

"right adjusted" bedeutet die 8 LSBs in ADCL und die 2 MSBs in ADCH.
In v steht nun das Ergebnis mit vollen 10 Bit (aber noch unsigned).


wegen der "integer promotion" (interne Umwandlung zu int, auf AVR also
16 Bit). Aus z.B. dem 8 Bit Wert -128 (0x80) kann so ungewollt 0xFF80
werden (65408 als unsigned interpretiert), da negative Zahlen in

mit 0. Siehe hierzu auch:
<https://www.securecoding.cert.org/confluence/display/c/INT02-C.+Understand+integer+conversion+rules

Re: Rechnen ist schwer


Quoted text here. Click to load it

Quoted text here. Click to load it

Mit dem IAR-Compiler zumindest funktioniert der 16Bit-Zugriff  
automatisch ohne diese manuelle schiebereien..
ui16_AdcValue = ADC;


Quoted text here. Click to load it

Quoted text here. Click to load it

Quoted text here. Click to load it

Der andere Weg ist wenn die 8Bit reichen (warum den 8bitter mit 16Bit  

ui8_AdcValue = ADCL;


Gerald

Re: Rechnen ist schwer
Am 10.02.2017 um 20:07 schrieb Gerald Oppen:
Quoted text here. Click to load it

Quoted text here. Click to load it
Hallo,











peter

Re: Rechnen ist schwer
Gerald Oppen wrote:

Quoted text here. Click to load it

Quoted text here. Click to load it

AFAIK kann der GCC das nicht.

Re: Rechnen ist schwer

Quoted text here. Click to load it



// return ADC value if ready, -1 if not
static int16_t get_adc(void)
{
  // loop_until_bit_is_set(ADCSRA, ADIF);
  if (ADCSRA & _BV(ADIF))
  {
    ADCSRA |= _BV(ADIF);  
    return ADC;
  }
  return -1;
}

cu
Michael

Re: Rechnen ist schwer
Michael Schwingen wrote:

Quoted text here. Click to load it

Quoted text here. Click to load it


10 Jahre alten libc geschaut (memory mapped I/O bei einem ATmega128):
|  
| #define ADC       _SFR_IO16(0x04)
| #define _SFR_IO16(io_addr) _MMIO_WORD((io_addr) + 0x20)
| #define _MMIO_WORD(mem_addr) (*(volatile unsigned int *)(mem_addr))

Das ging also wohl schon immer und meine Erinnerung war falsch.

Re: Rechnen ist schwer



Quoted text here. Click to load it

Ja.

uint8_t wandlerwert = ADC>>2;

int16_t rechenwert = wandlerwert - 100;
--  
MaWin, Manfred Winterhoff, mawin at gmx dot net
Homepage http://www.oocities.org/mwinterhoff/
We've slightly trimmed the long signature. Click to see the full one.
Re: Rechnen ist schwer
Am 10.02.2017 um 10:51 schrieb Peter Thoms:
Quoted text here. Click to load it

Quoted text here. Click to load it


Quoted text here. Click to load it


(0-1023) in einen beliebigen anderen (ganzzahligen) Bereich abzubilden.  
Siehe Reference zu map(), dort findest Du ein Beispiel und auch die Formel.

Oder Du programmierst das selbst:
aus = (analogRead(A0) - 512) * irgendwas;

DoDi

Site Timeline