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 | }
|