32 Bit in Schieberegister Schieben

OP #1331492
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
}
#1331520
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
OP #1332650
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.