Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Rasenmaehroboter fuer schwierige und grosse Gaerten im Test

Baustelle.gif An diesem Artikel arbeitet gerade Mitglied SprinterSB.

Am besten momentan noch keine gravierenden Ergänzungen / Änderungen vornehmen.

Dieser Hinweis verschwindet wenn der Autor soweit ist. Sollte dieser Hinweis länger als drei Tage auf einer Seite sein, bitte beim Autor SprinterSB per PM / Mail oder Forum nachfragen ob er vergessen wurde.

Vorteile
  • schnell
  • preiswert
  • einfach anzusteuern (auch ohne Hardware-Unterstützung)
  • modular aufgebaut und erweiterbar
  • alle Ports können gleichzeitig geschaltet werden, auch 100 Stück
  • SPI-Interface und ISP-Pins können verwendet werden
  • Bus hat nur 3 Leitungen, dadurch kein kompliziertes Layout mit vielen Leitungen
Nachteile
  • bei dieser Version nur Ausgabe möglich

Schaltplan

Portexpander 74595 an AVR.png

C-Code

Der folgende C-Code ist Pseudocode, was Setzen der Ports angeht. Die entsprechenden Befehle sind durch die richtigen C-Befehle für diese Ports zu ersetzen.

MAKE_OUT (X)
Schaltet X als Ausgang (DDR-Register)
SET (X)
Setzt Ausgang X auf HIGH (PORT-Register)
CLR (X)
Setzt Ausgang X auf LOW (PORT-Register)

Makros,Datenstrukturen,Funktionen

#define SERPA_SIZE
Define für Anzahl der auszugebenden Bytes
extern unsigned char serpa[SERPA_SIZE]
Das Array, dessen Bytes ausgegeben werden. serpa[0] landet in dem Portexpander-IC, das direkt am Controller sitzt. Bit0 erscheint jeweils an Ausgang QA, Bit7 erscheint am Ausgang QH, etc.
void serpa_init()
Initialisiert die Schnittstelle bzw. die verwendeten Ports
void serpa_out()
Gibt die SERPA_SIZE Bytes aus dem Array serpa aus.

serpa.h

/* SERiell nach PArallel (serpa) im SPI-Protokoll */
#ifndef _SERPA_H_
#define _SERPA_H_

/* 4 Bytes (32 Ports) */
#define SERPA_SIZE 4

extern unsigned char serpa[];
extern void serpa_out();
extern void serpa_init();

#endif /* _SERPA_H_ */

Mit SPI-Hardware

serpa.c

/* SERiell nach PArallel (serpa) mit Hardware-Unterstützung */
#include <avr/io.h>
#include "serpa.h"

// Array für die Daten
unsigned char serpa[SERPA_SIZE];

void serpa_init()
{
   MAKE_OUT (PORT_MOSI); 
   MAKE_OUT (PORT_SCK);
   MAKE_OUT (PORT_RCK); SET (PORT_RCK);

   // !!! SS muss OUT sein, damit SPI nicht in Slave-Mode wechselt !!!
   // entfällt, falls PORT_RCK = PORT_SS  
   MAKE_OUT (PORT_SS);

   // SPI als Master
   // High-Bits zuerst
   // SCK ist HIGH wenn inaktiv
   SPCR = _BV(SPE) | _BV(MSTR) | _BV(CPOL);
	
   // pullup an MISO vermeidet Floaten
   SET (PORT_MISO);

   // maximale Geschwindigkeit: F_CPU / 2	 
   SPSR |= _BV(SPI2X);
}

void serpa_out ()
{
   unsigned char anz = SERPA_SIZE;
   unsigned char* serp = serpa+SERPA_SIZE;

   do
   {
      unsigned char data = *--serp;

      // SPDR schreiben startet Übertragung
      SPDR = data;

      // warten auf Ende der Übertragung für dieses Byte
      while (!(SPSR & (1 << SPIF)));

      // clear SPIF	
      data = SPDR;
   }
   while (--anz > 0);

    // Strobe an RCK bringt die Daten von den Schieberegistern in die Latches
   CLR (PORT_RCK);
   SET (PORT_RCK);
}

Ohne SPI-Hardware

serpa.c

/* SERiell nach PArallel (serpa) via Software */
#include "serpa.h"

// Array für die Daten
unsigned char serpa[SERPA_SIZE];

void serpa_init ()
{
    // Verwendete Ports auf OUT
    MAKE_OUT (PORT_SER);
    MAKE_OUT (PORT_SCK);
    MAKE_OUT (PORT_RCK);

    // SCR und RCK auf definierten Level HIGH
    SET (PORT_SCK);
    SET (PORT_RCK);
}

void serpa_out ()
{
    unsigned char anz = SERPA_SIZE;
    unsigned char* serp = serpa+SERPA_SIZE;

    do
    {
        unsigned char bits;
        unsigned char data = *--serp;

        // 8 Bits pro Byte rausschieben
        for (bits = 8; bits > 0; bits--)
        {
            CLR (PORT_SER);
            if (data & 0x80)
            {
                SET (PORT_SER);
            }

            data <<= 1;
            // Strobe an SCK schiebt Daten im Gänsemarsch 
            // um 1 Position weiter durch alle Schieberegister
            CLR (PORT_SCK);
            SET (PORT_SCK);
        }
    }
    while (--anz > 0);

    // Strobe an RCK bringt die Daten von den Schieberegistern in die Latches
    CLR (PORT_RCK);
    SET (PORT_RCK);
}

LiFePO4 Speicher Test