2017-01-26 02:20 AM
#define sbi(port,bit) port |= (1<<bit)
#define cbi(port,bit) port &= ~(1<<bit)
#define cb(port,bit) port & (1<<bit)
void
clock_setup(
)
;
void
spi_master_setup(
)
;
void
spi_tx(
unsigned
char
tx)
;
void
gpio_init(
)
;
void
spi_enable(
)
;
void
clock_setup(
)
{
sbi(
RCC->
APB2ENR,
12
)
;
//enable clock for SPI1
sbi(
RCC->
AHB1ENR,
0
)
;
//enable clock for GPIOA
}
void
spi_master_setup(
)
{
cbi(
SPI1->
CR1,
15
)
;
//spi 2 line unidirection full duplex
sbi(
SPI1->
CR1,
2
)
;
//spi1 in master mode
cbi(
SPI1->
CR1,
11
)
;
//SPI1 in 8 bit data format
sbi(
SPI1->
CR1,
1
)
;
//CPOL=1 clock polarity 1 when idle
sbi(
SPI1->
CR1,
0
)
;
//CPHA=1 second clock transition is the first data capture edge
cbi(
SPI1->
CR1,
9
)
;
//NSS software slave management---------------
SPI1->
CR1&=
~(
(
1
<<
3
)
|
(
1
<<
4
)
|
(
1
<<
5
)
)
;
//000 for prescaler fpclk/2
cbi(
SPI1->
CR1,
7
)
;
//MSB first
}
void
gpio_init(
)
{
GPIOA->
MODER|=
(
(
1
<<
11
)
|
(
1
<<
13
)
|
(
1
<<
15
)
)
;
//set A5,A6,A7 as alternate function mode
GPIOA->
OTYPER&=
~(
(
1
<<
5
)
|
(
1
<<
6
)
|
(
1
<<
7
)
)
;
//output type pushpull
GPIOA->
OSPEEDR&=
~(
(
1
<<
10
)
|
(
1
<<
11
)
|
(
1
<<
12
)
|
(
1
<<
13
)
|
(
1
<<
14
)
|
(
1
<<
15
)
)
;
//output speed
GPIOA->
AFR[
0
]
|=
(
(
1
<<
20
)
|
(
1
<<
22
)
)
;
//select AF5 for SPI_SCK
GPIOA->
AFR[
0
]
|=
(
(
1
<<
24
)
|
(
1
<<
26
)
)
;
//select AF5 for SPI_MISO
GPIOA->
AFR[
0
]
|=
(
(
1
<<
28
)
|
(
1
<<
30
)
)
;
//select AF5 for SPI_MISO
sbi(
GPIOA->
MODER,
0
)
;
//set 0th bit to set GPIOA_0 as output mode
cbi(
GPIOA->
OTYPER,
0
)
;
//Push-pull
GPIOA->
OSPEEDR&=
~(
(
1
<<
0
)
|
(
1
<<
1
)
)
;
//low speed
sbi(
GPIOA->
ODR,
0
)
;
}
void
spi_enable(
)
{
sbi(
SPI1->
CR1,
6
)
;
}
void
spi_tx(
unsigned
char
tx)
{
cbi(
GPIOA->
ODR,
0
)
;
tx=
SPI1->
DR;
while
(
!
(
cb(
SPI1->
SR,
1
)
)
)
;
SPI1->
DR=
tx;
sbi(
GPIOA->
ODR,
0
)
;
}
void
delayf(
unsigned
int
x)
;
int
main(
)
{
unsigned
char
tx=
0
;
clock_setup(
)
;
spi_master_setup(
)
;
gpio_init(
)
;
spi_enable(
)
;
while
(
1
)
{
tx++;
spi_tx(
tx)
;
delayf(
10
)
;
}
}
void
delayf(
unsigned
int
x)
{
unsigned
int
i,
j;
for
(
i=
0
;
i<
x;
i++
)
{
for
(
j=
0
;
j<
1000
;
j++
)
;
}
}
above code is for spi interfacing with stm32f407vg discovery board...i wrote my own bare-metal code...and i just debug this code with st-link debugger provided on board with keilV5 IDE...here my code is for spi master mode..and when i enable spi SPE(spi enable bit) it will automatically reset MSTR(Master mode bit) bit..and it behaves like slave mode and i debug this code many times but i couldn't identify where i am doing wrong..
please help us little bit...
2017-01-26 05:28 PM
Did you use CUBE MX ?
there are separate modes for SPI slave and SPI master.
I guess the Cubemx file has the SPI port set to master.
2017-01-27 11:30 PM
No i haven't use CUBE MX...i just wrote bare-metal code for this
2017-01-27 11:52 PM
there are three options for the flag:
#define SPI_NSS_SOFT SPI_CR1_SSM
#define SPI_NSS_HARD_INPUT (0x00000000U)
#define SPI_NSS_HARD_OUTPUT (0x00040000U)
implementation:
hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
is this what you have ?
�?�?�?�?�?�?�?�?�?�?
2017-01-28 12:27 AM
yes, then also it is not working.
2017-01-28 12:28 AM
Do you have any sample code for SPI interfacing with STM32F407xx???
2017-01-28 12:38 AM
I too use uV5 and bare metal,..
void quickSend8SPI(SPI_HandleTypeDef *hspi){while( !(hspi->Instance->SR & SPI_FLAG_TXE));*((__IO uint8_t *)&hspi->Instance->DR) = TxSPIByte;}void quickSendReceive8SPI(SPI_HandleTypeDef *hspi){ while( !(hspi->Instance->SR & SPI_FLAG_TXE));*((__IO uint8_t *)&hspi->Instance->DR) = TxSPIByte;// force the SPI to transceive 8 bitwhile( !(hspi->Instance->SR & SPI_FLAG_TXE));while( (hspi->Instance->SR & SPI_FLAG_BSY));while( (hspi->Instance->SR & SPI_FLAG_RXNE))RxSPIByte1 = hspi->Instance->DR;}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
this runs on an '
2017-01-28 05:11 AM
Both the SPL and HAL libraries come with directories full of peripheral examples. There should definitely be a board-to-board one.
2017-09-08 12:08 AM
The SSOE (Slave Select Output Enable) bit in Control Register 2 (CR2) should also be set if the SPI1 is configured in Master mode. If this bit is reset to zero, the SPI1 will think that the it is configured in SPI Multi-master mode and it will become a slave even if you try to pull the NSS line low. Eventually, the MSTR bit in CR1 will be cleared and the MODF bit in the status register will be set and an Interrupt will be triggered if enabled.