学习STM32的SD卡读写

为了更好地理解如何在STM32微控制器上进行SD卡读写操作,以下是一个详细的代码案例,涵盖了初始化SD卡、写入数据和读取数据。该代码案例使用STM32Cube库和HAL驱动库。

代码案例概述:

  1. 初始化SD卡。
  2. 创建一个用于写入的缓冲区,并将其填充为示例数据。
  3. 在SD卡上创建一个新的文件。
  4. 将缓冲区的数据写入SD卡的文件中。
  5. 关闭写入文件。
  6. 打开同一个文件进行读取。
  7. 创建一个用于读取的缓冲区。
  8. 从SD卡文件中读取数据到缓冲区。
  9. 关闭读取文件。
  10. 验证读取到的数据是否与写入的数据一致。

代码实现: 首先,需要在STM32CubeMX中配置SD卡接口和相关GPIO引脚。确保已经添加了FATFS库。

#include "stm32f4xx_hal.h"
#include "fatfs.h"

#define BUFFER_SIZE 512
#define FILENAME "test.txt"

FATFS fs;
FIL file;
uint8_t write_buffer[BUFFER_SIZE] = "This is a test message for SD card read/write operation!";
uint8_t read_buffer[BUFFER_SIZE];

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDIO_SD_Init(void);
void Error_Handler(void);

接下来,需要定义一些辅助函数,用于控制SD卡接口和处理错误。

void SD_IO_Init(void);
void SD_IO_WriteCmd(uint8_t cmd, uint32_t arg, uint8_t crc);
uint8_t SD_IO_WaitResponse(uint8_t response);
uint8_t SD_IO_ReadByte(void);
void SD_IO_WriteByte(uint8_t value);
void SD_IO_WriteDummy(void);
void SD_IO_WriteBytes(const uint8_t *data, uint32_t num_bytes);
void SD_IO_ReadBytes(uint8_t *data, uint32_t num_bytes);
void SD_Init(void);
void SD_OpenFile(FIL* file, const TCHAR* path);
void SD_CloseFile(FIL* file);

现在,我们可以开始编写主函数,用于初始化系统和SD卡,并执行读写操作。

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  
  MX_GPIO_Init();
  MX_SDIO_SD_Init();
  
  SD_Init();
  
  if(f_mount(&fs, "", 1) != FR_OK)
  {
    Error_Handler();
  }
  
  SD_OpenFile(&file, FILENAME);
  
  FRESULT res = f_write(&file, write_buffer, sizeof(write_buffer), NULL);
  if(res != FR_OK)
  {
    Error_Handler();
  }
  
  SD_CloseFile(&file);
  
  SD_OpenFile(&file, FILENAME);
  
  res = f_read(&file, read_buffer, sizeof(read_buffer), NULL);
  if(res != FR_OK)
  {
    Error_Handler();
  }
  
  SD_CloseFile(&file);
  
  if(memcmp(write_buffer, read_buffer, sizeof(write_buffer)) != 0)
  {
    Error_Handler();
  }

  while (1);
}

下面是辅助函数的实现:

void SD_IO_Init(void)
{
  HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(SD_CLK_GPIO_Port, SD_CLK_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(SD_CMD_GPIO_Port, SD_CMD_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(SD_D0_GPIO_Port, SD_D0_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(SD_D1_GPIO_Port, SD_D1_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(SD_D2_GPIO_Port, SD_D2_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(SD_D3_GPIO_Port, SD_D3_Pin, GPIO_PIN_SET);
}

void SD_IO_WriteCmd(uint8_t cmd, uint32_t arg, uint8_t crc)
{
  SD_IO_WriteByte(0x40 | cmd);
  SD_IO_WriteByte((uint8_t)(arg >> 24));
  SD_IO_WriteByte((uint8_t)(arg >> 16));
  SD_IO_WriteByte((uint8_t)(arg >> 8));
  SD_IO_WriteByte((uint8_t)arg);
  SD_IO_WriteByte(crc);
}

uint8_t SD_IO_WaitResponse(uint8_t response)
{
  uint32_t timeout = 100000;
  uint8_t r;
  
  do
  {
    r = SD_IO_ReadByte();
    if(--timeout == 0)
    {
      return 0xFF;
    }
  } while(r != response);
  
  return r;
}

uint8_t SD_IO_ReadByte(void)
{
  uint8_t value;
  HAL_SD_ReadBlocks(&hsd, &value, 1, 0, 1);
  return value;
}

void SD_IO_WriteByte(uint8_t value)
{
  HAL_SD_WriteBlocks(&hsd, &value, 1, 0, 1);
}

void SD_IO_WriteDummy(void)
{
  SD_IO_WriteByte(0xFF);
}

void SD_IO_WriteBytes(const uint8_t *data, uint32_t num_bytes)
{
  HAL_SD_WriteBlocks(&hsd, (uint32_t*)data, 0, num_bytes/4, 1);
}

void SD_IO_ReadBytes(uint8_t *data, uint32_t num_bytes)
{
  HAL_SD_ReadBlocks(&hsd, (uint32_t*)data, 0, num_bytes/4, 1);
}

void SD_Init(void)
{
  SD_IO_Init();
  
  SD_IO_WriteDummy();
  
  SD_IO_WriteCmd(0x08, 0x00, 0x87);
  SD_IO_WriteCmd(0x37, 0x00, 0x95);
  
  uint8_t response = SD_IO_WaitResponse(0x01);
  while(response == 0xFF)
  {
    response = SD_IO_WaitResponse(0x01);
  }
  
  if(response != 0x00)
  {
    Error_Handler();
  }
  
  SD_IO_WriteDummy();
  
  SD_IO_WriteCmd(0x16, 0x00000200, 0x01);
  
  response = SD_IO_WaitResponse(0x00);
  while(response == 0xFF)
  {
    response = SD_IO_WaitResponse(0x00);
  }
  
  response = SD_IO_WaitResponse(0x00);
  while(response != 0x00)
  {
    response = SD_IO_WaitResponse(0x00);
  }
  
  SD_IO_WriteDummy();
}

void SD_OpenFile(FIL* file, const TCHAR* path)
{
  if(f_open(file, path, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
  {
    Error_Handler();
  }
}

void SD_CloseFile(FIL* file)
{
  if(f_close(file) != FR_OK)
  {
    Error_Handler();
  }
}

在以上代码中,还使用了一些由HAL库提供的函数,例如SystemClock_Config和MX_GPIO_Init。这些函数的具体实现可以在相应的HAL库文件中找到。

这个代码案例提供了一个基本的框架,帮助您开始在STM32上使用SD卡进行读写操作。根据您的需求,您可以进一步扩展和优化代码。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值