0 Members and 1 Guest are viewing this topic.
Slave select (NSS) pin managementHardware or software slave select management can be set using the SSM bit in the SPI_CR1 register.• Software NSS management (SSM = 1)The slave select information is driven internally by the value of the SSI bit in the SPI_CR1 register. The external NSS pin remains free for other application uses.• Hardware NSS management (SSM = 0)Two configurations are possible depending on the NSS output configuration (SSOE bit in register SPI_CR2).– NSS output enabled (SSM = 0, SSOE = 1)This configuration is used only when the device operates in master mode. The NSS signal is driven low when the master starts the communication and is kept low until the SPI is disabled. – NSS output disabled (SSM = 0, SSOE = 0)This configuration allows multimaster capability for devices operating in master mode. For devices set as slave, the NSS pin acts as a classical NSS input: the slave is selected when NSS is low and deselected when NSS high.
#include "stm32f10x.h"/* DEFINE */#define BUFFSIZE 32/* GLOBAL VARIABLE */static volatile uint8_t spi_tx_buff[BUFFSIZE] = {0}, spi_rx_buff[BUFFSIZE] = {0}; /* FUNCTION PROTOTYPES */void RCC_Config(void);void GPIO_Config(void);void NVIC_Config(void);void SPI1_Config(void);void DMA1_SPI1_TX_Config(void);void DMA1_SPI1_RX_Config(void); int main(void){ /* Config */ RCC_Config(); GPIO_Config(); NVIC_Config(); SPI1_Config(); DMA1_SPI1_TX_Config(); DMA1_SPI1_RX_Config(); /* SysTick 1ms */ SysTick_Config(SystemCoreClock / 1000); while(1){ }}/* FUNCTION -------------------------------------------------------------------*//* CONFIG ---------------------------------------------------------------------*/void RCC_Config(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);}void GPIO_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; /* GPIO Alternate function */ /* SPI1: PA4 -> NSS */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* SPI1: PA5 -> SCK */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* SPI1: PA6 -> MISO */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* SPI1: PA7 -> MOSI */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure);}void NVIC_Config(void){ NVIC_InitTypeDef NVIC_InitStructure; /* DMA1_Channel2_IRQn */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);}void SPI1_Config(void){ SPI_InitTypeDef SPI_InitStructure; SPI_I2S_DeInit(SPI1); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);}void DMA1_SPI1_TX_Config(void){ DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel3); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_rx_buff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = BUFFSIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel3, &DMA_InitStructure); DMA_Cmd(DMA1_Channel3, ENABLE);}void DMA1_SPI1_RX_Config(void){ DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel2); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_rx_buff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = BUFFSIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel2, &DMA_InitStructure); DMA_Cmd(DMA1_Channel2, ENABLE); DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);}/* INTERRUPT ------------------------------------------------------------------*/void SysTick_Handler(void){}void DMA1_Channel2_IRQHandler(void){ /* SPI1: RX */ if(DMA_GetITStatus(DMA1_IT_TC2) != RESET){ DMA_ClearITPendingBit(DMA1_FLAG_GL2); }}