Exemplo n.º 1
0
/**
  * @brief  Initializes the SPIx peripheral according to the specified 
  *   parameters in the SPI_InitStruct.
  * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
  * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
  *   contains the configuration information for the specified SPI peripheral.
  * @retval None
  */
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
{
  uint16_t tmpreg = 0;
  
  /* check the parameters */
  assert_param(IS_SPI_ALL_PERIPH(SPIx));   
  
  /* Check the SPI parameters */
  assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
  assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
  assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
  assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
  assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
  assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
  assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
  assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));

/*---------------------------- SPIx CR1 Configuration ------------------------*/
  /* Get the SPIx CR1 value */
  tmpreg = SPIx->CR1;
  /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
  tmpreg &= CR1_CLEAR_Mask;
  /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
     master/salve mode, CPOL and CPHA */
  /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
  /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */
  /* Set LSBFirst bit according to SPI_FirstBit value */
  /* Set BR bits according to SPI_BaudRatePrescaler value */
  /* Set CPOL bit according to SPI_CPOL value */
  /* Set CPHA bit according to SPI_CPHA value */
  tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
                  SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |  
                  SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |  
                  SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
  /* Write to SPIx CR1 */
  SPIx->CR1 = tmpreg;
  
  /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
  SPIx->I2SCFGR &= SPI_Mode_Select;		

/*---------------------------- SPIx CRCPOLY Configuration --------------------*/
  /* Write to SPIx CRCPOLY */
  SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
}
Exemplo n.º 2
0
void InitSpi(SPI_TypeDef *_s, uint16_t _mode,
			 GPIO_TypeDef *_clkG, uint32_t _clkP,
			 GPIO_TypeDef *_mosiG, uint32_t _mosiP,
			 GPIO_TypeDef *_misoG, uint32_t _misoP,
			 uint16_t _CPOL,uint16_t _CPHA)
{
	assert_param(IS_SPI_CPOL(_CPOL));
	assert_param(IS_SPI_CPHA(_CPHA));
	if (_s == SPI1)
	{
		RCC_APB2PeriphClockCmd(GetRCS_RCC_APB2Periph_SPI(_s), ENABLE);
	}
	else
	{
		RCC_APB1PeriphClockCmd(GetRCS_RCC_APB1Periph_SPI(_s), ENABLE);
	}

	RCC_AHB1PeriphClockCmd(GetRCS_RCC_AHB1Periph_GPIO(_clkG), ENABLE);
	RCC_AHB1PeriphClockCmd(GetRCS_RCC_AHB1Periph_GPIO(_mosiG), ENABLE);
	RCC_AHB1PeriphClockCmd(GetRCS_RCC_AHB1Periph_GPIO(_misoG), ENABLE);

	GPIO_PinAFConfig(_clkG, GetRCS_GPIO_PinSource(_clkP), GetRCS_GPIO_AF_SPI(_s));
	GPIO_PinAFConfig(_mosiG, GetRCS_GPIO_PinSource(_mosiP), GetRCS_GPIO_AF_SPI(_s));
	GPIO_PinAFConfig(_misoG, GetRCS_GPIO_PinSource(_misoP), GetRCS_GPIO_AF_SPI(_s));

	GPIO_InitTypeDef GPIO_Struct;

	GPIO_StructInit(&GPIO_Struct);
	GPIO_Struct.GPIO_Pin = _clkP;
	GPIO_Struct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
#ifdef  OD_OUTPUT
	GPIO_Struct.GPIO_OType = GPIO_OType_OD;
	GPIO_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
	GPIO_Struct.GPIO_OType = GPIO_OType_PP;
	GPIO_Struct.GPIO_PuPd = GPIO_PuPd_UP;
#endif
	GPIO_Init(_clkG, &GPIO_Struct);

	GPIO_StructInit(&GPIO_Struct);
	GPIO_Struct.GPIO_Pin = _mosiP;
	GPIO_Struct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
#ifdef  OD_OUTPUT
	GPIO_Struct.GPIO_OType = GPIO_OType_OD;
	GPIO_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
	GPIO_Struct.GPIO_OType = GPIO_OType_PP;
	GPIO_Struct.GPIO_PuPd = GPIO_PuPd_UP;
#endif
	GPIO_Init(_mosiG, &GPIO_Struct);

	GPIO_StructInit(&GPIO_Struct);
	GPIO_Struct.GPIO_Pin = _misoP;
	GPIO_Struct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
#ifdef  OD_OUTPUT
	GPIO_Struct.GPIO_OType = GPIO_OType_OD;
	GPIO_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
	GPIO_Struct.GPIO_OType = GPIO_OType_PP;
	GPIO_Struct.GPIO_PuPd = GPIO_PuPd_UP;
#endif
	GPIO_Init(_misoG, &GPIO_Struct);

	SPI_InitTypeDef SPI_InitStructure;
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

	SPI_InitStructure.SPI_Mode = _mode;

	SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;

	SPI_InitStructure.SPI_CPOL = _CPOL;
	SPI_InitStructure.SPI_CPHA = _CPHA;
	if (_mode == SPI_Mode_Master)
	{
		SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	}
	else
	{
		SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
	}
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init(_s, &SPI_InitStructure);
	SPI_CalculateCRC(_s,DISABLE);
	SPI_Cmd(_s, ENABLE);
	SPI_CalculateCRC(_s,DISABLE);
}
Exemplo n.º 3
0
/***********************************************************************************************
 功能:SPI 初始化
 形参:SPI_InitStruct SPI 初始化结构
 返回:0
 详解:0
************************************************************************************************/
void SPI_Init(SPI_InitTypeDef* SPI_InitStruct)
{
	SPI_Type *SPIx = NULL;
	PORT_Type *SPI_PORT = NULL;
	SPI_DataMapTypeDef *pSPI_DataMap = (SPI_DataMapTypeDef*)&(SPI_InitStruct->SPIxDataMap);
	SPI_CSMapTypeDef *pSPI_CSMap = (SPI_CSMapTypeDef*)&(SPI_InitStruct->SPIxPCSMap);
	
	//参数检测
	assert_param(IS_SPI_DATA_CHL(SPI_InitStruct->SPIxDataMap));
	assert_param(IS_SPI_PCS_CHL(SPI_InitStruct->SPIxPCSMap));
	assert_param(IS_SPI_BAUDRATE(SPI_InitStruct->SPI_BaudRatePrescaler));
	assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
	assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
	assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
	assert_param(IS_SPI_FIRSTBIT(SPI_InitStruct->SPI_FirstBit));
	
	//找出SPI模块 开SPI模块时钟
	switch(pSPI_DataMap->SPI_Index)
	{
		case 0:
			SIM->SCGC6 |= SIM_SCGC6_SPI0_MASK;
			SPIx = SPI0;
			break;
		case 1:
			SIM->SCGC6 |= SIM_SCGC6_SPI1_MASK;
			SPIx = SPI1;
			break;
		case 2:
			SIM->SCGC3 |= SIM_SCGC3_SPI2_MASK;
		  SPIx = SPI2;
			break;
		default:break;     
	}
	//找出对应的PORT
	switch(pSPI_DataMap->SPI_GPIO_Index)
	{
		case 0:
			SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;
			SPI_PORT = PORTA;
			break;
		case 1:
			SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
			SPI_PORT = PORTB;
			break;
		case 2:
			SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
			SPI_PORT = PORTC;
			break;
		case 3:
			SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK;
			SPI_PORT = PORTD;
			break;
		case 4:
			SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK;
			SPI_PORT = PORTE;
			break;
		default:break;
	}
	//开启对应的引脚 SCK SOUT SIN
	SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index] &= ~PORT_PCR_MUX_MASK;
	SPI_PORT->PCR[pSPI_DataMap->SPI_SIN_Pin_Index] &= ~PORT_PCR_MUX_MASK;
	SPI_PORT->PCR[pSPI_DataMap->SPI_SOUT_Pin_Index] &= ~PORT_PCR_MUX_MASK;
	SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index);
	SPI_PORT->PCR[pSPI_DataMap->SPI_SIN_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index);
	SPI_PORT->PCR[pSPI_DataMap->SPI_SOUT_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index);
	/*SCK配置开漏*/
	SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index]|= PORT_PCR_ODE_MASK;
	//配置PCS
	//找出对应的PORT
	switch(pSPI_CSMap->SPI_GPIO_Index)
	{
		case 0:
			SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;
			SPI_PORT = PORTA;
			break;
		case 1:
			SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
			SPI_PORT = PORTB;
			break;
		case 2:
			SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
			SPI_PORT = PORTC;
			break;
		case 3:
			SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK;
			SPI_PORT = PORTD;
			break;
		case 4:
			SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK;
			SPI_PORT = PORTE;
			break;
		default:break;
	}
	SPI_PORT->PCR[pSPI_CSMap->SPI_PCS_Pin_Index] &= ~PORT_PCR_MUX_MASK;
	SPI_PORT->PCR[pSPI_CSMap->SPI_PCS_Pin_Index] |= PORT_PCR_MUX(pSPI_CSMap->SPI_Alt_Index);
	//设置主从模式
	(SPI_InitStruct->SPI_Mode == SPI_Mode_Master)?(SPIx->MCR  |= SPI_MCR_MSTR_MASK):(SPIx->MCR  &= ~SPI_MCR_MSTR_MASK);
	//配置SPI主模式寄存器
	SPIx->MCR  = 0 & (~SPI_MCR_MDIS_MASK) 
									|SPI_MCR_HALT_MASK        //让SPI进入停止模式
									|SPI_MCR_MSTR_MASK        //配置SPI为主机模式
									|SPI_MCR_PCSIS_MASK       //PCS为高电平当在SPI不工作的时候
									|SPI_MCR_CLR_TXF_MASK     //首先要清除MDIS,清除TXF_MASK和RXF_MASK
									|SPI_MCR_CLR_RXF_MASK  
									|SPI_MCR_DIS_TXF_MASK     //然后再禁止TXD和RXD FIFO 模式 ,将SPI配置成正常模式
									|SPI_MCR_DIS_RXF_MASK
									|SPI_MCR_SMPL_PT(2);
	//配置分频及波特率
	SPIx->CTAR[1] = 0| SPI_CTAR_DBR_MASK	 //设置通信的
									| SPI_CTAR_PCSSCK(0)
									| SPI_CTAR_PASC(0)
									| SPI_CTAR_PBR(0)
									| SPI_CTAR_CSSCK(0)
									| SPI_CTAR_FMSZ(SPI_InitStruct->SPI_DataSize -1) //设置数据传输的位数
									| SPI_CTAR_PDT(0);                                //设置片选信号在数据完成后的延时值 
	//分频设置
	SPIx->CTAR[1] |=SPI_CTAR_BR(SPI_InitStruct->SPI_BaudRatePrescaler);							 
	//时钟相位设置
	(SPI_InitStruct->SPI_CPHA == SPI_CPHA_1Edge)?(SPIx->CTAR[1] &= ~SPI_CTAR_CPHA_MASK):(SPIx->CTAR[1] |= SPI_CTAR_CPHA_MASK);
	//时钟极性
	(SPI_InitStruct->SPI_CPOL == SPI_CPOL_Low)?(SPIx->CTAR[1] &= ~SPI_CTAR_CPOL_MASK):(SPIx->CTAR[1] |= SPI_CTAR_CPOL_MASK);
	//配置MSB或者LSD
	(SPI_InitStruct->SPI_FirstBit == SPI_FirstBit_MSB)?(SPIx->CTAR[1] &= ~SPI_CTAR_LSBFE_MASK):(SPIx->CTAR[1] |= SPI_CTAR_LSBFE_MASK);
	//清空状态
  SPIx->SR = SPI_SR_EOQF_MASK   //队列结束标志 w1c  (write 1 to clear)     
            | SPI_SR_TFUF_MASK    //TX FIFO underflow flag  w1c
            | SPI_SR_TFFF_MASK    //TX FIFO fill      flag  w1c
            | SPI_SR_RFOF_MASK    //RX FIFO overflow  flag  w1c
            | SPI_SR_RFDF_MASK    //RX FIFO fill      flasg w1c (0时为空)
					  | SPI_SR_TCF_MASK;
	//开始传输
	 SPIx->MCR &= ~SPI_MCR_HALT_MASK;    //开始传输,见参考手册1129页
}
/**
  * @brief  Initializes the SPI according to the specified parameters 
  *         in the SPI_InitTypeDef and create the associated handle.
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
  *                the configuration information for SPI module.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
{
  /* Check the SPI handle allocation */
  if(hspi == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
  assert_param(IS_SPI_MODE(hspi->Init.Mode));
  assert_param(IS_SPI_DIRECTION_MODE(hspi->Init.Direction));
  assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
  assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
  assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
  assert_param(IS_SPI_NSS(hspi->Init.NSS));
  assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
  assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
  assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
  assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
  assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));

  if(hspi->State == HAL_SPI_STATE_RESET)
  {
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
    HAL_SPI_MspInit(hspi);
  }
  
  hspi->State = HAL_SPI_STATE_BUSY;

  /* Disble the selected SPI peripheral */
  __HAL_SPI_DISABLE(hspi);

  /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
  /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
  Communication speed, First bit and CRC calculation state */
  WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
                                  hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
                                  hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit  | hspi->Init.CRCCalculation) );

  /* Configure : NSS management */
  WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode));

  /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
  /* Configure : CRC Polynomial */
  WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);

#if defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
  /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
  CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
#endif

#if defined (STM32F101xE) || defined (STM32F103xE)
  /* Check RevisionID value for identifying if Device is Rev Z (0x0001) in order to enable workaround for
     CRC errors wrongly detected */
  /* Pb is that ES_STM32F10xxCDE also identify an issue in Debug registers access while not in Debug mode.
     Revision ID information is only available in Debug mode, so Workaround could not be implemented
     to distinguish Rev Z devices (issue present) from more recent version (issue fixed).
     So, in case of Revison Z F101 or F103 devices, below variable should be assigned to 1 */
  uCRCErrorWorkaroundCheck = 0;
#else
  uCRCErrorWorkaroundCheck = 0;
#endif

  hspi->ErrorCode = HAL_SPI_ERROR_NONE;
  hspi->State = HAL_SPI_STATE_READY;
  
  return HAL_OK;
}