华大HC32F460 SDIO TF卡实验
目录
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卡实验相关推荐
- 【正点原子探索者STM32F407开发板例程连载+教学】第43章 sd卡实验-SDIO
第四十三章 SD卡实验 1.硬件平台:正点原子探索者STM32F407开发板 2.软件平台:MDK5.1 3.固件库版本:V1.4.0 很多单片机系统都需要大容量存储设备,以存 ...
- STM32——SD卡实验(SDIO方式)
一.SD卡简介 1.什么是SD卡? SD卡(Secure Digital Memory Card)即:安全数码卡.它是在MMC的基础上发展而来,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛的用 ...
- sd卡和sdio sdhc_想买TF卡,那些标注卡上的参数看懂了么?
想买TF卡,那些标注卡上的参数看懂了么? 虽然现在手机已经很少加tf卡了,但是很多设备都需要额外存储卡,而市面上的存储卡一堆一堆,看起来都是64G价格却差距颇大,这是为什么呢?今天就教你看懂参数买对卡 ...
- 【正点原子STM32连载】第四十五章 SD卡实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...
- TF卡 MicroSD卡使用信息
TF卡 或者SD卡封装,带自谈的 SD卡介绍 对于SD卡的硬件结构,在官方的文档上有很详细的介绍,如SD卡内的存储器结构.存储单元组织方式等内容.要实现对它的读写,最核心的是它的时序,笔者在经过了实际 ...
- 克隆树莓Raspberry Pi Mode4 的TF卡
▌01 树莓派TF卡 1.背景介绍 在今年 2021春季学期教学记录 包括一门 2021春季学期-创新设计与实践-高级下 ,其中使用了来自于龙邱科技的 树莓派小车 .在 开始试验 的时候,将其中一块树 ...
- tf卡测试软件_真正的白菜价?1G不到1元,铠侠(原东芝存储)microSD卡评测
在我们的生活中总是离不开存储媒介,特别是进入数字时代,资料的存储显得尤为重要.而对于一些数码产品,microSD卡(TF卡)或者SD卡依旧是常用的选择.而说起存储卡就不得不提到东芝存储,不过在去年东芝 ...
- 基础——ROM, RAM, FLASH, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡,相互关系
1. 关系 ROM, RAM, FLASH闪存, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡, 这几个名词在手机和电脑等数码产品的参数中经常出现,单独看还明白是什么,放在一块,他 ...
- zynq linux tf卡系统升级,zynq之TF卡写入常见问题
zynq之TF卡写入常见问题 1.基本原理 前面做过zynq的TF读写实验,使用串口返回了实验所需的现象.那个时候也没有深究头文件"ff.h"里的几个常用的函数.这次需要使用TF卡 ...
最新文章
- MySQL/MariaDB查询执行路径
- Linux系统学习笔记:文件描述符标志
- java环境变量用不用jre_为什么安装jdk时,会安装两个jre?不用配置jre的环境变量...
- 如何在linux下安装mysql5.7?
- 显示网格_快速制图软件 Edraw Max教程:Edraw Max怎么显示出网格线?
- 动态创建 @ViewChild 导致运行时错误的原因分析
- gitlab 2.7版本升级到2.8
- 开源cms 和 开源博客_BackBee CMS如何以及为何开源
- svn: 无法连接主机“127.0.0.1”: 拒绝连接
- Sharepoint学习笔记---Debug--使用ULS Log跟踪Solution错误信息
- 5319. 删除回文子序列
- C++之stringstream(字符串与数字相互转换)
- Linux下打包qt程序,可以发布到一台纯净的linux发行版系统上
- 【Spring】Spring常用配置-Bean的初始化和销毁(生命周期)
- 74LS165芯片单颗与级联的万能代码|2021-10-6
- 谈MDM主数据管理系统、BI、大数据、SOA之间的关系
- c# Directshow
- 关于字符串赋值的方法以及注意事项
- MFC下的汉字串拼音首字母提取
- photoshop cs5 安装过程及序列号