基于nrf51822 SDK10的蓝牙串口工程 ,增加SPI的资源文件到工程,定义SPI0使能,以及定义IO口,和CS引脚电平,新建drv_sd_api.c文件如下即可在主函数调用接口函数对SD卡进行操作,此接口函数是官方提供的一个我只是修改一下,使用前对SD卡的指令以及一些注意事项说明如下:
SD卡的命令格式如下,6字节共48位,传输时最高位(MSB)先传输:
SD卡的command(命令)占6 bit,一般叫CMDx或ACMDx,比如CMD1就是1,CMD13就是13,ACMD41就是41,依此类推。Command Argument(命令参数)占4 byte,并不是所有命令都有参数,没有参数的话该位一般就用置0。最后一个字节由7 bit CRC校验位和1 bit停止位组成。在SPI模式下,CRC是被忽略的,可以都置1或置0.但是发送CMD0时要记得加上CRC,即最后1字节为0x95,因为发送CMD0时还未进入SPI模式。
常用的指令解释如下:
关于SD卡SPI和command的发送要注意以下几点:
1.SD卡的SPI总线,在读入数据时SD卡的SPI是CLK的上升沿输入锁存,输出数据也是在上升沿。
2.向SD卡写入一个CMD或者ACMD指令的过程是这样的: 首先使CS为低电平,SD卡使能;其次在SD卡的Din写入指令;写入指令后还要附加8个填充时钟,是SD卡完成内部操作;之后在SD卡的Dout上接受回应;回应接受完毕使CS为低电平,再附加8个填充时钟。
#include "nrf_gpio.h"
#include "nrf_drv_spi.h"
#include "nrf_drv_common.h"
#include "nrf_assert.h"
#include "app_util_platform.h"
#include "bsp.h"
#include "app_trace.h"
#include "string.h"
#define TX_RX_MSG_LENGTH 100
#define GO_IDLE_STATE 0
#define SEND_OP_COND 1
#define SEND_CSD 9
#define STOP_TRANSMISSION 12
#define SEND_STATUS 13
#define SET_BLOCK_LEN 16
#define READ_SINGLE_BLOCK 17
#define READ_MULTIPLE_BLOCKS 18
#define WRITE_SINGLE_BLOCK 24
#define WRITE_MULTIPLE_BLOCKS 25
#define ERASE_BLOCK_START_ADDR 32
#defin