64Bit Senden, funktioniert zwar, aber wie kann mans effizienter gestallten?

Gast #2534831
Lesenswert?

Hallo,

ich versuche mir gerade eine Uhr zu programmieren.

Im Augenblick steuer ich die LEDs für jede einzelne Sekunde über eine 
einzelne switch case Abfrage an.

kleines Beispiel:
1
switch (sekunden)
2
  {
3
  case 1:
4
  SPI_MasterTransmit(0x01);
5
  SPI_MasterTransmit(0x00);
6
  SPI_MasterTransmit(0x00);
7
  SPI_MasterTransmit(0x00);
8
  SPI_MasterTransmit(0x00);
9
  SPI_MasterTransmit(0x00);
10
  SPI_MasterTransmit(0x00);
11
  SPI_MasterTransmit(0x00);
12
    break;
13
  case 2:
14
  SPI_MasterTransmit(0x03);
15
  SPI_MasterTransmit(0x00);
16
  SPI_MasterTransmit(0x00);
17
  SPI_MasterTransmit(0x00);
18
  SPI_MasterTransmit(0x00);
19
  SPI_MasterTransmit(0x00);
20
  SPI_MasterTransmit(0x00);
21
  SPI_MasterTransmit(0x00);
22
    break;
23
  case 3:
24
  SPI_MasterTransmit(0x07);
25
  SPI_MasterTransmit(0x00);
26
  SPI_MasterTransmit(0x00);
27
  SPI_MasterTransmit(0x00);
28
  SPI_MasterTransmit(0x00);
29
  SPI_MasterTransmit(0x00);
30
  SPI_MasterTransmit(0x00);
31
  SPI_MasterTransmit(0x00);
32
    break;
33
  case 50:
34
  SPI_MasterTransmit(0xFF);
35
  SPI_MasterTransmit(0xFF);
36
  SPI_MasterTransmit(0xFF);
37
  SPI_MasterTransmit(0xFF);
38
  SPI_MasterTransmit(0xFF);
39
  SPI_MasterTransmit(0xFF);
40
  SPI_MasterTransmit(0x03);
41
  SPI_MasterTransmit(0x00);
42
    break;
43
  case 51:
44
  SPI_MasterTransmit(0xFF);
45
  SPI_MasterTransmit(0xFF);
46
  SPI_MasterTransmit(0xFF);
47
  SPI_MasterTransmit(0xFF);
48
  SPI_MasterTransmit(0xFF);
49
  SPI_MasterTransmit(0xFF);
50
  SPI_MasterTransmit(0x07);
51
  SPI_MasterTransmit(0x00);
52
    break;
53
  }

Danach kommt noch die Ansteuerung für eine kleine Anzeige, daher muss 
ich immer 8 Byte senden und die restlichen LEDs, die wegen der Anzahl 
der Sekunden nicht an sein dürfen, auf 0 setzen.

Das funktioniert wunderbar, ich stell mir allerdings schon seit einer 
halben Ewigkeit die Frage, wie ich die Sekunden direkt mit den Anzahl 
der zu sendenden Bits verrechnen kann.

Prinzipiell muss ich ja nur dafür sorgen, dass bei 50 Sekunden, 50 High 
Bits gesendet werden und 14 Low Bits.

Eine Idee die mir durch den Kopf geht, wäre mit (64 - sekunden) / 8 die 
Anzahl der Highbits zu berechnen und dann den Rest mit Lows aufzufüllen, 
aber ob das so ideal ist?


Viele Grüße aus München
Persönliche Seite #2534950
Lesenswert?

Du kannst doch direkt in einer Schleife ausgeben:
1
#include <stdint.h>
2

3
extern void SPI_MasterTransmit (uint8_t);
4

5
void send (uint8_t leds)
6
{
7
    for (uint8_t n = 0; n < 8; n++)
8
    {
9
        uint8_t val;
10
        
11
        if (leds >= 8)
12
        {
13
            val = 0;
14
            leds -= 8;
15
        }
16
        else
17
        {
18
            val = 1 << leds;
19
            leds = 0;
20
        }
21

22
        SPI_MasterTransmit (val-1);
23
    }
24
}
#2534980
Lesenswert?

> Prinzipiell muss ich ja nur dafür sorgen, dass bei 50 Sekunden,
> 50 High Bits gesendet werden und 14 Low Bits.
>
> Eine Idee die mir durch den Kopf geht, wäre mit (64 - sekunden) / 8
> die Anzahl der Highbits zu berechnen und dann den Rest mit Lows
> aufzufüllen, aber ob das so ideal ist?

Kannst du natürlich machen.

Im Allgemeinen ist doch der Ablauf so:

   sende eine entsprechende Anzahl an 0xFF für alle 8-er
   Gruppen die vollständig leuchten sollen. Diese Anzahl
   kann natürlich auch 0 sein.

   Danach kommt ein Byte bei dem 0 bis 7 LED leuchten sollen

   Und dann braucht es noch eine Anzahl 0x00 Bytes, um auf die
   insgesammt 8 zu sendenden Bytes zu kommen. Diese Anzahl kann
   natürlich auch 0 sein.

Wenn du also 20 LED einschalten musst, dann musst du

    2 Bytes   0xFF senden, dennn 2 * 8 sind 16 Bits denn 16
        ist die größte 8-er Zahl kleiner 20.

    Es bleiben 20 - 16 -> 4 Bits überig, für die du 1 Byte
        brauchst, in dem 4 Bits gesetzt sind  (das kann man
        zb sich aus einem Array holen, in die für jede Anzahl
        von Bits das entsprechende zu sendende Byte enthalten ist

    Bis jetzt hast du 2 + 1, also 3 Bytes ausgegeben, also musst du
    noch 5 Bytes mit lauter 0x00 nachschieben, damit in Summe wieder
    8 Bytes ausgegeben werden.


Das ganze ist einfach nur ein bischen (einfache) Rechnerei, 2 Schleifen, 
eine direkte Ausgabe und 1 Arrayzugriff.

1
void outSec( uint8_t sec )
2
{
3
  uint8_t nrFullBytes = sec / 8;
4
  uint8_t nrSingleBits = sec % 8;
5
  static uint8_t bitPattern[] = { 0x00, 0x01, 0x03, 0x03, 0x0F, 0x1F, 0x3F, 0x7F } ;
6

7
  for( uint8_t i = 0; i < nrFullBytes; i++ )
8
    SPI_MasterTransmit( 0xFF );
9

10
  SPI_MasterTransmit( bitPatterm[nrSingleBits] );
11

12
  for( uint8_t i = 0; i < 8 - 1 - nrFullBytes; i++ )
13
    SPI_MasterTransmit( 0x00 );
14
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren