系统初始化与LED闪烁
一、实验目的
学习使用SDIO方式读写Micro SD卡(TF卡)
二、开发工具
STM32CUBEMX
Keil MDK-ARM V5
MicroSD Card
三、开发步骤
组员前面已经发帖详细讲解了工程的创建方法,此处不再赘述,只说重点
1、新建工程并生成代码
打开Cube新建一个工程,MCU型号选择STM32F746NGH
在Pinout界面设置SDMMC1的Mode,对读写速度要求较高时可选择4bit,此处设置为 1 bit
选择USART1模式为异步
USART引脚需要按原理图配置一下
设置波特率
点击菜单栏project-generate code可以生成工程文件及代码
2、调用SDIO库函数读写SD卡
读扇区 HAL_SD_ReadBlocks
定义读buffer uint32_t receive[1024]; //ReadBuffer 长度设为1024为后面读多块扇区做准备
写扇区 HAL_SD_WriteBlocks
定义写buffer uint32_t write[512]; //WriteBuffer
定义串口发送数组 uint8_t send[512];
1) 读写一块扇区
代码如下
#include "stm32f7xx_hal.h"
-
- /* Private variables ---------------------------------------------------------*/
-
- SD_HandleTypeDef hsd1;
- HAL_SD_CardInfoTypedef SDCardInfo1;
-
- UART_HandleTypeDef huart1;
-
- /* USER variables begin */
- uint8_t send[512];
- uint32_t write[512]; //WriteBuffer
- uint32_t receive[1024]; //ReadBuffer 大小最好为512的整数倍,此处设为1024方便后面读多块扇区
- uint8_t error=0; //errorstate 返回值若不为0,则代表有错误,详见下图
- /* USER variables end */
-
-
-
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- static void MX_GPIO_Init(void);
- static void MX_SDMMC1_SD_Init(void);
- static void MX_USART1_UART_Init(void);
-
-
-
- int main(void)
- {
-
- /* MCU Configuration----------------------------------------------------------*/
-
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
-
- /* Configure the system clock */
- SystemClock_Config();
-
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_SDMMC1_SD_Init();
- MX_USART1_UART_Init();
-
-
- for(uint16_t i=0;i<512;i++)
- {
- write[i]=i/4; //uint8_t 最大到255
- }
-
-
- /* USER CODE BEGIN 2 */
-
- error=HAL_SD_WriteBlocks (&hsd1, write,0, 512,1); //从地址0开始,blocksize为512字节,块数量为1
if(error!=0)
{
HAL_UART_Transmit(&huart1, &error,1, 50);
- }
HAL_Delay(100);
-
- error=HAL_SD_ReadBlocks (&hsd1, receive,0, 512, 1);//读1块
- HAL_Delay(100);
-
- for( uint16_t j=0;j<512;j++)
- {
- send[j]=receive[j];
- }
- HAL_UART_Transmit(&huart1, send,512, 5000); //
-
- /* USER CODE END 2 */
-
- while (1)
- {
-
- }
-
}
若无错误,返回值error为0。错误状态列表如下图所示。
下载程序后,打开串口助手选择COM口和波特率,按RESET后可看到以下结果
write[512]里存的是0,0,0,0,1,1,1,1一直到128,每个数字重复4次,共512个元素。
然而只写入了128个字节,这令我很困惑。blocksize为512,那么写1块应该是512字节才对,不是吗?
2) 读写多块扇区
写4块,读4块
- error=HAL_SD_WriteBlocks (&hsd1, write,0, 512,4); //[i]NumberOfBlocks[/i] 设为4
- HAL_Delay(100);
-
- error=HAL_SD_ReadBlocks (&hsd1, receive,0, 512, 4);//[i]NumberOfBlocks[/i] 设为4
- HAL_Delay(100);
- for( uint16_t j=0;j<512;j++)
- {
- send[j]=receive[j];
- }
- HAL_UART_Transmit(&huart1, send,512, 5000);
-
-
所以说,4块才是512字节么。
3)地址从0开始写4块,从512开始再写4块,一次性读8块
- error=HAL_SD_WriteBlocks (&hsd1, write,0, 512,4); //<em>NumberOfBlocks</em> 设为4
- HAL_Delay(100);
- error=HAL_SD_WriteBlocks (&hsd1, write,512, 512,4); //<em>NumberOfBlocks</em> 设为4
- HAL_Delay(100);
- error=HAL_SD_ReadBlocks (&hsd1, receive,0, 512, 8);//<em>NumberOfBlocks</em> 设为8
- HAL_Delay(100);
-
- for( uint16_t j=0;j<512;j++)
- {
- send[j]=receive[j];
- }
- HAL_UART_Transmit(&huart1, send,512, 5000);
-
- for(uint16_t i=0;i<512;i++)
- {
- send[i]=receive[512+i];
- }
- HAL_UART_Transmit(&huart1, send,512, 5000);
结果是前512字节正常,后面出现乱码。
4) 后续测试
把第二个写函数的地址改成 512*4=2048试一下
HAL_SD_WriteBlocks (&hsd1, write,0, 512,4);
HAL_Delay(100);
HAL_SD_WriteBlocks (&hsd1, write,2048, 512,4);
HAL_Delay(100);
HAL_SD_ReadBlocks (&hsd1, receive,0, 512, 8);
HAL_Delay(100);
OK 两次分别写入了512字节 读出1024字节
所以我认为是这样的:读写函数中,每块在存储区占用了512字节,但是呢,只能存入128字节的数据
也就是说比如现在有0-511字节的数据从0写入,执行下面这条语句
HAL_SD_WriteBlocks (&hsd1, write,0, 512,4);
SD卡存储区中的结果会是这样:
SDIO告一段落,还请各位大神多多指教
本帖最后由 义剑仗乾坤 于 2015-10-25 10:24 编辑