PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anbindung eines ADNS-3080 per SPI an STM32F401C-DISCO



Manekken
13.05.2016, 08:57
Hallo liebe Roboternetz Gemeinde.
Und zwar bin ich momentan dabei einen ADNS-3080 Maussensor an mein
STM32F401C-DISCO Board anzubinden. Und zwar über SPI.

Über folgenden Link kann man das Datenblatt des Sensors finden:
https://people.ece.cornell.edu/land/courses/ece476...

Die Spannungsversorgung funktioniert zuverlässig. Wurde alles per
Multimeter ausgemessen. An allen relevanten Pins habe ich 3.3V gemessen.

Verbunden habe ich alles folgendermaßen:
PA13 - RESET (zum resetten des Sensors)
PA15 - NCS
PA5 - SCLK (SPI1)
PA6 - MISO (SPI1)
PA7 - MOSI (SPI1)

Ich habe die Verbindungskabel direkt am Sensor verlötet. Die andere
Seite habe ich mich Steckern versehen und auf der Board gesteckt. Was
ich aus dem Datenblatt herauslesen konnte ist folgendes:
Zuerst muss die Spannungsversorgung auf 3.3V sichergestellt werden. Dann
muss der RESET Pin von low auf high gezogen werden und dann wieder auf
low. Allerdings passiert nach diesem Vorgang absolut nichts. Eigentlich
muss dann die LED_CRTL eine Spannung aufweisen. Was mir aufgefallen ist:
Entferne ich die Verbindung zum RESET Pin, kann ich den PA13 auf low
(0V) und high (~3V) ziehen. Der Code funktioniert also. Ist nun die
Verbindung vorhanden lande ich bei low auf ca. 1.38V und bei high wieder
auf ca. 3V. Ich verstehe nicht wo diese Spannung herkommt wo ich doch
PA13 auf low gezogen habe.
Vielleicht hat ja jemand Erfahrung mit diesem Sensor oder vielleicht hab
ich auch im Datenblatt etwas wichtiges nicht kapiert. Ich würde mich
dementsprechend über Hilfe wirklich freuen!

So jetzt noch mein bisheriger Code:




#include "stdint.h"
#include "inttypes.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_spi.h"
#include "spiFunctions.h"


void Delay(volatile uint32_t nCount)
{
while(nCount--)
{
}
}
void initSPI(void) {
SPI_InitTypeDef SPI_InitTypeDefStruct;

SPI_InitTypeDefStruct.SPI_BaudRatePrescaler=SPI_Ba udRatePrescaler_2;
SPI_InitTypeDefStruct.SPI_Direction=SPI_Direction_ 2Lines_FullDuplex;
SPI_InitTypeDefStruct.SPI_Mode=SPI_Mode_Master;
SPI_InitTypeDefStruct.SPI_DataSize=SPI_DataSize_8b ;
SPI_InitTypeDefStruct.SPI_NSS=SPI_NSS_Soft;
SPI_InitTypeDefStruct.SPI_FirstBit=SPI_FirstBit_MS B;
SPI_InitTypeDefStruct.SPI_CPOL=SPI_CPOL_High;
SPI_InitTypeDefStruct.SPI_CPHA=SPI_CPHA_2Edge;

SPI_Init(SPI1, &SPI_InitTypeDefStruct);

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;

GPIO_Init(GPIOA, &GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_15;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;

GPIO_Init(GPIOA, &GPIO_InitStruct);



GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);

SPI_Cmd(SPI1, ENABLE);
}

void initReset(void) {

GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;

GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void init1(void) {
GPIO_InitTypeDef GPIO_InitStructure;

// Clock Enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

// Config PD12 als Digital-Ausgang
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void init2(void) {
GPIO_InitTypeDef GPIO_InitStructure;

// Clock Enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

// Config PD14 als Digital-Ausgang
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}



int main(void)
{
init1();
init2();
initSPI();
initReset();

Delay(500000);
GPIO_SetBits(GPIOA,GPIO_Pin_13); //Soll den RESET starten
Delay(500000);
GPIO_ResetBits(GPIOA,GPIO_Pin_13); //Soll den RESET beenden

while(1) { //hier nur zum testen lasse ich eine LED blinken
Delay(900000);
GPIOD->ODR ^= GPIO_Pin_12; // PD12 toggeln
}
}



Also wie gesagt. Danke schonmal wer bis hier gelesen hat!

Grüße,
Manekken.

Unregistriert
14.05.2016, 08:57
Verbunden habe ich alles folgendermaßen:
PA13 - RESET (zum resetten des Sensors)
PA15 - NCS
PA5 - SCLK (SPI1)
PA6 - MISO (SPI1)
PA7 - MOSI (SPI1)



Die Pins PA13-PA15 sind bei Power-On auf JTAG konfiguriert.
Hast Du das in der Software deaktiviert? Scheint mir nicht so.
Check das mal und benutze andere Pins. Zur Software kann ich nichts sagen, ich benutze diese üblen ST-Bibliotheken nicht und programmiere die Register direkt. Das macht viel weniger Probleme und man versteht, was passiert...

Manekken
14.05.2016, 19:52
Hi, danke schonmal für die Antwort!
Aber die Pins haben doch folgende alternate functions:
PA13 - JTMS-SWDIO
PA14 - JTCK-SWCLK, I2S3ext_WS
PA15 - JTDI, TIM2_CH1/TIM2_ETR, SPI1_NSS, SPI3_NSS/I2S3_WS

Von JTAG find ich da nix. Außerdem sind die doch alle bei start auf Main function oder?
Kapier das net ganz.

Grüße,
Manekken

Unregistriert
15.05.2016, 10:25
Hi, danke schonmal für die Antwort!
Aber die Pins haben doch folgende alternate functions:
PA13 - JTMS-SWDIO
PA14 - JTCK-SWCLK, I2S3ext_WS
PA15 - JTDI, TIM2_CH1/TIM2_ETR, SPI1_NSS, SPI3_NSS/I2S3_WS

Von JTAG find ich da nix. Außerdem sind die doch alle bei start auf Main function oder?
Kapier das net ganz.

Grüße,
Manekken


JTMS, JTCK, JTDI sind JTAG-Signale.

Und - auch wenn es nervt, das immer wieder schreiben zu müssen - RTFM.
Auf Seite 148 des Reference Manuals steht doch alles ( http://www2.st.com/content/ccc/resource/technical/document/reference_manual/5d/b1/ef/b2/a1/66/40/80/DM00096844.pdf/files/DM00096844.pdf/jcr:content/translations/en.DM00096844.pdf ):

- After reset all I/Os are connected to the system’s alternate function 0 (AF0)
- JTAG/SWD, after each device reset these pins are assigned as dedicated pins immediately usable by the debugger host (not controlled by the GPIO controller)
- Note: You can disable some or all of the JTAG/SWD pins and so release the associated pins for GPIO usage.

Dazu dann Seite 805:
- To use the serial wire DP to release some GPIOs, the user software mustchange the GPIO (PA15, PB3 and PB4) configuration mode in the GPIO_MODER register. This releases PA15, PB3 and PB4 which now become available as GPIOs.


Nochmal meine Meinung:
Lass die rotzigen Bibliotheken weg. Das führt nur zu Problemen. Investier lieber ein bisschen Zeit in die Grundlagen, lies Datasheet, Reference Manual und - wenn es mal ans Eingemachte geht - die ARM-Unterlagen zum Core und programmier dann die Register selber.
Dann weißt Du, was passiert und bist auch gezwungen, Dich damit auseinanderzusetzen. Nur so entsteht Verständnis.

Manekken
15.05.2016, 11:04
Ah okay das wusste ich nicht dass das auch alles JTAG Signale sind.
Ich werd einfach mal andere Pins nehmen die frei sind und das ganze dann nochmal testen.
Oder ich ändere das GPIO_MODER Register einfach so das alles passt.
Ja das mitm Einlesen und selber machen macht sicherlich Sinn. Werde das mal tun!

Danke auf jeden Fall für deine Hilfe!