Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
SPI
请教SPI初始化SD卡
发布于 2019-01-25 23:22:51 浏览:3197
订阅该版
```/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-09-25 misonyo first edition. */ /* * 程序清单:这是一个SD卡设备的使用例程 * 例程导出了 sd_sample 命令到控制终端 * 命令调用格式:sd_sample sd0 * 命令解释:命令第二个参数是要使用的SD设备的名称,为空则使用例程默认的SD设备。 * 程序功能:程序会产生一个块大小的随机数,然后写入SD卡中,然后在读取这部分写入的数据。 * 对比写入和读出的数据是否一致,一致则表示程序运行正确。 */ #include
#include
#include
#define SD_DEVICE_NAME "sd0" extern rt_err_t msd_init(const char *sd_device_name, const char *spi_device_name); void fill_buffer(rt_uint8_t *buff, rt_uint32_t buff_length) { rt_uint32_t index; /* 往缓冲区填充随机数 */ for (index = 0; index < buff_length; index++) { buff[index] = ((rt_uint8_t)rand()) & 0xff; } } static int sd_sample(int argc, char *argv[]) { rt_err_t ret; rt_device_t sd_device; char sd_name[RT_NAME_MAX]; rt_uint8_t *write_buff, *read_buff; struct rt_device_blk_geometry geo; rt_uint8_t block_num; /* 判断命令行参数是否给定了设备名称 */ if (argc == 2) { rt_strncpy(sd_name, argv[1], RT_NAME_MAX); } else { rt_strncpy(sd_name, SD_DEVICE_NAME, RT_NAME_MAX); } /* 查找设备获取设备句柄 */ sd_device = rt_device_find(sd_name); if (sd_device == RT_NULL) { rt_kprintf("find device %s failed!
", sd_name); return RT_ERROR; } /* 打开设备 */ ret = rt_device_open(sd_device, RT_DEVICE_OFLAG_RDWR); if (ret != RT_EOK) { rt_kprintf("open device %s failed!
", sd_name); return ret; } rt_memset(&geo, 0, sizeof(geo)); /* 获取块设备信息 */ ret = rt_device_control(sd_device, RT_DEVICE_CTRL_BLK_GETGEOME, &geo); if (ret != RT_EOK) { rt_kprintf("control device %s failed!
", sd_name); return ret; } rt_kprintf("device information:
"); rt_kprintf("sector size : %d byte
", geo.bytes_per_sector); rt_kprintf("sector count : %d
", geo.sector_count); rt_kprintf("block size : %d byte
", geo.block_size); /* 准备读写缓冲区空间,大小为一个块 */ read_buff = rt_malloc(geo.block_size); if (read_buff == RT_NULL) { rt_kprintf("no memory for read buffer!
"); return RT_ERROR; } write_buff = rt_malloc(geo.block_size); if (write_buff == RT_NULL) { rt_kprintf("no memory for write buffer!
"); rt_free(read_buff); return RT_ERROR; } /* 填充写数据缓冲区,为写操作做准备 */ fill_buffer(write_buff, geo.block_size); /* 把写数据缓冲的数据写入SD卡中,大小为一个块,size参数以块为单位 */ block_num = rt_device_write(sd_device, 0, write_buff, 1); if (1 != block_num) { rt_kprintf("write device %s failed!
", sd_name); } /* 从SD卡中读出数据,并保存在读数据缓冲区中 */ block_num = rt_device_read(sd_device, 0, read_buff, 1); if (1 != block_num) { rt_kprintf("read %s device failed!
", sd_name); } /* 比较写数据缓冲区和读数据缓冲区的内容是否完全一致 */ if (rt_memcmp(write_buff, read_buff, geo.block_size) == 0) { rt_kprintf("Block test OK!
"); } else { rt_kprintf("Block test Fail!
"); } /* 释放缓冲区空间 */ rt_free(read_buff); rt_free(write_buff); return RT_EOK; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(sd_sample, sd device sample); int main() { msd_init(SD_DEVICE_NAME, "spi1"); return 0; } ```大家好,我在做SPI实验时遇到了图中的问题,请问一下该如何解决? 我使用的是原子mini stm32f103rct6开发板,SD卡的使能引脚是PA3; 在main线程中调用了msd_init()函数(不知道这样使用是否正确、规范?)。 编译运行后list_device,见上图。 运行sd_sample的时候就出现问题了,是使能引脚有误么?该在哪里修改呢...:) 
查看更多
7
个回答
默认排序
按发布时间排序
yaomo718
2019-01-25
这家伙很懒,什么也没写!
看错误提示是说有互斥量未被初始化。再看上面打印的设备里SPI1的ref count为0,说明你的spi1没有打开呀,造成互斥量没有被初始化。
misonyo
2019-01-29
这家伙很懒,什么也没写!
msd_init函数怎么实现的
liu2guang
认证专家
2019-01-30
这家伙很懒,什么也没写!
在list_device中没有看见SPI Device驱动,怀疑你没有在SPI Bus总线驱动上去注册SPI Device驱动,应该是用法错误。 楼上所说的SPI1的ref count为0是正常情况,因为SPI Bus本来就不会被打开(open)的。 建议参考下LPC54114 Bsp下面的挂载spi sdcard的实例。
Liam
2019-01-30
这家伙很懒,什么也没写!
>在list_device中没有看见SPI Device驱动,怀疑你没有在SPI Bus总线驱动上去注册SPI Device驱动,应该是用法 ... --- 非常感谢。经过这两天的实验,调通了SDIO接口和USB大容量存储设备,大概知道了RTT设备这一块是如何工作的。 刚才将menuconfig中SPI sd打开,重新编译运行后执行list_device,可以看到SPI bus,但是没有看到SPI device,这时mount肯定不成功的。有一个问题,SPI总线可以挂载多个设备,那么设备的片选信号引脚在软件里面该如何设置?
Liam
2019-01-30
这家伙很懒,什么也没写!
>msd_init函数怎么实现的 --- 这个函数在spi_msd.c中实现的,病急乱投医,不懂怎么用,拿来测试的。
liu2guang
认证专家
2019-01-30
这家伙很懒,什么也没写!
[i=s] 本帖最后由 liu2guang 于 2019-1-30 15:55 编辑 [/i] >非常感谢。经过这两天的实验,调通了SDIO接口和USB大容量存储设备,大概知道了RTT设备这一块是如何工作的 ... --- 在注册SPI Device设备时,需要指定CS引脚, 然后CS的管理由,SPI框架去处理,对于开发者来说,只需要open write read就好了,可以看作"几个完全独立的设备了"。 再补充一点:SPI BUS驱动注册成功了可以看到 SPI Bus类型设备,SPI Device 可以看到 SPI Dev类型的设备,SPI SDCARD模拟成功了会看到 Block块设备。 希望以上信息能够帮助到你!
Liam
2019-01-30
这家伙很懒,什么也没写!
>在注册SPI Device设备时,需要指定CS引脚, 然后CS的管理由,SPI框架去处理,对于开发者来说,只需要open w ... --- 非常感谢耐心回答:lol 我再测试一下
撰写答案
登录
注册新账号
关注者
0
被浏览
3.2k
关于作者
Liam
这家伙很懒,什么也没写!
提问
10
回答
38
被采纳
0
关注TA
发私信
相关问题
1
BBB的SPI驱动
2
求个SPI上挂两个或多个设备的使用例子
3
SPI设备有个bug
4
spi flash 的fatfs使用一段时间后读写文件出现故障
5
SPI驱动
6
请教rt_spi_configure函数理解
7
SPI FLASH挂载的问题
8
SPI-FLASH 文件系统 SPIFFS
9
求助一个完整的 spi flash 驱动
10
关于同时使用文件系统与SPI FLASH的问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
MCAX-156 ADC测评
2
【FRDM-MCXA156测评】- CherryUSB与hid鼠标设备模仿
3
【FRDM-MCXA156测评】- 硬件SPI模块
4
【NXP-MCXA156】恩智浦A156上的 IIC(硬件) 实践
5
【FRA156测评DM-MCX】- PWM模块
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
UART
ESP8266
cubemx
WIZnet_W5500
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
GD32
ADC
flashDB
编译报错
socket
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
出出啊
1520
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
550
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
5
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
1
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部