www.mikrocontroller.net

Forum: Compiler & IDEs 32 Bit in Schieberegister Schieben


Autor: Peter F. (piet)
Datum:

Bewertung
0 lesenswert
nicht 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
#include <util/delay.h>
#include <avr/interrupt.h> 
#include "io.h"
#include "globals.h"
#include "uart.h"

// human readable output on 7 segment 
uint8_t numbermask[10] = { 0b10111101, 0b10000100, 0b00110111, 0b10100111, 0b10001110, 0b10101011, 0b10111011, 0b10000101, 0b10111111, 0b10101111 };

// bitcounter for shift register
uint8_t bitcounter = 0;

// shift register bitfield
volatile uint32_t shiftreg = 0b11111111111111111111111111111111;

// initialise IO port as output, set all pins to 0
void init_io(void) {
  IODDR = 0xFF;
  IOPORT = 0x00;
}

// clear the shift register
void clear_shiftreg(void) {
  
  // shift out 40 empty bits
  for ( bitcounter = 0; bitcounter <= 31; bitcounter++) {
      // output 0
      IOPORT &= ~(1<<SER);
      // generate memory clock
      IOPORT |= (1<<CLOCK);
      IOPORT &= ~(1<<CLOCK);
  }
  // generate latch clock
  IOPORT |= (1<<STORE);
  IOPORT &= ~(1<<STORE);
}


// fill the entire shift register with data
void fill_shiftreg(void) {
  
  // shift out 40 bits
  for ( bitcounter = 0; bitcounter <= 39; bitcounter++) {
      // output 1
      IOPORT |= (1<<SER);
      // generate memory clock
      IOPORT |= (1<<CLOCK);
      IOPORT &= ~(1<<CLOCK);
  }
  // generate latch clock
  IOPORT |= (1<<STORE);
  IOPORT &= ~(1<<STORE);
}


// update shift register 
void update_shiftreg(void) {
  
  // shift out entire shiftreg variable
  for ( bitcounter = 0; bitcounter <= 31; bitcounter++) {
    if ( shiftreg & (1 << bitcounter)) {
      // shift out 1      
      IOPORT |= (1<<SER);
      IOPORT |= (1<<CLOCK);
      IOPORT &= ~(1<<CLOCK);}
    else {
      // shift out 0
      IOPORT &= ~(1<<SER);
      IOPORT |= (1<<CLOCK);
      IOPORT &= ~(1<<CLOCK);}
  }

  // shift out id_own on 7 segment
  for ( bitcounter = 0; bitcounter <= 7; bitcounter++) {
    if ( numbermask[id_own] & (1 << bitcounter)) {
      // shift out 1      
      IOPORT |= (1<<SER);
      IOPORT |= (1<<CLOCK);
      IOPORT &= ~(1<<CLOCK);}
    else {
      // shift out 0
      IOPORT &= ~(1<<SER);
      IOPORT |= (1<<CLOCK);
      IOPORT &= ~(1<<CLOCK);}
  }

  // generate latch clock
  IOPORT |= (1<<STORE);
  IOPORT &= ~(1<<STORE);
  

}


Autor: Stefan Ernst (sternst)
Datum:

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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

mask =1;

...

numbermask[id_own] & mask)

...

mask <<=1;


MfG
Falk

Autor: Peter F. (piet)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
>
>     if ( shiftreg & (1 << bitcounter)) {
> 
> 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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.