Forum: Mikrocontroller und Digitale Elektronik Sensor über SPI auslesen STM32F4


von Sebastian T. (sebastian_tsch)


Lesenswert?

Hi,

Ich versuche einen AS5048 über die SPI Schnittstelle auszulesen, doch 
leider funktioniert das ganze noch nicht. Wie ich das sehe, muss ich, um 
die Winkelposition zu erhalten, den Wert 0x3FFF dem SPI übergeben? Habe 
ich da was missverstanden?

Datenblatt As5048: 
https://ams.com/eng/content/download/438523/1341157/file/AS5048_DS000298_2-00.pdf

Grüsse Sebastian
1
#include "stm32f4xx.h"
2
#include "stm32f4_discovery.h"
3
      
4
5
void init_SPI1(void){
6
7
  GPIO_InitTypeDef GPIO_InitStruct;
8
  SPI_InitTypeDef SPI_InitStruct;
9
10
  // enable clock for used IO pins
11
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
12
13
  /* configure pins used by SPI1
14
   * PA5 = SCK
15
   * PA6 = MISO
16
   * PA7 = MOSI
17
   */
18
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
19
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
20
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
21
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
22
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
23
  GPIO_Init(GPIOA, &GPIO_InitStruct);
24
25
  // connect SPI1 pins to SPI alternate function
26
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
27
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
28
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
29
30
  // enable clock for used IO pins
31
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
32
33
  /* Configure the chip select pin
34
     in this case we will use PE7 */
35
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
36
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
37
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
38
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
39
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
40
  GPIO_Init(GPIOE, &GPIO_InitStruct);
41
42
  GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high
43
44
  // enable peripheral clock
45
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
46
47
  /* configure SPI1 in Mode 0
48
   * CPOL = 0 --> clock is low when idle
49
   * CPHA = 0 --> data is sampled at the first edge
50
   */
51
  SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
52
  SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
53
  SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b; // one packet of data is 8 bits wide
54
  SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
55
  SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
56
  SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high
57
  SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI frequency is APB2 frequency / 4
58
  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
59
  SPI_Init(SPI1, &SPI_InitStruct);
60
61
  SPI_Cmd(SPI1, ENABLE); // enable SPI1
62
}
63
64
/* This funtion is used to transmit and receive data
65
 * with SPI1
66
 *       data --> data to be transmitted
67
 *       returns received value
68
 */
69
uint16_t SPI1_send(uint16_t data){
70
71
  SPI1->DR = data; // write data to be transmitted to the SPI data register
72
  while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
73
  while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
74
  while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
75
  return SPI1->DR; // return received data from SPI data register
76
}
77
78
int main(void)
79
{
80
  /* Initialize system */
81
  SystemInit();
82
83
  init_SPI1();
84
85
  uint16_t data=0;
86
87
  while(1) {
88
    //activate slave with LOW, disable with HIGH
89
    GPIOE->BSRRH |= GPIO_Pin_7; // set PE7 (CS) low
90
    data = SPI1_send(0x3FFF); // 0x3FFF -> Transmit Angle Read command
91
    GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 (CS) high
92
93
    for(int i=0;i<8000000;i++);
94
  }
95
}

von Gerhard G. (xmega)


Lesenswert?

Sebastian T. schrieb:

richtig:
> GPIOE->BSRRH |= GPIO_Pin_7; // set PE7 (CS) high
> GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 (CS) low

hast du nicht GPIOE->BSRRH mit GPIOE->BSRRL vertauscht?

von Sebastian T. (sebastian_tsch)


Lesenswert?

Ich habe es hinbekommen, ich musste natürlich die oberen beiden Bits 
abschneiden von den Daten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.