Ich versuche, den SAM3x8E-Chip auf dem Arduino Due über Atmel Studio zu programmieren. Ich möchte mit dem SAM3-Chip einen digitalen Widerstand über die SPI-Schnittstelle steuern können. Ich verwende Atmel Studio 6.2. Ich habe KEIN PROBLEM, Dinge auf der Arduino IDE zum Laufen zu bringen, aber ich möchte wirklich herausfinden, wie man dies auf die "harte Weise" in Atmel programmiert. Ich kann den Chip erfolgreich in Atmel Studio programmieren, indem ich eine Batch-Datei verwende, die bosssa.exe lädt.
Hier ist mein ARBEITENDER Arduino IDE-Code:
Code:
// inslude the SPI library:
#include <SPI.h>
// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 13;
void setup() {
// initialize SPI:
SPI.begin();
SPI.setDataMode(SPI_MODE0);
// SPI.setClockDivider(slaveSelectPin, 8);
SPI.setBitOrder(LSBFIRST);
pinMode (slaveSelectPin, OUTPUT);
}
void loop() {
// Raise the volume from off to loud
// Increase brightness of LED
for (int i = 63; i>=0; i--) {
digitalPotWrite(i, i);
if(i>20)
delay(10);
else
delay(100);
}
digitalPotWrite(0, 0);
// delay(500);
// Decrease brightness of LED
for (int i = 0; i <= 63; i++) {
digitalPotWrite(i, i);
if(i>20)
delay(10);
else
delay(100);
}
}
void digitalPotWrite(int left, int right) {
// take the SS pin low to select the chip:
digitalWrite(slaveSelectPin, HIGH);
// send in the address and value via SPI:
SPI.transfer(left);
SPI.transfer(right);
// take the SS pin high to de-select the chip:
digitalWrite(slaveSelectPin, LOW);
}
Nun (leider) ist dies mein Atmel-Code:
Code:
#include <asf.h>
#include "spi_master.h"
int main (void)
{
/* Initialize the SAM system. */
sysclk_init();
board_init();
}
Wie Sie sehen können, habe ich nicht die geringste Ahnung, wie ich die SPI-Schnittstelle in Atmel Studio einrichten soll. Ich habe mir Beispielcode wie den eingebauten "SPI_EXAMPLE1" angesehen, aber ich verstehe ihn NICHT. Kann mir jemand helfen zu verstehen, wie Sie den SPI initialisieren? Woher weiß ich, welche Pins im Initialisierungscode verwendet werden sollen?
Sie haben hier zwei Möglichkeiten. Sie können die Konfigurationsregister direkt für das SPI-Peripheriegerät manuell festlegen oder das „Atmel Software Framework“ verwenden, das viele Details in einer übergeordneten API abstrahiert. In beiden Fällen müssen Sie sich um viele Dinge kümmern, die die Arduino-Umgebung für Sie erledigt.
Sie müssen die Uhr des Prozessors einrichten, was bedeutet, dass Sie eine Quelle auswählen (normalerweise haben Sie die Wahl zwischen einem internen Hochgeschwindigkeits-, einem internen Niedriggeschwindigkeits-, einem externen Hochfrequenz-Quarz, einem externen Niederfrequenz-Quarz oder einem externen Takt) und einer Kombination von Multiplikatoren /Teiler, die Ihre gewünschte Kerntaktfrequenz ableiten. Dann müssen Sie sicherstellen, dass das SPI-Peripheriegerät und die GPIO-Module ein Taktsignal empfangen (standardmäßig werden Taktsignale nicht an Peripheriegeräte geleitet, um Strom zu sparen) und dass das Taktsignal auf eine angemessene Geschwindigkeit heruntergeteilt wird (das MCU-Datenblatt wird Geben Sie das Min/Max-Timing sowie das Datenblatt Ihres externen ICs an, und Sie müssen sicherstellen, dass Sie die Anforderungen beider erfüllen).
Sie müssen die GPIO-Pins richtig konfigurieren, damit das SPI-Peripheriegerät sie steuern kann. Viele MCUs dieser Klasse verfügen über mehrere SPI-Einheiten, und das Datenblatt gibt an, welche Pins von welcher Einheit verwendet werden können. Die meisten Pins haben viele Peripheriegeräte, die ausgewählt werden können, also müssen Sie den Pin-Multiplexer einstellen, um die richtige SPI-Einheit auszuwählen. Sie müssen auch die Stiftrichtung und Pullups/Pulldowns nach Bedarf einstellen.
Schließlich müssen Sie das SPI-Peripheriegerät selbst konfigurieren. Dazu gehören die Einstellung der Taktgeschwindigkeit, die zu verwendenden Taktflanken, Master/Slave, Pin-Routing und viele andere Optionen, die im Datenblatt aufgeführt werden.
Wenn Sie gerade erst anfangen, dann ist ASF der richtige Weg. Es gibt Beispiele in der ASF-Dokumentation, die in früheren Kommentaren verlinkt sind, die Ihnen helfen sollten, und wenn Sie sie genau untersuchen, sollten Sie sehen, dass die Beispielanwendungen all die Dinge tun, die ich oben skizziert habe. Die ASF-Dokumentation erklärt jedoch außerordentlich schlecht, was vor sich geht und warum. Sie müssen also die Abschnitte des MCU-Datenblatts zu Takt, Energieverwaltung, GPIO und SPI sorgfältig studieren, um wirklich herauszufinden, was Sie tun . Leider erklärt das Datenblatt auch nur unzureichend, wie Peripheriegeräte verwendet werden sollen, sodass einiges zwischen den Zeilen gelesen werden muss. Als allgemeine Regel gilt, dass Hersteller-APIs und -Dokumentation für ARM-MCUs (nicht nur Atmels SAMs) nicht sehr gut sind. daher ist viel Lesen und Experimentieren erforderlich. Verwenden Sie die Funktion Rechtsklick -> "Zur Implementierung gehen" von Atmel Studio großzügig, um mehr darüber zu erfahren, was ASF unter der Haube tut. Ein Rückbezug auf die Datenblattbeschreibungen der Funktionen der verschiedenen Hardwareregister wird hilfreich sein.
Das alles ist also eine sehr allgemeine Antwort - Ihre spezifische Lösung hängt von der jeweiligen Hardwarekonfiguration ab, die Sie haben, also müssen Sie sich die Arduino Due-Schaltpläne ansehen, um herauszufinden, welche Pins Sie für SPI und verwenden müssen welche Uhreinstellungen angemessen sind. Die MCU wird standardmäßig von einem internen Oszillator gestartet, daher würde ich vorschlagen, dass Sie damit beginnen, nur den GPIO zum Laufen zu bringen – blinken Sie einfach eine LED, um sicherzustellen, dass Sie den GPIO im Griff haben, und beginnen Sie dann mit der Arbeit mit dem SPI-Modul .
Denken Sie vor allem daran, dass das Datenblatt Ihr Freund ist!
Obwohl erfahrene Entwickler sagen, dass Anfänger mit ASF gehen sollten (was tatsächlich stimmt), bedeutet das nicht, dass Sie mit weniger Aufwand dasselbe erreichen können. Sie brauchen nur eine andere Art von Anstrengung. (siehe: http://sam4dev.blogspot.co.at/2015/10/should-i-use-asf.html )
Wie auch immer, um die Frage zu beantworten: Ich habe SPI mit ASF im Master-Modus implementiert, SPI-Modus 0 auf SAM4S16C. Schauen Sie sich diesen Beitrag für Details an: http://sam4dev.blogspot.co.at/2015/10/spi-with-asf.html Ich stelle hier die wesentlichen Teile zur Verfügung.
Fügen Sie Ihrem Projekt mit ASF Wizard die folgenden Dienste/Treiber hinzu:
Initialisieren Sie in Ihrer init.c-Datei die Treiber und Dienste.
#include <asf.h>
#include <board.h>
#include <conf_board.h>
void board_init(void)
{
WDT->WDT_MR = WDT_MR_WDDIS; //switch off watchdog
sysclk_init();
ioport_init();
irq_initialize_vectors();
cpu_irq_enable();
//Set Led Pin directions
ioport_set_pin_dir(LED0_PIN,IOPORT_DIR_OUTPUT);
ioport_set_pin_dir(LED1_PIN,IOPORT_DIR_OUTPUT);
}
SPI-Init: Diese Init-Methode richtet SPI im Master-Modus ein, der SPI-Modus ist der SPI-Modus 0, die Taktrate liegt bei etwa 1 MHz.
#define SPI_ID ID_SPI
#define SPI_MASTER_BASE SPI
#define SPI_MISO_GPIO (PIO_PA12_IDX)
#define SPI_MISO_FLAGS (PIO_PERIPH_A | PIO_DEFAULT)
#define SPI_MOSI_GPIO (PIO_PA13_IDX)
#define SPI_MOSI_FLAGS (PIO_PERIPH_A | PIO_DEFAULT)
#define SPI_SPCK_GPIO (PIO_PA14_IDX)
#define SPI_SPCK_FLAGS (PIO_PERIPH_A | PIO_DEFAULT)
#define SPI_NPCS0_GPIO (PIO_PA11_IDX)
#define SPI_NPCS1_GPIO (PIO_PA31_IDX)
#define SPI_NPCS1_FLAGS (PIO_PERIPH_A | PIO_DEFAULT)
#define SPI_CHIP_SEL 1 //Use SPI Chip Select 1 (SPI_NPCS1_GPIO) for CS
#define SPI_CHIP_PCS spi_get_pcs(SPI_CHIP_SEL)
/* Clock polarity. */
#define SPI_CLK_POLARITY 0
/* Clock phase. */
#define SPI_CLK_PHASE 0
/* Delay before SPCK. */
//#define SPI_DLYBS 0x40
#define SPI_DLYBS 0xFF
/* Delay between consecutive transfers. */
#define SPI_DLYBCT 0x10
/* SPI clock setting (Hz). */
static uint32_t gs_ul_spi_clock = 1000000;
//Paramteres:
// data: data to be sent
// last_byte: either 0 or 1.
// 0-There are following bytes to be sent. The following bytes and the current byte composes one data-unit, CS should be kept low after sending out the current byte
// 1-Last byte of a data unit. CS will be set to HIGH when the current byte has been sent out.
void spi_tx(uint8_t data,uint8_t last_byte)
{
spi_write(SPI,data,SPI_CHIP_SEL,last_byte);
while ((spi_read_status(SPI) & SPI_SR_RDRF) == 0);/* Wait transfer done. */
}
uint8_t spi_rx(void)
{
uint8_t tmp;
spi_read (SPI,&tmp,SPI_CHIP_SEL);
return tmp;
}
void spi_init(void)
{
//Assign I/O lines to peripheral
gpio_configure_pin(SPI_MISO_GPIO, SPI_MISO_FLAGS);
gpio_configure_pin(SPI_MOSI_GPIO, SPI_MOSI_FLAGS);
gpio_configure_pin(SPI_SPCK_GPIO, SPI_SPCK_FLAGS);
gpio_configure_pin(SPI_NPCS1_GPIO, SPI_NPCS1_FLAGS);
spi_enable_clock(SPI_MASTER_BASE);
spi_disable(SPI_MASTER_BASE);
spi_reset(SPI_MASTER_BASE);
spi_set_lastxfer(SPI_MASTER_BASE);
spi_set_master_mode(SPI_MASTER_BASE);
spi_disable_mode_fault_detect(SPI_MASTER_BASE);
spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_PCS);
spi_configure_cs_behavior(SPI, 1, SPI_CS_RISE_NO_TX);
spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
spi_set_bits_per_transfer(SPI_MASTER_BASE, SPI_CHIP_SEL,
SPI_CSR_BITS_8_BIT);
spi_set_baudrate_div(SPI_MASTER_BASE, SPI_CHIP_SEL,(sysclk_get_cpu_hz() / gs_ul_spi_clock));
spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS,SPI_DLYBCT);
spi_enable(SPI_MASTER_BASE);
}
KyranF
KyranF
KyranF
KyranF