Forum: Mikrocontroller und Digitale Elektronik (Wahrscheinlich) Pointer Problem


von Martin K. (thereallife)


Lesenswert?

Moin Leute,
Ich habe anscheind ein Pointer problem bzw mache da einen Fehler, sehe 
diesen allerdings nicht.

Allgemein:
Ich nutze einen ATmega32A
an diesem ist ein 74hc165. Am 165 ist ein Drehencoder an den ersten 
beiden Pins angeschlossen alle anderen DATA_Inputs vom 165er habe ich 
auf masse gelegt. Das Auslesen funktioniert soweit problemlos.
Nur bei der Datenverarbeitung scheine ich einen Fehler zu machen, wenn 
ich mir mein value ausgeben lasse, bekomme ich meistens eine 0 hin und 
wieder 183 oder 181...

Der Fehler müsste meiner meinung nach zwischen der funktion read encoder 
(beim switch wo er die funktion aufruft) und der funktion wertSkalieren 
liegen. Ich habe euch dennoch mal den ganzen Code kopiert.
Hier mal mein Code.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#ifndef F_CPU
4
#define F_CPU 8000000UL
5
#endif
6
#include <stdio.h>
7
#define BAUD 9600L 
8
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   
9
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     
10
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)
11
////////////////////////////////////////////////////////////////////
12
int uart_putchar(char c, FILE *stream)
13
{
14
  loop_until_bit_is_set(UCSRA, UDRE);
15
  UDR = c;
16
  return 0;
17
}
18
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
19
////////////////////////////////////////////////////////////////////
20
#include <util/delay.h>
21
////////////////////////////////////////////////////////////////////
22
#define DATA595_PIN        PC0
23
#define DATA595_PORT      PORTC
24
#define DATA595_DDR        DDRC
25
///////
26
#define DATA595_high()      (DATA595_PORT |= _BV(DATA595_PIN))
27
#define DATA595_low()      (DATA595_PORT &= ~_BV(DATA595_PIN))
28
////////////////
29
#define RCLOCK595_PIN      PC2
30
#define RCLOCK595_PORT      PORTC
31
#define RCLOCK595_DDR      DDRC
32
///////
33
#define RCLOCK595_high()    (RCLOCK595_PORT |= _BV(RCLOCK595_PIN))
34
#define RCLOCK595_low()      (RCLOCK595_PORT &= ~_BV(RCLOCK595_PIN))
35
////////////////
36
#define CLOCK595_PIN      PC1
37
#define CLOCK595_PORT      PORTC
38
#define CLOCK595_DDR      DDRC
39
///////
40
#define CLOCK595_high()      (CLOCK595_PORT |= _BV(CLOCK595_PIN))
41
#define CLOCK595_low()      (CLOCK595_PORT &= ~_BV(CLOCK595_PIN))
42
////////////////////////////////////////////////////////////////////
43
#define DATA165_PIN        PC5
44
#define DATA165_PORT      PORTC
45
#define DATA165_DDR        DDRC
46
////////////////////////////
47
#define CLOCK165_PIN      PC4
48
#define CLOCK165_PORT      PORTC
49
#define CLOCK165_DDR      DDRC
50
#define CLOCK165_high()      (CLOCK165_PORT |= _BV(CLOCK165_PIN))
51
#define CLOCK165_low()      (CLOCK165_PORT &= ~_BV(CLOCK165_PIN))
52
////////////////////////////
53
#define PARALLEL165_PIN      PC3
54
#define PARALLEL165_PORT    PORTC
55
#define PARALLEL165_DDR      DDRC
56
#define PARALLEL165_high()    (PARALLEL165_PORT |= _BV(PARALLEL165_PIN))
57
#define PARALLEL165_low()    (PARALLEL165_PORT &= ~_BV(PARALLEL165_PIN))
58
////////////////////////////////////////////////////////////////////
59
uint8_t Encoder1AS;
60
uint8_t Encoder1BS;
61
uint8_t encoderState;
62
uint8_t oldEncoderState;
63
uint8_t encoderValue;
64
////////////////////////////////////////////////////////////////////
65
66
void get_Encoder_data(int v165)
67
{
68
  Encoder1AS = (v165 & _BV(1)) ? 1:0;
69
  Encoder1BS = (v165 & _BV(2)) ? 1:0;
70
  printf("\n");
71
  printf("test encodder A =");
72
  printf("%d", Encoder1AS);
73
  printf("\n");
74
  printf("test encodder B =");
75
  printf("%d", Encoder1BS);
76
  printf("\n");
77
}
78
79
////////////////////////////
80
int wertSkalieren(uint8_t *value, int offset)
81
{
82
  *value = value+offset;
83
  return (int)value;
84
}
85
86
////////////////////////////
87
88
void setup_Encoder()
89
{
90
  oldEncoderState = encoderState = (Encoder1AS << 1) | Encoder1BS;
91
  encoderValue = 0;
92
}
93
////////////////////////////
94
95
void read_Encoder()
96
{
97
  encoderState = (Encoder1AS<<1) | Encoder1BS;
98
  if (encoderState != oldEncoderState)
99
  {
100
    uint8_t transition = (oldEncoderState << 2) | encoderState;
101
    
102
    switch (transition) {
103
      case 0b0001:  wertSkalieren( &encoderValue, -1 ); break;
104
      case 0b0010:  wertSkalieren( &encoderValue, +1 ); break;
105
      
106
      case 0b0100:  wertSkalieren( &encoderValue, +1 ); break;
107
      case 0b0111:  wertSkalieren( &encoderValue, -1 ); break;
108
      
109
      case 0b1000:  wertSkalieren( &encoderValue, -1 ); break;
110
      case 0b1011:  wertSkalieren( &encoderValue, +1 ); break;
111
      
112
      case 0b1101:  wertSkalieren( &encoderValue, +1 ); break;
113
      case 0b1110:  wertSkalieren( &encoderValue, -1 ); break;
114
    }
115
    oldEncoderState = encoderState;
116
  }
117
}
118
119
120
////////////////////////////////////////////////////////////////////
121
void USART_Init( unsigned int baud )
122
{
123
  UBRRH = UBRR_VAL >>8;
124
  UBRRL = UBRR_VAL & 0xFF;
125
  UCSRB = (1<<RXEN)|(1<<TXEN);
126
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
127
}
128
//////////////////////////////////////////////////////////////////
129
void InitShiftOut()
130
{
131
  RCLOCK595_DDR |= _BV(RCLOCK595_PIN);
132
  CLOCK595_DDR |= _BV(CLOCK595_PIN);
133
  DATA595_DDR |= _BV(DATA595_PIN);
134
}
135
void InitShiftIn()
136
{
137
  PARALLEL165_DDR |= _BV(PARALLEL165_PIN);
138
  CLOCK165_DDR |= _BV(CLOCK165_PIN);
139
  DATA165_DDR &= ~_BV(DATA165_PIN);
140
  DATA165_PORT &= ~_BV(DATA165_PIN);
141
}
142
////////////////////////////////////////////////////////////////////
143
void Pulse595Clock()
144
{
145
  CLOCK595_high();
146
  CLOCK595_low();
147
}
148
void Pulse165Clock()
149
{
150
  CLOCK165_low();
151
  CLOCK165_high();
152
}
153
154
////////////////////////////////////////////////////////////////////
155
156
void Pulse595Rclock()
157
{
158
  RCLOCK595_high();
159
  RCLOCK595_low();
160
}
161
void Pulse165Parallel()
162
{
163
  PARALLEL165_low();
164
  PARALLEL165_high();
165
}
166
167
////////////////////////////////////////////////////////////////////
168
169
void ShiftOut(uint8_t var)
170
{
171
  for (uint8_t i =0; i<8; i++)
172
  {
173
    if(var & 0b10000000)
174
    {
175
      DATA595_high();
176
    }
177
    else
178
    {
179
      DATA595_low();
180
    }
181
    Pulse595Clock();
182
    var=var<<1;
183
    DATA595_low();
184
  }
185
  Pulse595Rclock();
186
}
187
////////////////////////////////////////////////////////////////////
188
#if 0
189
void ShiftIn(int *var)
190
{
191
  CLOCK165_high();
192
  Pulse165Parallel();
193
  for (unsigned char i = 0; i < 8; ++i)
194
  {
195
    *var <<= 1;
196
    if (DATA165_read())
197
    *var |= 0x01;
198
    Pulse165Clock();
199
  }
200
  CLOCK165_low();
201
}
202
#endif
203
static uint8_t DATA165_read(void)
204
{
205
  if (PINC & _BV(DATA165_PIN))
206
  printf("1");
207
  else
208
  printf("0");
209
  return (PINC & _BV(DATA165_PIN)) ? 1 : 0;
210
}
211
212
uint8_t ShiftIn(void)
213
{
214
  uint8_t shiftResult;
215
  
216
  CLOCK165_high();
217
  Pulse165Parallel();
218
  
219
  for (unsigned char i = 0; i < 8; ++i) {
220
    shiftResult |= DATA165_read();
221
    shiftResult <<= 1;
222
    Pulse165Clock();
223
  }
224
  CLOCK165_low();
225
  return shiftResult;
226
}
227
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
230
231
int main(void)
232
{
233
  stdout = &mystdout;
234
  long baud = 9600UL;
235
  USART_Init(baud);    
236
  InitShiftIn();
237
  int v165 = 0;
238
  InitShiftOut();
239
  while(1)
240
  {
241
    //ShiftIn(var);
242
    printf("\n Binärcode : ");
243
    v165 = ShiftIn();
244
    ShiftOut(v165);
245
    printf("\n Variable: ");
246
    printf("%d", v165);
247
    setup_Encoder();
248
    get_Encoder_data(v165);
249
    read_Encoder();
250
    printf("%d", encoderValue);
251
  }
252
}

Grüße
Martin

von mio (Gast)


Lesenswert?

1
  *value = *value+offset;
 +die Zeile unten drunter

von Peter II (Gast)


Lesenswert?

1
int wertSkalieren(uint8_t *value, int offset)
2
{
3
  *value = value+offset;
4
  return (int)value;
5
}

das return ist falsch, schon der cast hätte dich wundern müssen.
1
int wertSkalieren(uint8_t *value, int offset)
2
{
3
  *value = value+offset;
4
  return *value;
5
}

von Martin K. (thereallife)


Lesenswert?

Danke schonmal, das hatte ich auch schonmal.
dann kommt beim value allerdings 0 oder 1 oder 255 raus... ^^

von Martin K. (thereallife)


Lesenswert?

Peter II schrieb:
int wertSkalieren(uint8_t *value, int offset)
{
  *value = value+offset;
  return *value;
}

dann bekomme ich die warnmeldung
assignment makes integer from pointer without a cast

und ich er ist wieder bei 0, 183, 181...

wenn ich das so mache:
1
int wertSkalieren(uint8_t *value, int offset)
2
{
3
  *value = *value+offset;
4
  return *value;
5
}
ist die fehlermeldung logischerweise weg,
allerdings bekomme ich wieder werte mit 0 , 1 oder 255...

Warum ist das return so falsch gewesen? möchte ich nicht eigentlich 
einen integer wert zurückgeben und keinen pointer?

von mio (Gast)


Lesenswert?

Du möchtest gar nicht zurückgeben, denn der Rückgabewert von 
'wertSkalieren' wird nicht zugewiesen.

Wo wird denn eigentlich 'encoderValue' gesetzt?

von Marcel (Gast)


Lesenswert?

Martin Kathke schrieb:
> Warum ist das return so falsch gewesen? möchte ich nicht eigentlich
> einen integer wert zurückgeben und keinen pointer?

value ist der Zeiger.
*value ist das worauf der Zeiger zeigt.

Martin Kathke schrieb:
> allerdings bekomme ich wieder werte mit 0 , 1 oder 255...

Du wirfst unsigned und signed Variablen durcheinander. 255 ist -1, wenn 
man die 255 als signed interpretiert.

von Ralf G. (ralg)


Lesenswert?

1
////////////////////////////
2
int wertSkalieren(uint8_t *value, int offset)
3
{
4
  *value = value+offset;
5
  return (int)value;
6
}
Diese Mischung aus singned/ unsigned und dann noch mit unterschiedlicher 
Breite ist wenigstens ünglücklich gewählt, wenn nicht sogar 
fehleranfällig.
Ich würde das hier auf eine einheitliche Breite und einheitliches 
Vorzeichen bringen:
1
////////////////////////////
2
int8_t wertSkalieren(int8_t value, int8_t offset)
3
{
4
  return value + offset;
5
}

von Martin K. (thereallife)


Lesenswert?

Ralf G. schrieb:
> ////////////////////////////
> int wertSkalieren(uint8_t *value, int offset)
> {
>   *value = value+offset;
>   return (int)value;
> }
> Diese Mischung aus singned/ unsigned und dann noch mit unterschiedlicher
> Breite ist wenigstens ünglücklich gewählt, wenn nicht sogar
> fehleranfällig.
> Ich würde das hier auf eine einheitliche Breite und einheitliches
> Vorzeichen bringen:////////////////////////////
> int8_t wertSkalieren(int8_t value, int8_t offset)
> {
>   return value + offset;
> }

Hab sie aufn gemeinsamen nenner gebracht,
*value = *value+offset;
muss aber drinbleiben, ich bearbeite den Wert ja sonst nicht

hab zum test mal nen printf bei jedem case hintergehangen damit ich sehe 
das er die auch wirklich durchführt, das geht aufjedenfall.

von Ralf G. (ralg)


Lesenswert?

Martin Kathke schrieb:
> *value = *value+offset;
> muss aber drinbleiben, ich bearbeite den Wert ja sonst nicht

?????????????
Hier wird's 'bearbeitet':
1
      case 0b0001:  wertSkalieren( &encoderValue, -1 ); break;

Nur das Pointerzeug ist an der Stelle unnütz und unübersichtlich.
Deshalb:
1
      case 0b0001:  encoderValue = wertSkalieren( encoderValue, -1 ); break;
Jetzt sieht das wie eine 'richtige' Funktion aus! (Deine Variante 
könntest du übrigens gleich als 'void' deklarieren.)

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Ralf G. schrieb:
> Jetzt sieht das wie eine 'richtige' Funktion aus! (Deine Variante
> könntest du übrigens gleich als 'void' deklarieren.)

wobei man sich schon fragen sollte, für was man überhaupt noch die 
Funktion braucht.
1
case 0b0001:  encoderValue += -1 ); break;

von Martin K. (thereallife)


Lesenswert?

Peter II schrieb:
> Ralf G. schrieb:
>> Jetzt sieht das wie eine 'richtige' Funktion aus! (Deine Variante
>> könntest du übrigens gleich als 'void' deklarieren.)
>
> wobei man sich schon fragen sollte, für was man überhaupt noch die
> Funktion braucht.
> case 0b0001:  encoderValue += -1 ); break;

Die Funktion ist dafür gedacht, damit ich später den Wert mit einem 
minimum und maximum skalieren kann, ich wollte es jedoch erstmal zum 
laufen bekommen und mich danach um min und max kümmern.

von Ralf G. (ralg)


Lesenswert?

Peter II schrieb:
> wobei man sich schon fragen sollte, für was man überhaupt noch die
> Funktion braucht.

Naja, die Berechnung soll vielleicht mal später komplizierter werden...

Tante Edit hat's gesehen:
Martin Kathke schrieb:
> Die Funktion ist dafür gedacht, damit ich später den Wert mit einem
> minimum und maximum skalieren kann, ich wollte es jedoch erstmal zum
> laufen bekommen und mich danach um min und max kümmern.

: Bearbeitet durch User
von Martin K. (thereallife)


Lesenswert?

Ich habs mal ausprobiert, der Wert hat wieder entweder 0, 1 oder 255...
1
  switch (transition) {
2
      case 0b0001:  encoderValue += -1; printf("\n Case1\n"); break;
3
      case 0b0010:  encoderValue += +1; printf("\n Case2\n"); break;
4
      
5
      case 0b0100:  encoderValue += +1; printf("\n Case3\n"); break;
6
      case 0b0111:  encoderValue += -1; printf("\n Case4\n"); break;
7
      
8
      case 0b1000:  encoderValue += -1; printf("\n Case5\n"); break;
9
      case 0b1011:  encoderValue += +1; printf("\n Case6\n"); break;
10
      
11
      case 0b1101:  encoderValue += +1; printf("\n Case7\n"); break;
12
      case 0b1110:  encoderValue += -1; printf("\n Case8\n"); break;
13
    }

Scheint als würde der Fehler irgendwo anders liegen oder?


mal ein auszug aus meinen printf:

 Binärcode : 00000001
 Variable: 2
test encodder A =1
test encodder B =0

 Case2
1
 Binärcode : 00000000
 Variable: 0
test encodder A =0
test encodder B =0

 Case5
255
 Binärcode : 00000000
 Variable: 0
test encodder A =0
test encodder B =0

: Bearbeitet durch User
von Stefan E. (sternst)


Lesenswert?

1
void setup_Encoder()
2
{
3
...
4
  encoderValue = 0;
5
}
6
7
...
8
9
while(1)
10
  {
11
...
12
    setup_Encoder();
13
...
14
    read_Encoder();
15
    printf("%d", encoderValue);
16
  }

von Martin K. (thereallife)


Lesenswert?

das hat natürlich nix in der while schleife zu suchen...
Ich depp

danke euch :)

von Peter II (Gast)


Lesenswert?

Martin Kathke schrieb:
> das hat natürlich nix in der while schleife zu suchen...
> Ich depp
>
> danke euch :)

naja, das liegt aber auch daran das du alles als globale Variablen 
definiert hast.

Damit kann sie überall geändert werden.


uint8_t encoderState;
uint8_t oldEncoderState;


müssen auch nicht global sein, sie können static in der Funktion sein.

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.