发 帖  
原厂入驻New
[问答]

SD卡操作,写了其他数据进去,但是每次读出来都是0x09是怎么回事

223 SD卡 数据
分享
就是实现很简单的步骤,SD卡采用SPI通信模式,写一个数据进去,然后把它读出来,数据时肯定写进去了,但是读出来每次都是0x09,只有当单步调试的时候,一步一步走,读出来的数据才是符合要求的,很奇怪,是什么原因造成的呢?
0
2020-5-26 23:37:30   评论 分享淘帖 邀请回答

相关问题

33个回答
简直令人崩溃,buf[318-512]的数据读出来的又是对的,buf[0-318]读出来的数据不是09就是255 255居多,太奇怪了、、
2020-5-27 07:29:03 评论

举报

数据没写进去.要是写进去了就肯定可以读出来.或者你写入的地址和读出的地址不一致.
自己慢慢检查吧.
2020-5-27 07:36:32 评论

举报

我慢慢慢慢查了很久 发现数据的确是写进去了,而且刚好512个,但是我是从扇区0开始读的,然后将数组buf传送给串口 在电脑上打印出数据,我用原子哥那个程序,读出来是对的,然后我用我的程序,虽然也读的出来,但是地址并不对应,我的数组用的是buf[1000],我读1000次它的数据,然后将1000个数据打印到电脑上,结果是,并不是buf[0]-buf[512]为扇区数据,而是buf[308] - buf[308 + 512]为正确数据、纳闷了~~
2020-5-27 07:51:41 评论

举报

原子哥,当我采用单步调试时,一步一步走,就是buf[0]~buf[511]的正确数据了
2020-5-27 08:08:37 评论

举报

我只能从在读取数据时,采用先读308个数据,但不进行接收,等这308个数据完后,再开始接收。我试了,不是延时的问题,我在前面从1us的延时加到1000us 都无济于事,反而读出来的数据还出问题了。
2020-5-27 08:21:49 评论

举报

又有一个新的发现是 这个如果让SPI一直以低速时钟运行,读出来的数据 就是在buf[9] - buf[512] 以后的数据都是错的,9以前的数据也都是错的。
2020-5-27 08:36:23 评论

举报

纠正:buf[9]~buf[9 + 511]都是对的、、
2020-5-27 08:52:56 评论

举报

2020-5-27 09:06:36 评论

举报

原子哥,我已经把频率降到最低了~ 再低就只能降单片机主频的时钟了~
2020-5-27 09:12:10 评论

举报

SPI时钟已经降到最低了、、
2020-5-27 09:20:38 评论

举报

简直没办法了,降了试了下,读出来全是44了。。。
2020-5-27 09:33:36 评论

举报

那就是其他问题了,呵呵.
2020-5-27 09:41:18 评论

举报

哎 对它简直无言了, 数据都是对的,就是位置对不上
2020-5-27 09:53:42 评论

举报

相关代码上来,其他人才能看出问题吧
2020-5-27 10:08:29 评论

举报

呵呵 这不是怕大家没时间帮我吗~
这是我的初始化,spi_speed(1);代表高速模式 spi_speed(0);代表低速模式
send就是SPI发送的,send_com是发送给SD卡命令 参数 CRC的
u8 init_SD(void)
{
u8 i, r1;
spi_init();//spi及相应脚初始化
spi_speed(0);//低速模式
for (i = 0; i < 20; i++)   //延时74个时钟以上
send(0xff);
i = 20;
do
{
r1 = send_com(0, 0, 0x95);        //复位SD卡,send_com函数里已将CS = 0;
i--;
}while(r1 != 0x01 && i);       
if (i != 0)
{
i = 0xff;
do
{
send_com(55, 0, 0x0);
r1 = send_com(41, 0x40000000, 0x01);           //检验是否为SD卡,是则继续,不是则拒绝访问
}while(r1 && i--);
if (i != 0)
{
if (r1 == 0)
{
cs = 1;
send(0xff);      //禁止SD卡,发送8个时钟
spi_speed(1);
return 1;
}
else
return 0;
}
else
{
cs = 1;
send(0xff);
spi_speed(1);
return 0;
}
}
else
{
cs = 1;
send(0xff);
spi_speed(1);
return 0;
}
}
2020-5-27 10:25:19 评论

举报

这事我的读函数
u8 SD_read(void)
{
u8 r1, t, res;
u16 i;
r1 = send_com(17, 0, 0x01);                //发送读指令,从扇区0开始
if (r1 == 0)
{
t = 0xff;
do
{
res = send(0xfe);
t--;
}while(res != 0xfe && t);               //检验起始令牌
for (i = 0; i < 512; i++)                //开始读数据
{
buf = send(0xff);
}
send(0xff);
send(0xff);
cs = 1;
send(0xff);
return 1;
}
return 0;
}
2020-5-27 10:42:40 评论

举报

这是我的指令发送函数,是参照原子大哥写的。
u8 send_com(u8 com, u32 arg, u8 crc)
{
u8 t, r1;
cs = 1;
send(0xff);                  
SD_select();                //cs = 0
send(com | 0x40);
send((u8)arg >> 24);
send((u8)arg >> 16);
send((u8)arg >> 8);
send((u8)arg);
send(crc);
t = 0x1f;
do
{
t--;
r1 = send(0xff);
}while((r1 & 0x80) && t);
return r1;
}
2020-5-27 10:58:12 评论

举报

这是设置时钟频率
void spi_speed(u8 speed)
{
SPI1->CR1 &= 0xffc7;
if (speed == 0)
SPI1->CR1 |= 7 << 3;
if (speed == 1)
SPI1->CR1 |= 1 << 3;
SPI1->CR1 |= 1 << 6;
}
这是SPI初始化
void spi_init(void)
{
RCC->APB2ENR |= 1 << 2 | 1 << 12;
GPIOA->CRL &= 0x000f0fff;
GPIOA->CRL |= 0xbbb03000;
cs = 1;
SPI1->CR1|=0<<10;//全双工模式
SPI1->CR1|=1<<9; //软件nss管理
SPI1->CR1|=1<<8;  
SPI1->CR1|=1<<2; //SPI主机
SPI1->CR1|=0<<11;//8bit数据格式
SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1
SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1  
SPI1->CR1|=7<<3; //Fsck=Fcpu/256
SPI1->CR1|=0<<7; //MSBfirst   
SPI1->CR1|=1<<6; //SPI设备使能
send(0xff);
}
这是SPI的发送
u8 send(u8 da)
{
while((SPI1->SR & 1 << 1) == 0);
SPI1->DR = da;
while((SPI1->SR & 1 << 0) == 0);
return SPI1->DR;
}
这是SD片选函数
void SD_select(void)
{
u8 t;
cs = 0;
t = 0xff;
do
{
t--;
}while(t && send(0xff) != 0xff);
}
2020-5-27 11:07:27 评论

举报

各位大爷 大哥 大侠 求助啊! 小生实在没办法解决了
2020-5-27 11:22:42 评论

举报

只有小组成员才能发言,加入小组>>

12下一页

86个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /8 下一条

快速回复 返回顶部 返回列表