辽宁省营商建设监督局网站,莱芜新闻视频回放今天,网站被主流搜索引擎收录的网页数量是多少,网站备案IP与空间开发板
亚博K210开发板
实验目的
本实验主要学习 K210 通过 SPI 读写内存卡文件的功能
实验准备
实验元件
开发板自带的 TF 卡、LCD 显示屏 #xff08;提前准备好 FAT32 格式的TF 卡。TF 插入 TF 卡槽的时候注意方向#xff0c;TF 卡的金手指那一面需要面向开发板提前准备好 FAT32 格式的TF 卡。TF 插入 TF 卡槽的时候注意方向TF 卡的金手指那一面需要面向开发板如果方向插反了是无法读写数据的。TF卡尺寸小性能好传输速度快最初是用于支持内存扩展的手机上比较适合储存高清摄像和高音质音频内容因而被广泛应用于各种多媒体设备上
硬件连接
K210 开发板出厂默认已经焊接 TF 卡槽需要插入 TF 卡才可以使用其中TF 卡槽的 TF_MISO 连接到 IO26TF_CLK 连接到 IO27TF_MOSI 连接到 IO28TF_CSO连接 IO29。 SDK中相关API
SPI 是一种高速、高效率的串行接口技术。通常由一个主模块和一个或多个从模块组成主模块选择一个从模块进行同步通信从而完成数据的交换。SPI是一个环形结构通信时需要至少 4 根线事实上在单向传输时 3 根线也可以它们是 MISO主设备数据输入、MOSI主设备数据输出、SCLK时钟、CS片选。
MISO– Master Input Slave Output,主设备数据输入从设备数据输出MOSI– Master Output Slave Input主设备数据输出从设备数据输入SCLK – Serial Clock时钟信号由主设备产生CS – Chip Select从设备使能信号由主设备控制。当有多个从设备的时候因为每个从设备上都有一个片选引脚接入到主设备机中当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低或者是拉高。 相关接口
spi_init设置 SPI 工作模式、多线模式和位宽。
spi_init_non_standard多线模式下设置指令长度、地址长度、等待时钟数、指令地址传输模式。
spi_send_data_standardSPI 标准模式传输数据。
spi_send_data_standard_dmaSPI 标准模式下使用 DMA 传输数据。
spi_receive_data_standard标准模式下接收数据。
spi_receive_data_standard_dma标准模式下通过 DMA 接收数据。
spi_send_data_multiple多线模式发送数据。
spi_send_data_multiple_dma多线模式使用 DMA 发送数据。
spi_receive_data_multiple多线模式接收数据。
spi_receive_data_multiple_dma多线模式通过 DMA 接收。
spi_fill_data_dma通过 DMA 始终发送同一个数据可以用于刷新数据。
spi_send_data_normal_dma通过 DMA 发送数据。不用设置指令地址。
spi_set_clk_rate设置 SPI 的时钟频率。
spi_handle_data_dmaSPI 通过 DMA 传输数据。实验原理
TF 有 4 个数据传输端DAT0DAT1DAT2DAT3。还有一个 CMD 脚是用来读取卡内信息的。 TF 卡主要管脚的功能 CLK时钟信号每个时钟周期传输一个命令或数据位频率可在 025MHz之间变化TF 卡的总线管理器可以不受任何限制的自由产生 025MHz 的频率 CMD双向命令和回复线命令是主机到从卡操作的开始命令可以是从主机到单卡寻址也可以是到所有卡回复是对之前命令的回答回复可以来自单卡或所有卡 DAT03数据线数据可以从 TF 卡传向主机也可以从主机传向 TF 卡。TF 卡传输数据一般有两种模式SD 模式和 SPI 模式这里我们以 SPI 模式的方式传输数据。SPI 模式引脚如下1CS2DI3VSS4VDD5SCLK6VSS27DO8RSV9RSV。
实验过程
首先初始化 K210 的硬件引脚和软件功能使用的是 FPIOA 映射关系。
void hardware_init(void)
{/*** io26--miso--d1** io27--clk---sclk** io28--mosi--d0** io29--cs----cs*/fpioa_set_function(PIN_TF_MISO, FUNC_TF_SPI_MISO);fpioa_set_function(PIN_TF_CLK, FUNC_TF_SPI_CLK);fpioa_set_function(PIN_TF_MOSI, FUNC_TF_SPI_MOSI);fpioa_set_function(PIN_TF_CS, FUNC_TF_SPI_CS);
}// 硬件IO口与原理图对应
#define PIN_TF_MISO (26)
#define PIN_TF_CLK (27)
#define PIN_TF_MOSI (28)
#define PIN_TF_CS (29)/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口与程序对应
#define TF_CS_GPIONUM (2)/*****************************FUNC-GPIO************************************/
// GPIO口的功能绑定到硬件IO口
#define FUNC_TF_SPI_MISO (FUNC_SPI1_D1)
#define FUNC_TF_SPI_CLK (FUNC_SPI1_SCLK)
#define FUNC_TF_SPI_MOSI (FUNC_SPI1_D0)
#define FUNC_TF_SPI_CS (FUNC_GPIOHS0 TF_CS_GPIONUM)设置系统时钟频率由于 uarths 的时钟来自 PLL0所以设置 PLL0 之后需 要重新初始化以下 uarths否则 printf 可能会打印乱码。
/* 设置系统时钟频率 */
sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL);
sysctl_pll_set_freq(SYSCTL_PLL1, 300000000UL);
sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL);
uarths_init();检测是否有 TF 卡或者 TF 卡是否正常如果不正常则退出。
if (check_sdcard())
{printf(SD card err\n);return -1;
}
如果初始化 TF 卡成功则把 TF 的容量打印出来单位为 G。
static int check_sdcard(void)
{uint8_t status;printf(/******************check_sdcard*****************/\n);status sd_init();printf(sd init :%d\n, status);if (status ! 0){return status;}printf(CardCapacity:%.1fG \n, (double)cardinfo.CardCapacity / 1024 / 1024 / 1024);printf(CardBlockSize:%d\n, cardinfo.CardBlockSize);return 0;
}检测 TF 卡的格式是否是 FAT32如果不是则退出。
if (check_fat32())
{printf(FAT32 err\n);return -1;
}如果检测符合 FAT32 格式的 TF 卡则把 TF 卡挂在到“0”并且把 TF 卡根 目录下的文件和文件夹的名称都打印出来。
static int check_fat32(void)
{static FATFS sdcard_fs;FRESULT status;DIR dj;FILINFO fno;printf(/********************check_fat32*******************/\n);status f_mount(sdcard_fs, _T(0:), 1);printf(mount sdcard:%d\n, status);if (status ! FR_OK)return status;printf(printf filename\n);status f_findfirst(dj, fno, _T(0:), _T(*));while (status FR_OK fno.fname[0]){if (fno.fattrib AM_DIR)printf(dir:%s\n, fno.fname);elseprintf(file:%s\n, fno.fname);status f_findnext(dj, fno);}f_closedir(dj);return 0;
}向 TF 卡写入文件保存在 TF 卡跟目录下的 test.txt如果写入失败则退 出。
sleep(1);
if (sd_write_file(_T(0:test.txt)))
{printf(SD write err\n);return -1;
}在写入文件之前需要先打开文件如果文件不存在则需要创建新文件写入的数据都需要转化成 uint8_t 类型写完数据后必须执行 f_close 关闭文件。
FRESULT sd_write_file(TCHAR *path)
{FIL file;FRESULT ret FR_OK;printf(/*******************sd_write_file*******************/\n);uint32_t v_ret_len 0;/* 打开文件如果文件不存在则新建 */if ((ret f_open(file, path, FA_CREATE_ALWAYS | FA_WRITE)) ! FR_OK){printf(open file %s err[%d]\n, path, ret);return ret;}else{printf(Open %s ok\n, path);}/* 要写入的数据 */uint8_t data[] {H,i,,,D,a,t,a, ,W,r,i,t,e, ,O,k,!};/* 写入数据 */ret f_write(file, data, sizeof(data), v_ret_len);if (ret ! FR_OK){printf(Write %s err[%d]\n, path, ret);}else{printf(Write %d bytes to %s ok\n, v_ret_len, path);}/* 关闭文件 */f_close(file);return ret;
}从 TF 卡读取文件文件为在 TF 卡根目录下的 test.txt。
if (sd_read_file(_T(0:test.txt)))
{printf(SD read err\n);return -1;}读文件前需要判断文件的状态并且打开文件如果文件不存在或者出错则返回如果正常则以只读方式打开文件并且把读到的数据通过串口发送出来。
FRESULT sd_read_file(TCHAR *path)
{FIL file;FRESULT ret FR_OK;printf(/*******************sd_read_file*******************/\n);uint32_t v_ret_len 0;/* 检测文件状态 */FILINFO v_fileinfo;if ((ret f_stat(path, v_fileinfo)) FR_OK){printf(%s length is %lld\n, path, v_fileinfo.fsize);}else{printf(%s fstat err [%d]\n, path, ret);return ret;}/* 只读方式打开文件 */if ((ret f_open(file, path, FA_READ)) FR_OK){char v_buf[64] {0};ret f_read(file, (void *)v_buf, 64, v_ret_len);if (ret ! FR_OK){printf(Read %s err[%d]\n, path, ret);}else{printf(Read : %s \n, v_buf);printf(total %d bytes lenth\n, v_ret_len);}/* 关闭文件 */f_close(file);}return ret;
}编译调试烧录运行 进入 build 目录运行以下命令编译。
cmake .. -DPROJsdcard -G MinGW Makefiles
make编译完成后在 build 文件夹下会生成 sdcard.bin 文件。使用type-C 数据线连接电脑与 K210开发板打开kflash选择对应的设备再将程序固件烧录到 K210 开发板上。
实验现象
烧录完成固件后系统会弹出一个终端界面如果没有弹出终端界面的可以打开串口助手显示调试内容。
实验总结
1.TF 读或写文件前都必须先打开文件读写操作结束后也必须关闭文件。 2.TF 卡通过 SPI 通讯的方式读写数据以 uint8_t 为基本单位。 3.每次烧录完固件后都需要重新给 K210 开发板上电否则会出现 TF 卡初始化 失败而退出系统的问题。