www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Hat jemand für den ATtiny44 eine funktionierende USI to SPI Routine?


Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ich einen Funkchip über SPI ansteuern muss und mein ATtiny44 nur USI 
kann, wäre ich über eine Routine in C oder entsprechende Hinweise sehr 
dankbar.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Datenblatt S.120. Sollte recht einfach nach C zu übersetzen sein.

MfG Spess

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niemand zwingt Dich, das USI zu nehmen.
Nimm ne ganz einfache SW-SPI und gut is.


Peter

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, aber hab ich noch nie gemacht.
Hast du ein gutes Beispiel?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>OK, aber hab ich noch nie gemacht.
>Hast du ein gutes Beispiel?

Das ist auf dem Niveau: 2 LEDs blinken lassen. Wenn es schon daran 
hapert, wie willst du dann einen 'Funkchip' ansteuern?

MfG Spess

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi

> Das ist auf dem Niveau: 2 LEDs blinken lassen. Wenn es schon daran
> hapert, wie willst du dann einen 'Funkchip' ansteuern?

Was ist falsch daran, nach einem Beispiel zu fragen, wenn ich das noch 
nie gemacht habe? Und der Funkchip der funktioniert bereits, aber eben 
über die SPI.

Autor: Floh (Gast)
Datum:

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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Die Realisierung in Code überlass ich dir.
>:-)

Das ist aber nicht Copy&Paste-Fähig.

MfG Spess

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Das ist aber nicht Copy&Paste-Fähig.

Dafür müsste er ja auch seine Programmiersprache angeben ^^

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Dafür müsste er ja auch seine Programmiersprache angeben ^^

Hat er doch:

>...wäre ich über eine Routine in C oder entsprechende Hinweise sehr
>dankbar.

MfG Spess

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr\io.h>


struct bits {
  uint8_t b0:1;
  uint8_t b1:1;
  uint8_t b2:1;
  uint8_t b3:1;
  uint8_t b4:1;
  uint8_t b5:1;
  uint8_t b6:1;
  uint8_t b7:1;
} __attribute__((__packed__));

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


#define SPI_CLK         SBIT( PORTB, 0 )        // clock
#define SPI_CLK_DDR     SBIT( DDRB,  0 )
#define SPI_MISO_PIN    SBIT( PINB,  2 )
#define HC165_LD        SBIT( PORTB, 3 )
#define HC165_LD_DDR    SBIT( DDRB,  3 )
#define SPI_MOSI        SBIT( PORTB, 1 )


uint8_t spi_io( uint8_t val )
{
  uint8_t i;

  for( i = 8; i; i-- ){
    SPI_MOSI = 0;
    if( val & 0x80 )
      SPI_MOSI = 1;
    val <<= 1;
    if( SPI_MISO_PIN )
      val += 1;
    SPI_CLK = 0;
    SPI_CLK = 1;
  }
  return val;
}


Peter

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> if( SPI_MISO_PIN )
>       val += 1;

sollte man das Einlesen nicht während der Clockperiode machen?
:-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Floh schrieb:
> sollte man das Einlesen nicht während der Clockperiode machen?
> :-)

Man sollte es so machen, wie es im Datenblatt des zu kontrollierenden 
Chips steht (den wir aber nicht kennen).

Mein Bespiel liest einen 74HC165 ein.


Peter

Autor: H. G. (ledi)
Datum:

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

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

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

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

    while (!(USISR & (1<<USIOIF)))  //solange kein Timerüberlauf...
    {
      USICR  |=  (1<<USITC);    //Toggle clk
      USICR  |=  (1<<USITC);
    }
    PORTB  |=  (1<<PB1);    //CS = 1
}

int main (void)
{
  SPI_init();
  sei();
  while(1)
  {
    SPI_transfer(0xAF);
    PORTA |= (1<<PA7);  // Led on
    _delay_ms(1000);
    PORTA &= !(1<<PA7);  // Led off
    _delay_ms(1000);
  }
}

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert schon! :-)

Der "Fehler" war bei der Initialisierung des Input-Pins (PA6):

DDRA  &=  !(1<<PA6);

habe ich auf
DDRA  &=  ~(1<<PA6);
ausgebessert.

Warum nimmt das AVR-Studio das ! als Negation hier nicht an?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heimo G. schrieb:

> Warum nimmt das AVR-Studio das ! als Negation hier nicht an?

1) weil das eine C-Sache ist
2) weil ! die logische Negierung ist und nicht die bitweise

   Am Beispiel von 5 (0b00000101)
   !5     ergibt 0, weil 5 nicht 0 ist ( 5 ist logisch TRUE und
          dessen Negierung ist logisch FALSE)
   ~5     ergibt 0b11111010, weil jedes Bit umgedreht wird

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.