562|1

441

帖子

3

TA的资源

纯净的硅(高级)

楼主
 

【兆易GD32H759I-EVAL】 SDIO接口TF卡读写测试 [复制链接]

 

测试板卡SDIO接口的TF卡读写测试。

 

一、电路图部分

 

1.1、板卡上SDIO接口

 

 

1.2、SDIO端口连接选择

SDIO支持总线模式有1位模式和4位模式。

 

1.2.1、1位总线模式

1位总线模式只需要连接SDIO0_D0端口到SDIO。

 

 

1.2.2、4位总线模式

4线总线模式需要连接下面跳线

SDIO0_D0~SDIO0_D3都需要连接到SDIO。

 

二、程序部分

 

2.1、sd.c

#include "main.h"

sd_card_info_struct sd_cardinfo;                            /* information of SD card */

uint32_t __attribute__((aligned(32))) buf_write[512];       /* store the data written to the card */
uint32_t __attribute__((aligned(32))) buf_read[512];        /* store the data read from the card */

__align(4) uint8_t sd_data_buf[512];


__asm void INTX_DISABLE(void)
{
	CPSID   I
	BX      LR	  
}

__asm void INTX_ENABLE(void)
{
	CPSIE   I
	BX      LR  
}


void nvic_config(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(SDIO0_IRQn, 2U, 0);
}


sd_error_enum sd_io_init(void)
{
    sd_error_enum status = SD_OK;
    uint32_t cardstate = 0;

    status = sd_init();
    if(SD_OK == status) {
        status = sd_card_information_get(&sd_cardinfo);
    }
    if(SD_OK == status) {
        status = sd_card_select_deselect(sd_cardinfo.card_rca);
    }
    status = sd_cardstatus_get(&cardstate);
    if(cardstate & 0x02000000) {
        printf("\r\n the card is locked!");
        status = sd_lock_unlock(SD_UNLOCK);
        if(status != SD_OK) {
            return SD_LOCK_UNLOCK_FAILED;
        } else {
            printf("\r\n the card is unlocked successfully!");
        }
    }

    if((SD_OK == status) && (!(cardstate & 0x02000000))) {
        /* set bus mode */
#if (SDIO_BUSMODE == BUSMODE_4BIT)
        status = sd_bus_mode_config(SDIO_BUSMODE_4BIT, SDIO_SPEEDMODE);
#else
        status = sd_bus_mode_config(SDIO_BUSMODE_1BIT, SDIO_SPEEDMODE);
#endif
    }

    if(SD_OK == status) {
        /* set data transfer mode */
        status = sd_transfer_mode_config(SDIO_DTMODE);
    }
    return status;
}


void card_info_get(void)
{
    uint8_t sd_spec, sd_spec3, sd_spec4, sd_security;
    uint32_t block_count, block_size;
    uint16_t temp_ccc;
    printf("\r\n Card information:");
    sd_spec = (sd_scr[1] & 0x0F000000) >> 24;
    sd_spec3 = (sd_scr[1] & 0x00008000) >> 15;
    sd_spec4 = (sd_scr[1] & 0x00000400) >> 10;
    if(2 == sd_spec) {
        if(1 == sd_spec3) {
            if(1 == sd_spec4) {
                printf("\r\n## Card version 4.xx ##");
            } else {
                printf("\r\n## Card version 3.0x ##");
            }
        } else {
            printf("\r\n## Card version 2.00 ##");
        }
    } else if(1 == sd_spec) {
        printf("\r\n## Card version 1.10 ##");
    } else if(0 == sd_spec) {
        printf("\r\n## Card version 1.0x ##");
    }

    sd_security = (sd_scr[1] & 0x00700000) >> 20;
    if(2 == sd_security) {
        printf("\r\n## security v1.01 ##");
    } else if(3 == sd_security) {
        printf("\r\n## security v2.00 ##");
    } else if(4 == sd_security) {
        printf("\r\n## security v3.00 ##");
    }

    block_count = (sd_cardinfo.card_csd.c_size + 1) * 1024;
    block_size = 512;
    printf("\r\n## Device size is %dKB ##", sd_card_capacity_get());
    printf("\r\n## Block size is %dB ##", block_size);
    printf("\r\n## Block count is %d ##", block_count);

    if(sd_cardinfo.card_csd.read_bl_partial) {
        printf("\r\n## Partial blocks for read allowed ##");
    }
    if(sd_cardinfo.card_csd.write_bl_partial) {
        printf("\r\n## Partial blocks for write allowed ##");
    }
    temp_ccc = sd_cardinfo.card_csd.ccc;
    printf("\r\n## CardCommandClasses is: %x ##", temp_ccc);
    if((SD_CCC_BLOCK_READ & temp_ccc) && (SD_CCC_BLOCK_WRITE & temp_ccc)) {
        printf("\r\n## Block operation supported ##");
    }
    if(SD_CCC_ERASE & temp_ccc) {
        printf("\r\n## Erase supported ##");
    }
    if(SD_CCC_WRITE_PROTECTION & temp_ccc) {
        printf("\r\n## Write protection supported ##");
    }
    if(SD_CCC_LOCK_CARD & temp_ccc) {
        printf("\r\n## Lock unlock supported ##");
    }
    if(SD_CCC_APPLICATION_SPECIFIC & temp_ccc) {
        printf("\r\n## Application specific supported ##");
    }
    if(SD_CCC_IO_MODE & temp_ccc) {
        printf("\r\n## I/O mode supported ##");
    }
    if(SD_CCC_SWITCH & temp_ccc) {
        printf("\r\n## Switch function supported ##");
    }
}

void clear_buf(void)
{
	uint16_t i;
	for(i = 0; i < 512; i++) {
        buf_write[i] = i;
    }
	/* clean and invalidate buffer in D-Cache */
	SCB_CleanInvalidateDCache_by_Addr(buf_write, 512 * 4);
}


uint8_t sd_readdisk(uint8_t* buf,uint32_t sector,uint32_t cnt)
{
	uint8_t sta=SD_OK;
	uint8_t n;
	long long lsector=sector;
    
	lsector<<=9;
	INTX_DISABLE();
	if((uint32_t)buf%4!=0)
	{
		for(n=0;n<cnt;n++)
		{			
			sta = sd_multiblocks_read((uint32_t*)sd_data_buf, lsector+512*n, 512, 1);
			memcpy(buf,sd_data_buf,512);
			buf+=512;
		}
	}else
	{
		sta = sd_multiblocks_read((uint32_t*)sd_data_buf, lsector+512*n, 512, cnt);
	}
	INTX_ENABLE();
	return sta;
}


uint8_t sd_writedisk(uint8_t *buf,uint32_t sector,uint32_t cnt)
{   
	uint8_t sta=SD_OK;
	long long lsector=sector;
	uint8_t n;
	lsector<<=9;
	INTX_DISABLE();
	if((uint32_t)buf%4!=0)
	{
			for(n=0;n<cnt;n++)
			{
					memcpy(sd_data_buf,buf,512);
					sta = sd_multiblocks_write((uint32_t*)sd_data_buf, lsector+512*n, 512, 1);
					buf += 512;
			}
	}else
	{
		sta = sd_multiblocks_write((uint32_t*)sd_data_buf, lsector+512*n, 512, cnt);
	}
	INTX_ENABLE();
  return sta;
}

uint8_t init_sd(void)
{
	sd_error_enum sd_error;
	uint16_t i = 5;
	do {
        sd_error = sd_io_init();
    } while((SD_OK != sd_error) && (--i));

    if(i) 
		{
        printf("\r\n Card init success!\r\n");
				return i;
    } 
		else 
		{
      printf("\r\n Card init failed!\r\n");
			return 0;
    }
}


void sd_test(void)
{
	uint8_t buf[512];
	uint16_t sd_size;
	sd_error_enum sd_error;
	
	printf("\r\n\r\n Card test:");
    /* single block operation test */
	sd_error = sd_block_write(buf_write, 100, 512);
	if(SD_OK != sd_error) 
	{
		printf("\r\n Block write fail!");
		while(1) 
		{
		}
	} 
	else 
	{
		printf("\r\n Block write success!");
  }
	
	sd_error = sd_block_read(buf_read, 100, 512);
	if(SD_OK != sd_error) 
	{
		printf("\r\n Block read fail!");
		while(1) 
		{
		}
	} 
	else 
	{
		printf("\r\n Block read success!");
	}
	
	if(sd_readdisk(buf,0,1)==SD_OK)	
	{	
		printf("\r\n read sector 0 data:\r\n");
		for(sd_size=0;sd_size<512;sd_size++)
		{
			if(sd_size%32==0)
			{
				printf("\r\n ");
			}
			printf("%02x ",buf[sd_size]);
			
		}
	}
	else
	{
		printf("sector read fail!\r\n");
	}
}

 

2.3、sd.h

#ifndef SD_H
#define SD_H

#include "stdint.h"

#define BUSMODE_1BIT    1
#define BUSMODE_4BIT    0

/* SDIO bus switch */
/* config SDIO bus mode, select: BUSMODE_1BIT/BUSMODE_4BIT */
#define SDIO_BUSMODE        BUSMODE_1BIT
/* config SDIO speed mode, select: SD_SPEED_DEFAULT/SD_SPEED_HIGH */
#define SDIO_SPEEDMODE      SD_SPEED_HIGH
/* config data transfer mode, select: SD_POLLING_MODE/SD_DMA_MODE */
#define SDIO_DTMODE         SD_DMA_MODE //SD_POLLING_MODE

void nvic_config(void);
uint8_t init_sd(void);

void card_info_get(void);
void clear_buf(void);
void sd_test(void);

uint8_t sd_readdisk(uint8_t* buf,uint32_t sector,uint32_t cnt);
uint8_t sd_writedisk(uint8_t *buf,uint32_t sector,uint32_t cnt);


#endif 

 

2.4、main.c

#include "main.h"

void cache_enable(void);

int main(void)
{
	uint8_t x=0;
	uint32_t sd=0;
	uint32_t yd=0;
	
	
	
	uint8_t tx_dat[8];
	
	
	cache_enable();
	nvic_config();
	systick_config();
	init_usart(115200);
	init_led();
	while(init_sd()==0)
	{
		led2_on();
		delay_1ms(500);					
		led2_off();
		delay_1ms(500);
	}
	card_info_get();
	clear_buf();
	sd_test();

	while(1) 
	{
	}
}

void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}

 

 

三、运行结果

 

插入TF卡,容量2G,上电后,串口输出:

 

测试读写一个块的数据和读取扇区0的数据。

 

四、附件

 

程序源码:

gd32h759_prj_tf_wr.rar (815.26 KB, 下载次数: 3)

最新回复

感谢分享   详情 回复 发表于 2024-6-3 07:07
点赞 关注
 
 

回复
举报

6992

帖子

11

TA的资源

版主

沙发
 

感谢分享

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表