目录

1.实验目标

2.实验准备

3.硬件原理

4.驱动代码

5.主流程图

6.实验过程

7.实验扩展

1.实验目标

本实验使用SDIOC一线式读取SD卡相关信息并打印到USB-UART,同时将SD卡容量显示到TFT。等待KEY1按下进入第0区块读取.将读取结果打印到USB-UART同时在TFT显示状态提示。

2.实验准备

硬件搭建:ZW-HC32F460-BZ标准版开发板1套

软件搭建:MDK5.22

3.硬件原理

HC32F460开发板板载的SD卡座支持SD和SPI模式,SD模式支持1线和4线方式传输数据,SPI模式相对于SD模式速度要慢一点,本次实验采用的是SD模式实验1线方式传输数据。

4.驱动代码

【SD初始化函数】

函数原型:   u8 Sdio_Sd_int( void )

功能说明:   SD卡SDIO模式初始化

输入参数:   无

输出参数:   0为成功,其它为不成功

特殊备注:   无

u8 Sdio_Sd_int( void ){en_result_t enTestResult = Ok;   stc_sdcard_init_t stcCardInitCfg ={(en_sdioc_bus_width_t)SDIO_BUS_WIDTH,(en_sdioc_clk_freq_t)SDIO_CLK_FREQ,(en_sdioc_speed_mode_t)SDIO_SPEED_MODE,NULL,};SdioInitPins();MEM_ZERO_STRUCT( stcSdhandle );stcSdhandle.SDIOCx = SDIOC_UNIT;if ( Ok != SDCARD_Init( &stcSdhandle, &stcCardInitCfg ) ){enTestResult = Error;}return (u8)(enTestResult);}

【TFT与SD卡共用脚处理函数】

函数原型:   void SdioCmdPinFuc( en_port_func_t fuc )

功能说明:   TFT与SD卡共用脚处理

输入参数:   引脚功能

输出参数:   无

特殊备注:   无

void SdioCmdPinFuc( en_port_func_t fuc ){PORT_SetFunc( (en_port_t)SDIOC_CMD_PORT, SDIOC_CMD_PIN, fuc, Disable);}

由于SDIOC的CMD引脚是与LCD的D2引脚共用的,所以使用相应功能时,需要切换对应的引脚功能。

【获取SD卡信息函数】

函数原型:   void Sdio_Sd_info_printf( void )

功能说明:   在SDIO模式下获取SD信息

输入参数:   无

输出参数:   无

特殊备注:   无

void Sdio_Sd_info_printf( void ){stc_sd_card_info_t *sdInfo;sdInfo = &stcSdhandle.stcSdCardInfo;SDCardInfo.CardBlockSize = sdInfo->u32BlockSize;SDCardInfo.CardCapacity = (long long)sdInfo->u32BlockNbr;SDCardInfo.CardCapacity *= SDCardInfo.CardBlockSize;switch( sdInfo->u32CardType ){case SDIO_STD_CAPACITY_SD_CARD_V1_1:DDL_Printf( "Card Type:SDSC V1.1\r\n" );break;case SDIO_STD_CAPACITY_SD_CARD_V2_0:DDL_Printf( "Card Type:SDSC V2.0\r\n" );break;case SDIO_HIGH_CAPACITY_SD_CARD:DDL_Printf( "Card Type:SDHC V2.0\r\n" );break;case SDIO_MULTIMEDIA_CARD:DDL_Printf( "Card Type:MMC Card\r\n" );break;}  DDL_Printf( "Card ManufacturerID:%d\r\n",SDCardInfo.SD_cid.ManufacturerID);  //制造商IDDDL_Printf( "Card RCA:%d\r\n",SDCardInfo.RCA);                               //卡相对地址DDL_Printf( "Card Capacity:%d MB\r\n",(u32)(SDCardInfo.CardCapacity>>20));   //显示容量DDL_Printf( "Card BlockSize:%d\r\n\r\n",SDCardInfo.CardBlockSize);       //显示块大小}

这个函数只获取SD卡的制造商信息、卡的相对地址、卡的显示容量以及卡的块大小。通过DDL_Printf函数打印输出到串口显示这些信息。

【SD卡读扇区函数】

函数原型:   u8 Sdio_Sd_ReadDisk( u8 *ptr, u32 StartBlock, u32 BlockNum )

功能说明:   SD卡读扇区

输入参数:   u8 *ptr         读出数据存放指针

u32 StartBlock  从哪一个扇区开始读

u32 BlockNum    一共读多少个扇区

输出参数:   无

特殊备注:   无

u8 Sdio_Sd_ReadDisk( u8 *ptr, u32 StartBlock, u32 BlockNum ){u8 rt = 1;/* Read SD card */if ( Ok == SDCARD_ReadBlocks( &stcSdhandle, StartBlock, BlockNum, (u8 *)ptr, 20000u) ){rt = 0;       }return rt;}

【内存管理初始化函数】

函数原型:   void malloc_mem_init( u8 memx )

功能说明:   内存管理初始化

输入参数:   memx:所属内存块

输出参数:   无

特殊备注:   无

void malloc_mem_init( u8 memx ) { mallocmemset( mallco_dev.memmap[ memx ], 0, memtblsize[ memx ]*2 ); //内存状态表数据清零 mallocmemset( mallco_dev.membase[ memx ], 0, memsize[ memx] );      //内存池所有数据清零 mallco_dev.memrdy[ memx ] = 1;                                                               //内存管理初始化OK } 

这个函数实现的思想是采用分块式内存管理,如下图所示:

从上图可以看出,分块式内存管理由内存池和内存管理表两部分组成。内存池被等分为n块,对应的内存管理表,大小也为 n,内存管理表的每一个项对应内存池的一块内存。

内存管理表的项值代表的意义为:当该项值为 0 的时候,代表对应的内存块未被占用,当该项值非零的时候,代表该项对应的内存块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为 10,那么说明包括本项对应的内存块在内,总共分配了 10 个内存块给外部的某个指针。

内寸分配方向如图所示,是从顶→底的分配方向。即首先从最末端开始找空内存。当内存管理刚初始化的时候,内存表全部清零,表示没有任何内存块被占用。

       分配原理:当指针p调用malloc申请内存的时候,先判断p要分配的内存块数(m),然后从第n项开始,向下查找,直到找到 m 块连续的空内存块(即对应内存管理表项为0),然后将这m个内存管理表项的值都设置为m(标记被占用),最后,把最后的这个空内存块的地址返回指针p,完成一次分配。注意,如果当内存不够的时候(找到最后也没找到连续的m块空闲内存),则返回NULL给p,表示分配失败。

       释放原理:当p申请的内存用完,需要释放的时候,调用free函数实现。free函数先判断p指向的内存地址所对应的内存块,然后找到对应的内存管理表项目,得到p所占用的内存块数目m(内存管理表项目的值就是所分配内存块的数目),将这m个内存管理表项目的值都清零,标记释放,完成一次内存释放。

【分配内存函数】

函数原型:   void *malloc_malloc( u8 memx, u32 size )

功能说明:   分配内存(外部调用)

输入参数:   memx:所属内存块

size:内存大小(字节)

输出参数:   分配到的内存首地址

特殊备注:   无

void *malloc_malloc( u8 memx, u32 size ) { u32 offset;  offset = malloc_mem_malloc( memx, size );                  if( offset == 0XFFFFFFFF )return NULL; elsereturn (void*)( ( u32 )mallco_dev.membase[ memx ] + offset ); } 

【释放内存函数】

函数原型:   void malloc_free( u8 memx, void *ptr )

功能说明:   释放内存(外部调用)

输入参数:   memx:所属内存块

ptr:内存首地址

输出参数:   无

特殊备注:   无

void malloc_free( u8 memx, void *ptr ) { u32 offset;  if(ptr==NULL)return;//地址为0. offset=(u32)ptr-(u32)mallco_dev.membase[memx];    malloc_mem_free(memx,offset);  //释放内存     } 

5.主流程图

流程图中没有表现LCD显示SD的相关信息,在代码中是频繁出现的,因为在使用LCD和SD时需要切换引脚,但总体思路是这样一套流程。

6.实验过程

【第一步:新建/配置工程】

将工程模板复制到实验目录下,将工程名改为SD_SDIO。

勾选FWLibCfg.h配置中的CLK_EN、EFM_EN、GPIO_EN、PWC_EN、SRAM_EN、UTILITY_EN、SDIOC_EN、DMAC_EN选项

【第二步:添加SD模块驱动】

将Sdio.c和Sdio.h复制到\实验36 SD存储实验\Hardware\Peripheral路径下,同时将文件添加到工程中Hardware/Peripheral下。

【第三步:添加SD官方模块驱动】

将sd_card、sdmmc_cmd的头文件和源文件复制到\实验36 SD存储实验\Hardware\OnBoard\sd_card路径下,同时将文件添加到工程中Hardware/OnBoard下。

【第四步:添加内存模块】

将malloc.c和malloc.h复制到\实验36 SD存储实验Hardware\Common\Malloc路径下,同时将文件添加到工程中Hardware/Common下。

【第五步:初始化编程】

1)添加相关头文件头文件

在main.c文件中先添加malloc.h、Sdio.h、sd_card.h头文件。

#include "malloc.h"#include "Sdio.h"#include "sd_card.h"

2)配置SD引脚

打开Sdio.h(一般将h文件添加到c文件并编译,即可在c文件下方显示出该h文件)文件,在下方选择 “Configuration Wizard”标签,即可出现配置界面。将SD进行如下配置。

说明:关于按键、LCD的驱动已经在以前章节讲过怎么配置,请同学们自行配置。

3)内存初始化

在主函数中调用初始化函数malloc_mem_init()。

malloc_mem_init( SRAM1 );

这里只初始化一块内存SRAM1。

4)SD初始化

在主函数中调用初始化函数Sdio_Sd_int()。

       while( Sdio_Sd_int( ) )                               //检测不到SD卡{SdioCmdPinFuc( Func_Gpio );                  //TFT与SD卡共用脚处理DDL_Printf( "SD Card Error!\r\n" );LCD_ShowString(30,130,200,16,16,"SD Card Error!");Ddl_Delay1ms( 500 );                               DDL_Printf( "Please Check! \r\n" );LCD_ShowString(30,130,200,16,16,"Please Check! ");Ddl_Delay1ms( 500 );SdioCmdPinFuc( Func_Sdio );                   //TFT与SD卡共用脚处理  }

【第六步:读取SD卡信息并显示】

使用Sdio_Sd_info_printf()函数读取SD信息,通过串口和LCD显示出来。

  Sdio_Sd_info_printf();SdioCmdPinFuc( Func_Gpio );//检测SD卡成功                                                                           LCD_ShowString(30,130,200,16,16,"SD Card OK    ");LCD_ShowString(30,150,200,16,16,"SD Card Size:     MB");LCD_ShowNum(30+13*8,150,SDCardInfo.CardCapacity>>20,5,16);     //显示SD卡容量

【第七步:按键读取SD卡扇区】

在主循环中通过获取到按键值key1去申请内存然后读取SD扇区,通过LCD和串口显示SD卡扇区信息。

    while( 1 ){key = KeyScan( );if( key == KEY1_VAL )                                            //KEY1按下了{buf = malloc_malloc( 0, 512*4 );                //申请内存if( buf == NULL ){SdioCmdPinFuc( Func_Gpio );                  //TFT与SD卡共用脚处理DDL_Printf( "malloc Error!\r\n" );LCD_ShowString( 30, 150, 200, 16, 16, "malloc Error!" );Ddl_Delay1ms( 500 );                               DDL_Printf( "Please Check! \r\n" );LCD_ShowString( 30, 150, 200, 16, 16, "Please Check!" );Ddl_Delay1ms( 500 );SdioCmdPinFuc( Func_Sdio );                   //TFT与SD卡共用脚处理  }SdioCmdPinFuc( Func_Sdio );rt = Sdio_Sd_ReadDisk( buf, 0, 4 );            //读取0扇区的内容SdioCmdPinFuc( Func_Gpio );if( rt == 0 )    {     LCD_ShowString(30,190,200,16,16,"USART1 Sending Data...");      printf("SECTOR 0 DATA:\r\n");for(sd_size=0;sd_size<512;sd_size++)printf("%x ",buf[sd_size]);//打印0扇区数据              printf("\r\nDATA ENDED\r\n");Ddl_Delay1ms( 300 );LCD_ShowString(30,190,200,16,16,"USART1 Send Data Over!");}malloc_free(0,buf);//释放内存Ddl_Delay1ms(210);        }          }     

【第八步:下载验证】

连接好硬件,编译下载运行该程序,显示SD信息,按下按键key1,读取SD卡扇区,通过串口和LCD显示扇区内容。

    

请注意不同的SD卡,扇区0的内容是不一样的。

7.实验扩展

1)请使用SDIOC模式4线式方式读取SD卡信息。

2)请读取SD卡扇区1的数据。

华大HC32F460 SDIO TF卡实验相关推荐

  1. 【正点原子探索者STM32F407开发板例程连载+教学】第43章 sd卡实验-SDIO

    第四十三章  SD卡实验         1.硬件平台:正点原子探索者STM32F407开发板  2.软件平台:MDK5.1  3.固件库版本:V1.4.0  很多单片机系统都需要大容量存储设备,以存 ...

  2. STM32——SD卡实验(SDIO方式)

    一.SD卡简介 1.什么是SD卡? SD卡(Secure Digital Memory Card)即:安全数码卡.它是在MMC的基础上发展而来,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛的用 ...

  3. sd卡和sdio sdhc_想买TF卡,那些标注卡上的参数看懂了么?

    想买TF卡,那些标注卡上的参数看懂了么? 虽然现在手机已经很少加tf卡了,但是很多设备都需要额外存储卡,而市面上的存储卡一堆一堆,看起来都是64G价格却差距颇大,这是为什么呢?今天就教你看懂参数买对卡 ...

  4. 【正点原子STM32连载】第四十五章 SD卡实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  5. TF卡 MicroSD卡使用信息

    TF卡 或者SD卡封装,带自谈的 SD卡介绍 对于SD卡的硬件结构,在官方的文档上有很详细的介绍,如SD卡内的存储器结构.存储单元组织方式等内容.要实现对它的读写,最核心的是它的时序,笔者在经过了实际 ...

  6. 克隆树莓Raspberry Pi Mode4 的TF卡

    ▌01 树莓派TF卡 1.背景介绍 在今年 2021春季学期教学记录 包括一门 2021春季学期-创新设计与实践-高级下 ,其中使用了来自于龙邱科技的 树莓派小车 .在 开始试验 的时候,将其中一块树 ...

  7. tf卡测试软件_真正的白菜价?1G不到1元,铠侠(原东芝存储)microSD卡评测

    在我们的生活中总是离不开存储媒介,特别是进入数字时代,资料的存储显得尤为重要.而对于一些数码产品,microSD卡(TF卡)或者SD卡依旧是常用的选择.而说起存储卡就不得不提到东芝存储,不过在去年东芝 ...

  8. 基础——ROM, RAM, FLASH, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡,相互关系

    1. 关系 ROM, RAM, FLASH闪存, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡, 这几个名词在手机和电脑等数码产品的参数中经常出现,单独看还明白是什么,放在一块,他 ...

  9. zynq linux tf卡系统升级,zynq之TF卡写入常见问题

    zynq之TF卡写入常见问题 1.基本原理 前面做过zynq的TF读写实验,使用串口返回了实验所需的现象.那个时候也没有深究头文件"ff.h"里的几个常用的函数.这次需要使用TF卡 ...

最新文章

  1. MySQL/MariaDB查询执行路径
  2. Linux系统学习笔记:文件描述符标志
  3. java环境变量用不用jre_为什么安装jdk时,会安装两个jre?不用配置jre的环境变量...
  4. 如何在linux下安装mysql5.7?
  5. 显示网格_快速制图软件 Edraw Max教程:Edraw Max怎么显示出网格线?
  6. 动态创建 @ViewChild 导致运行时错误的原因分析
  7. gitlab 2.7版本升级到2.8
  8. 开源cms 和 开源博客_BackBee CMS如何以及为何开源
  9. svn: 无法连接主机“127.0.0.1”: 拒绝连接
  10. Sharepoint学习笔记---Debug--使用ULS Log跟踪Solution错误信息
  11. 5319. 删除回文子序列
  12. C++之stringstream(字符串与数字相互转换)
  13. Linux下打包qt程序,可以发布到一台纯净的linux发行版系统上
  14. 【Spring】Spring常用配置-Bean的初始化和销毁(生命周期)
  15. 74LS165芯片单颗与级联的万能代码|2021-10-6
  16. 谈MDM主数据管理系统、BI、大数据、SOA之间的关系
  17. c# Directshow
  18. 关于字符串赋值的方法以及注意事项
  19. MFC下的汉字串拼音首字母提取
  20. photoshop cs5 安装过程及序列号

热门文章

  1. PowerDesigner12.5创建物理数据模型
  2. R——R的一些边边角角
  3. 对于CNN卷积神经网络的前向传播和反向传播的理解
  4. 少女异闻录:白鹭白百合的华丽日常 v1.02 存档
  5. 宿州可以学中专计算机的学校有哪些,宿州中专学校排名榜,有哪些专业
  6. 中控指纹考勤机使用实战
  7. uboot usb设备驱动
  8. 如何编译ASP.NET Core源码
  9. JAVA代码总结开始篇【白丁水笔知其然】
  10. 模块的included()