nrf52832 SPi方式无操作系统与SD卡通信

在使用nrf52832开发不带操作系统SPI通信方式操作SD卡时,遇到了许多问题,现慢慢将这些问题整理出来,方便日后开发不会遇到同样的错误。

首先是SPi的初始化,

void SPI_SD_Init(void)
{
	ret_code_t error;
	nrf_gpio_cfg_output(SPIM0_SS_PIN);
	SPI_CS_HIGH();
	nrf_drv_spi_config_t spi_config = {                                                            
	   	.sck_pin      = SPI0_CONFIG_SCK_PIN,      
		.mosi_pin     = SPI0_CONFIG_MOSI_PIN,     
		.miso_pin     = SPI0_CONFIG_MISO_PIN,     
		.ss_pin       = NRF_DRV_SPI_PIN_NOT_USED,                
		.irq_priority = 6, 
		.orc          = 0xFF,                                    
 		.frequency    = NRF_DRV_SPI_FREQ_4M,                     
		.mode         = NRF_DRV_SPI_MODE_3,                      
		.bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,         
	};
	error=nrf_drv_spi_init(&spi, &spi_config, spi_event_handler);
	APP_ERROR_CHECK(error);
}

需要注意的是CS接口需选择NRF_DRV_SPI_PIN_NOT_USED,为了保证SD卡的读写时序和与其他SPI协议通信转换。并且SPI的时序需保证正确。

在SD操作中,会需要对SPI的频率做出修改。这里需要注意的是,在修改SPI频率之前,先要将之前设置的SPI实例除能,之后再以新的频率来在次初始化SPI。

在SD卡的读写数据和读写指令函数时需要注意的是,在返回接收的数据后在函数结束前需加上一段时间的延时:

uint8_t SD_SPI_ReadWriteByte(uint8_t byte)
{
	uint8_t retry=0;	
  /* 将接收标志位设为未接收*/
	spi_xfer_done=false;
  /* 使用spi传输数据*/
  nrf_drv_spi_transfer(&spi, &byte,1,&rx_data,1);
  /* 等待数据接收完成*/
  while (spi_xfer_done)
	{
		retry++;
		if(retry>200)return 0;
	}
	spi_xfer_done=false;
  /* 加上延时*/
	if(delay_HZ==4){
		nrf_delay_us(DELAY_4M);
	}
	else if(delay_HZ==250){
		nrf_delay_us(DELAY_250HZ);
	}
	else if(delay_HZ==125){
		nrf_delay_us(DELAY_125HZ);
	}
  return rx_data;
}
void spi_event_handler(nrf_drv_spi_evt_t const * p_event)
{
    spi_xfer_done = true;//将数据接收标志位设为已接收
}
spi速率也需要考虑,SD卡初始化操作时,SPI的速度需在400KHZ内,之后的数据传输的速率可以是高速率,可我实际操作时发现依旧只能在低速率时操作才会有效。
void SPIx_SetSpeed(uint8_t SpeedSet)
{
	ret_code_t error;
	nrf_drv_spi_uninit(&spi);//将之前的SPi初始化除能,不加这句重定义会失败
	nrf_drv_spi_config_t spi_config = {                                                            
    	.sck_pin      = SPI0_CONFIG_SCK_PIN,      
  	.mosi_pin     = SPI0_CONFIG_MOSI_PIN,     
   	.miso_pin     = SPI0_CONFIG_MISO_PIN,     
  	.ss_pin       = NRF_DRV_SPI_PIN_NOT_USED,                
   	.irq_priority = 6, 
    	.orc          = 0xFF,                                    
   	.frequency    = NRF_DRV_SPI_FREQ_4M,                     
  	.mode         = NRF_DRV_SPI_MODE_3,                      
  	.bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,         
	};
	switch(SpeedSet)
	{
		case 128:spi_config.frequency=NRF_DRV_SPI_FREQ_125K;break;
		case 250:spi_config.frequency=NRF_DRV_SPI_FREQ_250K;break;
		case 5:spi_config.frequency=NRF_DRV_SPI_FREQ_500K;break;
		case 1:spi_config.frequency=NRF_DRV_SPI_FREQ_1M;break;
		case 2:spi_config.frequency=NRF_DRV_SPI_FREQ_2M;break;
		case 4:spi_config.frequency=NRF_DRV_SPI_FREQ_4M;break;
		case 8:spi_config.frequency=NRF_DRV_SPI_FREQ_8M;break;
		default :break;
	}
	error=nrf_drv_spi_init(&spi, &spi_config, spi_event_handler);
	APP_ERROR_CHECK(error);
}
剩下来的要点就还有在nrf52832操作时,读写SD卡操作需要有段延时的缓冲,延时的大小估计与速率相关,实际测试在250KHZ时稳妥的延时为5ms。




你可能感兴趣的:(nrf52832BLE蓝牙开发,SPI,SD,nrf52832)