STM32F103做从机SPI通信SPI3中断异常

在做AM335D板子与STM32F103使用SPI通信时,需要用到STM32的从机模式,所以特别对于ST的从机模式进行了研究,由于硬件上使用的是STM32F103的SPI3,所以过程中遇到了一点麻烦,这里记录一下过程,以备查阅:

使用SPI3通信时,从机时钟产生不了中断,经过查阅资料,是因为spi3的nss口与JTAG有共用引脚,所以配置错误会导致SPI3无法使用。需要注意以下两点就可以了:
1.开启GPIO时钟的同时,开启AFIO时钟,如下:

RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );    
2.关闭JTAG功能,使能SWD 如下:

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE) ;

其他的SPI口正常配置,因为板子重启后默认为JTAG模式,所以注意千万不要使用GPIO_Remap_SWJ_Disable ,一旦这样就不能下载程序了,要使用ST的那个工具专门烧录。

以下是具体的代码:

extern u8 SPI3_Buffer_Rx[];
extern u8 RxIdx ;
u16 net_spi_Write(void);

void SPI3_Slave_Init(void)
{
	
	GPIO_InitTypeDef GPIO_InitStructure;
    //GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
	
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );	            
    //RCC_APB2Periph_AFIO很重要
	RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI3, ENABLE );
		
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE) ; //disable掉JTAG复用,很重要
 
	/* MISO设置为推挽输出 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	/* SCK和MOSI设置为下拉输入 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	SPI3_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
	SPI3_InitStructure.SPI_Mode = SPI_Mode_Slave;		
	SPI3_InitStructure.SPI_DataSize = SPI_DataSize_8b;		
	
	SPI3_InitStructure.SPI_CPOL = SPI_CPOL_Low;		
	SPI3_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	
	
	SPI3_InitStructure.SPI_NSS = SPI_NSS_Soft;		
	SPI3_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//
	SPI3_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	
	SPI3_InitStructure.SPI_CRCPolynomial = 7;	
	SPI_Init(SPI3, &SPI3_InitStructure);  //
	
	SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_RXNE, ENABLE); 
 
	SPI_Cmd(SPI3, ENABLE); 
	
	//SPI1_ReadWriteByte(0xff);		 
}   

  
void SPI3_SetSpeed(u8 SpeedSet)
{
	SPI3_InitStructure.SPI_BaudRatePrescaler = SpeedSet ;
    SPI_Init(SPI3, &SPI3_InitStructure);
	SPI_Cmd(SPI3,ENABLE);
} 


u8 SPI3_ReadWriteByte(u8 TxData)
{		
	u8 retry=0;				 	
	while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET) //发送缓存标志位
    {
		retry++;
		if(retry>200)return 0;
	}			  
	SPI_I2S_SendData(SPI3, TxData); //发送数据
	retry=0;

	while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET)//接收缓存标志位
	{
		retry++;
		if(retry>200)return 0;
	}	  						    
	return SPI_I2S_ReceiveData(SPI3); //返回接收到的数据			    
}

void SPI_net_Init(void)
{
	SPI3_Slave_Init();		   
} 

void NVIC_config(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void SPI3_IRQHandler(void) 
{
	volatile uint8_t data;
	if(SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_RXNE) == SET)
	{ 
			while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET)
			{
			}
			SPI3_Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI3);
			while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
			{
			}
			SPI_I2S_ClearITPendingBit(SPI3, SPI_I2S_IT_RXNE);
	} 
}

void net_spi_read_loop(void)
{
	u8 i;
	while (1)
  {
     if(RxIdx>=10)
     {
        SPI_Cmd(SPI3, DISABLE);
        RxIdx=0;
		printf("rcv full:\n");
        for(i=0;i<10;i++)
           printf("0x%02X ",SPI3_Buffer_Rx[i]);
		printf("\r\n ");
		memset(SPI3_Buffer_Rx,0,10);
	    SPI_Cmd(SPI3, ENABLE);
			 
     }
  }
	
	
}

 

你可能感兴趣的:(STM32)