OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12119|回复: 33

SD卡操作,写了其他数据进去,但是每次读出来都是0x09,求高人指点

[复制链接]

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
发表于 2012-5-24 01:32:04 | 显示全部楼层 |阅读模式
就是实现很简单的步骤,SD卡采用SPI通信模式,写一个数据进去,然后把它读出来,数据时肯定写进去了,但是读出来每次都是0x09,只有当单步调试的时候,一步一步走,读出来的数据才是符合要求的,很奇怪,是什么原因造成的呢?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 02:09:42 | 显示全部楼层
简直令人崩溃,buf[318-512]的数据读出来的又是对的,buf[0-318]读出来的数据不是09就是255 255居多,太奇怪了、、
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-5-24 09:03:43 | 显示全部楼层
数据没写进去.要是写进去了就肯定可以读出来.或者你写入的地址和读出的地址不一致.
自己慢慢检查吧.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 12:51:22 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
我慢慢慢慢查了很久 发现数据的确是写进去了,而且刚好512个,但是我是从扇区0开始读的,然后将数组buf传送给串口 在电脑上打印出数据,我用原子哥那个程序,读出来是对的,然后我用我的程序,虽然也读的出来,但是地址并不对应,我的数组用的是buf[1000],我读1000次它的数据,然后将1000个数据打印到电脑上,结果是,并不是buf[0]-buf[512]为扇区数据,而是buf[308] - buf[308 + 512]为正确数据、纳闷了~~
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 12:53:54 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
原子哥,当我采用单步调试时,一步一步走,就是buf[0]~buf[511]的正确数据了
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 13:07:13 | 显示全部楼层
我只能从在读取数据时,采用先读308个数据,但不进行接收,等这308个数据完后,再开始接收。我试了,不是延时的问题,我在前面从1us的延时加到1000us 都无济于事,反而读出来的数据还出问题了。
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 13:41:08 | 显示全部楼层
又有一个新的发现是 这个如果让SPI一直以低速时钟运行,读出来的数据 就是在buf[9] - buf[512] 以后的数据都是错的,9以前的数据也都是错的。
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 13:45:42 | 显示全部楼层
纠正:buf[9]~buf[9 + 511]都是对的、、
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-5-24 13:50:48 | 显示全部楼层
速度太快了吧.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 13:53:54 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
原子哥,我已经把频率降到最低了~ 再低就只能降单片机主频的时钟了~
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 13:54:11 | 显示全部楼层
SPI时钟已经降到最低了、、
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 13:58:22 | 显示全部楼层
简直没办法了,降了试了下,读出来全是44了。。。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-5-24 14:49:44 | 显示全部楼层
那就是其他问题了,呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 14:57:07 | 显示全部楼层
回复【13楼】正点原子:
---------------------------------
哎 对它简直无言了, 数据都是对的,就是位置对不上
回复 支持 反对

使用道具 举报

19

主题

302

帖子

2

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2011-11-22
在线时间
10 小时
发表于 2012-5-24 15:05:07 | 显示全部楼层
相关代码上来,其他人才能看出问题吧
世界如此美好,好好珍惜每一天吧!
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:17:30 | 显示全部楼层
呵呵 这不是怕大家没时间帮我吗~
这是我的初始化,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;
}
}
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:19:01 | 显示全部楼层
这事我的读函数

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;
}
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:21:03 | 显示全部楼层
这是我的指令发送函数,是参照原子大哥写的。

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;
}
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:24:04 | 显示全部楼层
这是设置时钟频率

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);
}
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:24:28 | 显示全部楼层
各位大爷 大哥 大侠 求助啊! 小生实在没办法解决了
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:33:15 | 显示全部楼层
另外有一个很奇怪的现象就是 在初始化完并检验SD卡后发送send_com(16, 512, 0x01);
读回来的数据是0x40,提示参数错误....
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:34:26 | 显示全部楼层
这是主程序、、
#include<stm32f10x_lib.h>
#include"sys.h"
#include"delay.h"
#include"lcd.h"

#define cs Aout(3)

u8 buf[550];

u8 send(u8 da);
void spi_init(void);
void spi_speed(u8);
u8 init_SD(void);
void SD_select(void);
u8 send_com(u8 com, u32 arg, u8 crc);
u8 SD_read(void);
void dis(u16);

void init_usart(void);

int main(void)
{
u8 r;
u16 i;

Stm32_Clock_Init(9);
delay_init(72);
LCD_Init();
init_usart();
r = init_SD();
while(1)
{
if (r == 0)
{
LCD_ShowString(50, 50, "not found");
}
if (r == 1)
{
LCD_ShowString(50, 50, "found SD!");
SD_read();
for(i = 0; i < 523; i++)
{
USART1->DR = buf;
while(!(USART1->SR & (1 << 6)));
USART1->SR &= ~(1 << 6);
}
dis(0);
while(1);
}
delay_ms(1000);
r = init_SD();
}
}
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:38:47 | 显示全部楼层
纠正:写send_com(16, 512, 0x01);返回的数据是0,是正常结果 之前说错了
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:51:54 | 显示全部楼层
            



 
这是实物图。。。。。打印的是523个数据额呢。
注:这个数据是在接收的时候是接收的523个 不是512个

回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 15:53:28 | 显示全部楼层
上图是在这个接收函数下的,之前那个读函数读出来的数据不能直观说明问题
u8 SD_read(void)
{
u8 r1, t, res;
u16 i;

r1 = send_com(17, 0, 0x01);
if (r1 == 0)
{
t = 0xff;
do
{
res = send(0xfe);
t--;
}while(res != 0xfe && t);

for (i = 0; i < 523; i++)
{
delay_us(5);
buf = send(0xff);
}
send(0xff);
send(0xff);
cs = 1;
send(0xff);
return 1;
}
return 0;
}
回复 支持 反对

使用道具 举报

19

主题

302

帖子

2

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2011-11-22
在线时间
10 小时
发表于 2012-5-24 17:49:42 | 显示全部楼层
u8 send(u8 da) 

while((SPI1->SR & 1 << 1) == 0); 
SPI1->DR = da; 
while((SPI1->SR & 1 << 0) == 0); 
return SPI1->DR; 


这个函数里的操作顺序对吗?

编辑,我弄错了还以为SPI1->SR & 1 << 1必须加上SPI1->SR &( 1 << 1),c语言从右向左
世界如此美好,好好珍惜每一天吧!
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 17:55:57 | 显示全部楼层
回复【26楼】dzng11:
---------------------------------
嗯?大哥?你的意思是?
这个函数是抄的原子大哥的~~
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 17:57:37 | 显示全部楼层
回复【26楼】dzng11:
---------------------------------
大哥,小生我求求你看看嘛,我这两天都快被这东西弄疯了
回复 支持 反对

使用道具 举报

19

主题

302

帖子

2

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2011-11-22
在线时间
10 小时
发表于 2012-5-24 18:04:27 | 显示全部楼层
我是说我弄错了,你的是对的 ,
怎么不直接抄原子的呢
世界如此美好,好好珍惜每一天吧!
回复 支持 反对

使用道具 举报

19

主题

302

帖子

2

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2011-11-22
在线时间
10 小时
发表于 2012-5-24 18:24:42 | 显示全部楼层
是不是读的太早了,这个函数如果t超时了,就读取数据了
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; 
}
世界如此美好,好好珍惜每一天吧!
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 22:10:24 | 显示全部楼层
回复【30楼】dzng11:
---------------------------------
学长 还是不对
u8 SD_read(void)
{
u8 r1, t, res;
u16 i;

r1 = send_com(17, 0, 0x01);
if (r1 == 0)
{
t = 0xff;
do
{
res = send(0xfe);
t--;
}while(res != 0xfe && t);
delay_us(150);//此处添加了150us的延时
for (i = 0; i < 523; i++)
{
buf = send(0xff);
}
send(0xff);
send(0xff);
cs = 1;
send(0xff);
return 1;
}
return 0;
}

我那儿再延时读出来的数据也是错的、、、~~学长
我被SD卡弄怕了
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 22:12:15 | 显示全部楼层
回复【31楼】lsj9383:
---------------------------------
SPI初始化,SD卡初始化,时钟频率设置,读顺序,都感觉没错,实在找不到原因了。
学长 你有它的程序吗?我能参考下你的吗?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-5-24 22:20:07 | 显示全部楼层
找不到出路的时候,换条路走.

比如用别人的代码试试.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2233
金钱
2233
注册时间
2012-4-30
在线时间
7 小时
 楼主| 发表于 2012-5-24 22:42:13 | 显示全部楼层
回复【33楼】正点原子:
---------------------------------
原子大哥,我直接用你的代码,可以读出来,但是如果将你的读取那个函数移植到我那个程序上面去,就还是不得行,我最怕的是我初始化程序会出错,但是我左检查右检查,都没的办法、我只好暂时放放它了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 01:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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