OpenEdv-开源电子网

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

一个纠结了两天的问题,最后结果却挺古怪,特发此贴忘告人指点,给新手警示

[复制链接]

5

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2012-2-15
在线时间
8 小时
发表于 2014-7-24 15:49:06 | 显示全部楼层 |阅读模式
硬件是STC12C5A60S2 +SD卡

移植pFatfs文件系统时,遇到的,问题如下

驱动SD卡是用SPI总线,用IO模拟总线的方式

为了限制SPI的速度,因此都加了延时函数

void SPI_WriteByte(UINT8 Dat)
{
  _dat=Dat;
  SPI_MOSI=_dat7;
  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);
  SPI_MOSI=_dat6;

  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);
  SPI_MOSI=_dat5;

  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);
  SPI_MOSI=_dat4;

  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);
  SPI_MOSI=_dat3;

  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);

  SPI_MOSI=_dat2;
  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);

  SPI_MOSI=_dat1;
  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);

  SPI_MOSI=_dat0;
  SPI_SCK_L;
  SPI_Delayms(SPI_Speed);
  SPI_SCK_H;
  SPI_Delayms(SPI_Speed);
}

void SPI_Delayms(UINT16 Nms)
{
   UINT16 i,j;
   for(i=Nms;i>0;i--)
      for(j=1;j>0;j--);
}
可以确认的是 这个延时函数的输入参数Nms 不可能超过255,实际上只有10
一开始用UINT8 ,也就是unsigned char 定义的,就是读取SD扇区数据不对
可能是因为速度过快,后来改为UINT16  定义 也就是unsigned int 定义的,其他的一个字符都没改就可以了
void SPI_Delayms(UINT8 Nms)
{
   UINT8 i,j;
   for(i=Nms;i>0;i--)
      for(j=1;j>0;j--);
}


不知道有没有遇到这个问题的,我一直搞不明白为什么
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-7-24 15:56:52 | 显示全部楼层
一般我都是定义16bit的,所以这个没遇到过
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

38

主题

2061

帖子

6

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3273
金钱
3273
注册时间
2012-1-16
在线时间
37 小时
发表于 2014-7-24 19:54:42 | 显示全部楼层
谢谢分享。。。。
站在巨人的肩膀上不断的前进。。。
回复 支持 反对

使用道具 举报

2

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
821
金钱
821
注册时间
2013-6-5
在线时间
141 小时
发表于 2014-7-27 20:19:00 | 显示全部楼层
虽然一个字也没改,但是处理char 是比处理 int 要快的,你的SPI_Delayms 实际上是变慢了,一点点就差这么一点点.
回复 支持 反对

使用道具 举报

10

主题

560

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1739
金钱
1739
注册时间
2014-6-27
在线时间
943 小时
发表于 2014-8-1 14:41:01 | 显示全部楼层
这个函数也写得太臃肿了点吧?给你个IO模拟的:
static void spi_delay()
{
delay_us(5);
}
//SPI2 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI_ReadWriteByte(u8 data,u8 speed)
{
   u8 i,getByte = 0;
   SCK=0;
   MOSI=1; 
   for(i=0;i<8;i++)
   {
    if(data & 0x80)
         {
             MOSI   = 1;
         }        
         else
         {
             MOSI   = 0;
         }
data<<=1;
         SCK         = 1;
if(speed)
spi_delay();
getByte <<= 0x01;
         if(MISO)
         {
             getByte |= 0x01;
         }
SCK         = 0;
if(speed)
spi_delay();

   }
   return getByte;     
}
你给个5us,也就是200KHZ了,时间要精确点。
回复 支持 反对

使用道具 举报

10

主题

560

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1739
金钱
1739
注册时间
2014-6-27
在线时间
943 小时
发表于 2014-8-1 14:45:24 | 显示全部楼层
初始化的时候,加延时,过后可以不用加了,就是高速了,看你单片机跑得多快了。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 03:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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