Hat jemand für den ATtiny44 eine funktionierende USI to SPI Routine?

Gast #1938471
Lesenswert?

Heimo G. schrieb:
> Hast du ein gutes Beispiel?

Nur senden:

Zähler = 8

Schleife:
  Mosi = oberstes Bit im Datenbyte
  Sck = high
  kurz warten
  Sck = low
  Datenbyte einmal links schieben
  Zähler dekrementieren,
wenn Zähler != 0, wieder die Schleife

Die Realisierung in Code überlass ich dir.
:-)
#1938489
Lesenswert?

1
#include <avr\io.h>
2

3

4
struct bits {
5
  uint8_t b0:1;
6
  uint8_t b1:1;
7
  uint8_t b2:1;
8
  uint8_t b3:1;
9
  uint8_t b4:1;
10
  uint8_t b5:1;
11
  uint8_t b6:1;
12
  uint8_t b7:1;
13
} __attribute__((__packed__));
14

15
#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
16

17

18
#define SPI_CLK         SBIT( PORTB, 0 )        // clock
19
#define SPI_CLK_DDR     SBIT( DDRB,  0 )
20
#define SPI_MISO_PIN    SBIT( PINB,  2 )
21
#define HC165_LD        SBIT( PORTB, 3 )
22
#define HC165_LD_DDR    SBIT( DDRB,  3 )
23
#define SPI_MOSI        SBIT( PORTB, 1 )
24

25

26
uint8_t spi_io( uint8_t val )
27
{
28
  uint8_t i;
29

30
  for( i = 8; i; i-- ){
31
    SPI_MOSI = 0;
32
    if( val & 0x80 )
33
      SPI_MOSI = 1;
34
    val <<= 1;
35
    if( SPI_MISO_PIN )
36
      val += 1;
37
    SPI_CLK = 0;
38
    SPI_CLK = 1;
39
  }
40
  return val;
41
}


Peter
OP #1939010
Lesenswert?

Hallo Peter!

Ich habe nun doch eine USI-SPI Routine geschrieben.

Soweit ich das überprüfen konnte, sollte es funktionieren.
Leider kann ich aber am DO (Pin PA5) kein Signal messen.

Was ist falsch?


Hier der Code:
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5

6
void SPI_init(void)
7
{
8
  DDRA  |=  (1<<PA4)|(1<<PA5);   //Output:   PA4=USCK, PA5=DO
9
  DDRB  |=  (1<<PB1);      //Output:   PB1=CS
10
  DDRA  &=  !(1<<PA6);      //Input:   PA6=DI
11
  PORTA  |=  (1<<PA6);      //int. Pull-up an PA6 aktivieren
12
  DDRA   |=   (1<<PA7);      //LED auf Ausgang
13

14
  USICR   =   (1<<USIWM0) | (1<<USICLK)| (1<<USITC)| (1<<USICS1);
15
}
16

17
void SPI_transfer(int data)
18
{
19
    PORTB  &=  !(1<<PB1);    //CS = 0
20
    USIDR = data;        //Daten in Data Register laden
21
    USISR   |=  (1<<USIOIF);  //Überlaufflag löschen  
22

23
    while (!(USISR & (1<<USIOIF)))  //solange kein Timerüberlauf...
24
    {
25
      USICR  |=  (1<<USITC);    //Toggle clk
26
      USICR  |=  (1<<USITC);
27
    }
28
    PORTB  |=  (1<<PB1);    //CS = 1
29
}
30

31
int main (void)
32
{
33
  SPI_init();
34
  sei();
35
  while(1)
36
  {
37
    SPI_transfer(0xAF);
38
    PORTA |= (1<<PA7);  // Led on
39
    _delay_ms(1000);
40
    PORTA &= !(1<<PA7);  // Led off
41
    _delay_ms(1000);
42
  }
43
}

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