STM32制作SD卡读卡器

 注意,本博客适合像我一样的小白,会的不多,但是想快速做些东西,不适合会写驱动的大佬。

本文使用stm32f103c8t6,裸机开发。

/**

 * 硬件连接:

 *        CS -> PB12 连接SD卡CS

 *        SCK -> PB13 连接SD卡SCK

 *        MISO -> PB14 连接SD卡MISO

 *        MOSI -> PB15 连接SD卡MOSI

 * 注意:

 *        有的SD卡是带有AMS1117的,其VCC要接在5V上,

 *        STM32在只有jinl供电时5V是不会输出的,要用USB给STM32供电!!!

 *        有的SD卡不支持SPI模式,我尝试后发现SNMSUNG的SD卡不支持,但是KINGSTON的可以

 */

【免费】stm32f103c8t6SD卡驱动(Fatfs)_103C8T6的FAFS文件系统资源-优快云文库

一、SD卡驱动

(一)copy源码,移植

我在优快云上找到了一位大佬用HAL库和fatfs实现stm32f103c8t6对micro SD卡读写的驱动。于是借(抄)鉴(袭)之。

1.编写SPI初始化函数(CubeIDE编辑生成的初始化代码好像在main.c和xxx_msp.c,比较散乱,于是直接上手写)
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//开启GPIOB的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);	//开启SPI2的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);					//将PB12引脚初始化为推挽输出
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);					//将PB13和PB15引脚初始化为复用推挽输出
	

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);					//将PB14引脚初始化为上拉输入
	
	
	/*SPI初始化*/
	SPI_InitTypeDef SPI_InitStructure;						//定义结构体变量
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;			//模式,选择为SPI主模式
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;	//方向,选择2线全双工
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//数据宽度,选择为8位
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;		//先行位,选择高位先行
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;	//波特率分频,选择128分频
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;				//SPI极性,选择低极性
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;			//SPI相位,选择第一个时钟边沿采样,极性和相位决定选择SPI模式0
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;				//NSS,选择由软件控制
	SPI_InitStructure.SPI_CRCPolynomial = 7;				//CRC多项式,暂时用不到,给默认值7
	SPI_Init(SPI2, &SPI_InitStructure);						//将结构体变量交给SPI_Init,配置SPI1
	
	SPI_Cmd(SPI2, ENABLE);									//使能SPI2,开始运行
	
	/*设置默认电平*/
	SD_CS(1);											//SS默认高电平

从原子哥的讲解来看,我们还需要更改SPI的速度,(也就是SPI_baudratePrescaler)可是 标准库当中并没有给出,我们只好操作寄存器,编写该函数(我比较菜,直接从原子哥的fatfs的SPI源码中copying过来)

 

SPI速度设置函数如下 
/**
 * @brief 设置SPI2的速度为低速
*/
void  sd_spi_speed_low(void)
{
	SPI2->CR1&=0XFFC7;
	SPI2->CR1|=SPI_BaudRatePrescaler_256;	//����SPI2�ٶ� 
	SPI_Cmd(SPI2,ENABLE); 
}

/**
 * @brief 设置SPI2的速度为高速
*/
void  sd_spi_speed_high(void)
{
	SPI2->CR1&=0XFFC7;
	SPI2->CR1|=SPI_BaudRatePrescaler_2;	//����SPI2�ٶ� 
	SPI_Cmd(SPI2,ENABLE); 

}

之后出现了一些灵异事件! 

main.c中有一个读写文件的示例函数:

void WritetoSD(char SD_FileName[], uint8_t write_buff[],uint8_t bufSize)

// {

//  FATFS fs;

//  FIL file;

//  uint8_t res=0;

//  UINT Bw;    

   

//  res = SD_init();        //SD卡初始化



//  if(res == 1)

//  {

//      UsartPrintf(USART_DEBUG,"SD卡初始化失败! \r\n");  

//      OLED_ShowString(1,1,"failed!");

//  }

//  else

//  {

//      UsartPrintf(USART_DEBUG,"SD卡初始化成功! \r\n");      

//      OLED_ShowString(1,1,"init successed!");

//  }

   

//  res=f_mount(&fs,"0:",1);        //挂载

   

// //   if(test_sd == 0)        //用于测试格式化

//  if(res == FR_NO_FILESYSTEM)     //没有文件系统,格式化

//  {

// //       test_sd =1;             //用于测试格式化

//      UsartPrintf(USART_DEBUG,"没有文件系统! \r\n");        

//      OLED_ShowString(2,1,"no file system!");

//      res = f_mkfs("", 0, 0);     //格式化sd卡

//      if(res == FR_OK)

//      {

//          UsartPrintf(USART_DEBUG,"格式化成功! \r\n");

//          OLED_ShowString(1,1,"geshihua sed!");      

//          res = f_mount(NULL,"0:",1);         //格式化后先取消挂载

//          res = f_mount(&fs,"0:",1);          //重新挂载  

//          if(res == FR_OK)

//          {

//              UsartPrintf(USART_DEBUG,"SD卡已经成功挂载,可以进进行文件写入测试!\r\n");

//              OLED_ShowString(3,1,"can test");    

//          }  

//      }

//      else

//      {

//          UsartPrintf(USART_DEBUG,"格式化失败! \r\n");    

//          OLED_ShowString(1,1,"geshihua fad!");      

//     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值