FCK Prescaler spi_init() sinnvoll mitteilen

OP #4298136
Lesenswert?
• ▲
▼
Hallo,

ich hätte mal eine kurze Frage, wie man sowas am besten lösen kann.

Ich übergebe der derzeitigen spi_init() meines Attiny841 ein mit, wie 
schnell dir Frequenz sein soll.
1
void spi_init(uint8_t prescaler)
2
{
3
  DDRA |= (1<<DDRA7) | (1<<DDRA6) | (1<<DDRA4);
4
  SPCR = (1<<SPE) | (1<<MSTR);
5
  SPSR &= ~(1<<SPI2X);
6
  
7
  switch(prescaler)
8
  {
9
    case 4:    return;
10
    case 16:  SPCR |= (1<<SPR0); break;
11
    case 64:  SPCR |= (1<<SPR1); break;
12
    case 128:  SPCR |= (1<<SPR1) | (1<<SPR0); break;
13
    case 2:    SPSR |= (1<<SPI2X); break;
14
    case 8:    SPSR |= (1<<SPI2X); SPCR |= (1<<SPR0); break;
15
    case 32:  SPSR |= (1<<SPI2X); SPCR |= (1<<SPR1); break;
16
    //case 64:  SPSR |= (1<<SPI2X); SPCR |= (1<<SPR1) | (1<<SPR0); break;
17
    default:  return;
18
  }
19
}
20

21

22

23

24
// ODER
25

26

27
#define SPI_FCK      128
28
#define SPI_USE_SPI2X
29
void spi_init(void)
30
{
31
  DDRA |= (1<<DDRA7) | (1<<DDRA6) | (1<<DDRA4);
32
  SPCR = (1<<SPE) | (1<<MSTR);
33
  
34
  #if (SPI_FCK == 16)
35
  SPCR |= (1<<SPR0);
36
  #elif (SPI_FCK == 64)
37
  SPCR |= (1<<SPR1);
38
  #elif (SPI_FCK == 128)
39
  SPCR |= (1<<SPR1) | (1<<SPR0);
40
  /*
41
  #else // SPI_FCK == 4 || SPI_FCK fehlerhaft
42
  */
43
  #endif
44
  
45
  #ifdef SPI_USE_SPI2X
46
  SPSR |= (1<<SPI2X);
47
  #endif
48
}

Das ganze produziert im Vergleich zur direkten Zuweisung natürlich 
deutlich mehr Programmspeicher. Gibt es da ansonsten Ansätze, dass noch 
kürzer zu lösen?
Gast #4298158
Lesenswert?
• ▲
▼
Stefan S. schrieb:
> as ganze produziert im Vergleich zur direkten Zuweisung natürlich
> deutlich mehr Programmspeicher.

Du vergleichst Äpfel mit Birnen. Das eine ist eine Konfiguration
"at runtime" die dort Änderungen zulässt, das andere eine
festverdrahtete unflexible Vorprogrammierung.
OP #4298166
Lesenswert?
• ▲
▼
Also mir geht es nicht darum, den Clock während des Betriebes zu ändern. 
Diesen setze ich einmal im Programm fix fest für das langsamste SPI 
Gerät.

Deshalb brauche ich die obere Lösung nicht.

Das mit der F_CPU mit reinzunehmen wäre nicht einmal eine schlechte 
Idee.

#define FCK  1000000UL // Gibt den Takt des langsamen Geraetes an
#4298174
Lesenswert?
• ▲
▼
1
#define SPI_FCK      128
2

3
void spi_init(void)
4
{
5
...
6
 switch(SPI_FCK)
7
 {
8
  case 2:... break;
9
  case 4:... break;
10
  ...
11
  case 128:... break;
12
 }
13
...

Jetzt werden nur die Anweisungen hinter "case 128" ins Programm 
eingebaut, da der Rest nie erreicht und vom Compiler wegoptimiert wird.


mfg.
OP #4298181
Lesenswert?
• ▲
▼
Danke!

Ich hatte jetzt sowas mal mit der F_CPU Berechnung angestellt.
1
  
2
  #define SPI_FCK    10UL
3
  #define PRESCALER  (F_CPU/SPI_FCK)
4
  #if    (PRESCALER > 64)
5
  #warning "SPI Speed not supported"
6
  #elif    (PRESCALER >= 64)
7
  SPCR |= (1<<SPR1);
8
  #elif  (PRESCALER < 32)
9
  SPCR |= (1<<SPR1);
10
  SPSR |= (1<<SPI2X);
11
  #elif  (PRESCALER < 16)
12
  SPCR |= (1<<SPR0);
13
  #elif  (PRESCALER < 8)
14
  SPCR |= (1<<SPR0);
15
  SPSR |= (1<<SPI2X);
16
  #elif  (PRESCALER < 4)
17
  #elif  (PRESCALER < 2)
18
  SPSR |= (1<<SPI2X);
19
  #endif

Nur schnell zusammengeschrieben, muss nicht funktionsfähig sein, es 
können auch Fehler beim Abschreiben aus dem DB entstanden sein.
#4298187
Lesenswert?
• ▲
▼
Stefan S. schrieb:
> #elif    (PRESCALER >= 64)
>   SPCR |= (1<<SPR1);
>   #elif  (PRESCALER < 32)
>   SPCR |= (1<<SPR1);
>   SPSR |= (1<<SPI2X);
>   #elif  (PRESCALER < 16)
>   SPCR |= (1<<SPR0);
>   #elif  (PRESCALER < 8)
>   SPCR |= (1<<SPR0);
>   SPSR |= (1<<SPI2X);
>   #elif  (PRESCALER < 4)
>   #elif  (PRESCALER < 2)
>   SPSR |= (1<<SPI2X);

so funktioniert das nicht.

Wenn PRESCALER <2, 4, 8, 16 oder 32 ist, ist es auch <=64. Somit ist 
immer die erste Bedingung erfüllt.
Also den kleinsten Wert zuerst prüfen.

mfg.

Antwort schreiben

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.

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.