Forum: Compiler & IDEs 32 Bit in Schieberegister Schieben


von Peter F. (piet)


Lesenswert?

Hallo!

Ich möchte gerade einen 32 Bit Wert in ein Schieberegister schieben, das 
klappt jedoch nicht.
Die ersten 16 Bit werden korrekt übertragen, danach kommen nurnoch 
Nullen.
Wenn ich aber zwei mal 16 Bit hintereinander schiebe geht es.
Woran könnte es liegen?

Das ganze register besteht aus 5 74HCT595, in das erste (was zuletzt 
geschoben wird) kommen die Daten für ein 7 Segment Display. In die 
nächsten 4 sollen dann die 32 Bit.

Die Funktion mit dem Problem ist update_shiftreg(), fill_shiftreg() und 
clear_shiftreg() funktionieren.
Auf dem Sieben Segment wird immer alles korrekt angezeigt, und im ganzen 
Register auch wenn ich zwei 16Bit nacheinander schieb statt einmal 32 
Bit.

AVR Studio 4.14 Build 589
WinAVR-20080610
Mega32

Mfg,
Peter
1
#include <util/delay.h>
2
#include <avr/interrupt.h> 
3
#include "io.h"
4
#include "globals.h"
5
#include "uart.h"
6
7
// human readable output on 7 segment 
8
uint8_t numbermask[10] = { 0b10111101, 0b10000100, 0b00110111, 0b10100111, 0b10001110, 0b10101011, 0b10111011, 0b10000101, 0b10111111, 0b10101111 };
9
10
// bitcounter for shift register
11
uint8_t bitcounter = 0;
12
13
// shift register bitfield
14
volatile uint32_t shiftreg = 0b11111111111111111111111111111111;
15
16
// initialise IO port as output, set all pins to 0
17
void init_io(void) {
18
  IODDR = 0xFF;
19
  IOPORT = 0x00;
20
}
21
22
// clear the shift register
23
void clear_shiftreg(void) {
24
  
25
  // shift out 40 empty bits
26
  for ( bitcounter = 0; bitcounter <= 31; bitcounter++) {
27
      // output 0
28
      IOPORT &= ~(1<<SER);
29
      // generate memory clock
30
      IOPORT |= (1<<CLOCK);
31
      IOPORT &= ~(1<<CLOCK);
32
  }
33
  // generate latch clock
34
  IOPORT |= (1<<STORE);
35
  IOPORT &= ~(1<<STORE);
36
}
37
38
39
// fill the entire shift register with data
40
void fill_shiftreg(void) {
41
  
42
  // shift out 40 bits
43
  for ( bitcounter = 0; bitcounter <= 39; bitcounter++) {
44
      // output 1
45
      IOPORT |= (1<<SER);
46
      // generate memory clock
47
      IOPORT |= (1<<CLOCK);
48
      IOPORT &= ~(1<<CLOCK);
49
  }
50
  // generate latch clock
51
  IOPORT |= (1<<STORE);
52
  IOPORT &= ~(1<<STORE);
53
}
54
55
56
// update shift register 
57
void update_shiftreg(void) {
58
  
59
  // shift out entire shiftreg variable
60
  for ( bitcounter = 0; bitcounter <= 31; bitcounter++) {
61
    if ( shiftreg & (1 << bitcounter)) {
62
      // shift out 1      
63
      IOPORT |= (1<<SER);
64
      IOPORT |= (1<<CLOCK);
65
      IOPORT &= ~(1<<CLOCK);}
66
    else {
67
      // shift out 0
68
      IOPORT &= ~(1<<SER);
69
      IOPORT |= (1<<CLOCK);
70
      IOPORT &= ~(1<<CLOCK);}
71
  }
72
73
  // shift out id_own on 7 segment
74
  for ( bitcounter = 0; bitcounter <= 7; bitcounter++) {
75
    if ( numbermask[id_own] & (1 << bitcounter)) {
76
      // shift out 1      
77
      IOPORT |= (1<<SER);
78
      IOPORT |= (1<<CLOCK);
79
      IOPORT &= ~(1<<CLOCK);}
80
    else {
81
      // shift out 0
82
      IOPORT &= ~(1<<SER);
83
      IOPORT |= (1<<CLOCK);
84
      IOPORT &= ~(1<<CLOCK);}
85
  }
86
87
  // generate latch clock
88
  IOPORT |= (1<<STORE);
89
  IOPORT &= ~(1<<STORE);
90
  
91
92
}

von Stefan E. (sternst)


Lesenswert?

1
    if ( shiftreg & (1 << bitcounter)) {
Die "1" ist nur 16 Bit groß, also funktioniert das so nicht.
Ändere es in "(1UL << bitcounter)".

von Falk B. (falk)


Lesenswert?

1
numbermask[id_own] & (1 << bitcounter)

Sowas ist auf kleinen uC wie dem AVR ungünstig, weil das ewig dauert. 
Besser ist die Verwenung einer zweiten Variable, die man dann immer um 1 
schiebt.
1
mask =1;
2
3
...
4
5
numbermask[id_own] & mask)
6
7
...
8
9
mask <<=1;

MfG
Falk

von Peter F. (piet)


Lesenswert?

Stefan Ernst schrieb:
>
1
>     if ( shiftreg & (1 << bitcounter)) {
2
>
> Die "1" ist nur 16 Bit groß, also funktioniert das so nicht.
> Ändere es in "(1UL << bitcounter)".

Ah, das wars, vielen Dank!
Hätte ich ja eigentlich selber drauf kommen müssen... ;^^

Mfg,
Peter

von Simon K. (simon) Benutzerseite


Lesenswert?

@Falk:
Ja, prinzipiell hast du ja Recht. Es ist auch immer das Gleiche wenn es 
um sowas geht, aber "ewig" langsam ist jetzt etwas übertrieben ;)

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.