打印
[ZLG-ARM]

lpc1343读写SD卡的FAT文件

[复制链接]
4722|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yoyowodeai|  楼主 | 2010-7-19 20:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为了让我的LPC1343同样丰富多彩,端午期间我调试了数字电源的OLED显示部分,目前已经可以显示字符、汉字、图形。

    只是代码写的比较乱,不好意思拿出来见人,等整理好后我会贴在“用LPC1343做一个可调数字电源和可调电子负载”http://bbs.**/thread-107860-1-2.html

    由于MCU的存储资源不多,这让OLED开机显示一些复杂的动画显得十分困难:我的OLED是128*128点阵,一副真彩色画面字节数=128*128*3=48K。显示一副画面的都要48K,更不要说几副连贯的动画。LPC1343只有32K的FLASH,就是不装程序也是一副真彩色画面都装不下。最后我只是装入一副64*64点阵真彩色画面看显示效果,虽然画面小了一点,但是显示效果确实不错。

    今天一早开帖,决定学习好zhaojun_xf的帖子,让LPC1343也能用上SD卡,读写SD卡的FAT文件。

    一:连接电路

   
未命名.JPG (12.15 KB)
2010-6-18 07:06



    SD卡兼容MMC卡,同样支持SPI方式读写。这是LPC1343是主机,SD是从机。

    连接:SSEL  -  P0.2       ---->    SD卡引脚1 CS

              SCK    -  P2.11     ---->    SD卡引脚5 CLK

              MISO  -  P 0.8       ---->   SD卡引脚7  DO (DO是从SD卡的角度)

              MOSI  -  P0.9       ---->    SD卡引脚2  DI (DI是从SD卡的角度)

              +3.3V                   ---->    SD卡引脚4  VDD

              GND                    ---->    SD卡引脚2、6 VSS

    在上一张我以前用的SD卡接线图,图例用的是SD方式,大家只需要参考图的接线编号。


1.JPG (22.97 KB)
2010-6-18 07:09



    电路部分结束,下面开始程序部分。

相关下载

相关帖子

沙发
yoyowodeai|  楼主 | 2010-7-19 20:50 | 只看该作者
上面的电路很简单: 我们所要做的就是找一个SD卡座,按照我提供的SD卡接线图找到那6个脚,对应焊接到开发板即可。



二、代码移植
    zhaojun_xf已经提供了SD的FAT的程序,他用的是LPC1114开发板。LPC1114和LPC1343在C代码里面管脚命名一样,SSP的寄存器的命名也一样。
    1、直接把他提供的源程序里的相关文件直接复制到我们的项目里:SSP.C, SSP.H, SD.C, SD.H,  FF.C, FF.H, DISKIO.C DISKIO.H, APP.C, APP.H, INTEGER.H, FFCONF.H, CONFIG.H, GPIO.C, GPIO.H。
    2、在CONFIG.H文件里找到#include "LPC11xx.h" 改为:#include "LPC13xx.h"。
    3、在我们需要引用的项目文件里(例如我的项目主程序是usbhidrom_main.c)添加#include "app.h"。
    4、试一试修改的程序编译是否通过,根据情况再做修改。我没有碰到什么困难,编译通过了。
    5、以后在项目文件就可以通过调用app.h定义好的那些文件读、写、删除等函数,实现对SD卡的文件的操作。
    6、我这里要实现:读SD卡的BMP文件,然后将图形数据写到OLED屏显示。不需要写到UART串口,所以没有拷贝UART.C, UART.H文件。
    7、对APP.C的读文件函数做修改,读SD卡的BMP文件,然后将图形数据写到OLED屏显示。
       图形都是128*128分辨率的,24位真彩,为*.bmp文件。
       每个*.bmp文件都有BMP文件头,我们只是显示,不需要仔细分析BMP文件头,所以在AppFileRead()里直接略过54字节BMP文件头,逐点读取24位真彩数据写到OLED显示。
/**************************************************************************************
* FunctionName   : AppFileRead()
* Description    : 读取文件
* EntryParameter : fileName - 需要读取的文件名或路径
* ReturnValue    : 成功返回-0;失败返回-1
**************************************************************************************/
uint8_t AppFileRead(const TCHAR *fileName)
{
FATFS fs;               /*Work area (file system object) for logical drive*/
    FIL file;               /*file objects*/
UINT  br,ii=0;               /*File R/W count*/



/*Register a work area for logical drive 0*/
    f_mount(0, &fs);



    /*Create file*/
    if(f_open(&file, fileName, FA_READ))
    {
  return 0;
    }
else
{
  //OLED屏幕写屏方式
  cmd(0x05);
  data(0x02);



  cmd(0x0A);    //指定对OLED全屏幕写屏
  data(0);
  data(0x00); //
  data(7);
  data(0x0f); //15
  data(2);
  data(0x00); //64          //D-IC Change : 128128 IC -> 128160 IC
  data(9);
  data(0x0F); //127
  cmd(0x0C);
  do
  {
   AppClearBuffer(0x00);   // 缓冲清零
   if(f_read(&file, Buffer, BUFFER_SIZE, &br))
   {
    return 0;
   }
   else
   {
    //UARTSendString((const CHAR *)Buffer);  // UART发送读取文件,我们不需要,注释掉
    int i;
    for(i=0;i<br;i=i+3)
    {
     if (ii>=54)    //丢掉我们不需要的BMP文件头,一共54个字节
     {
      data(Buffer[i+2]>>2);  //写到OLED,红色
      data(Buffer[i+1]>>2);  //写到OLED,绿色
      data(Buffer>>2);  //写到OLED,蓝色
     }
     ii+=3;
    }
   }
  } while (br);  // 判断是否读完(br == 0,表示读取完成)



  /*Close all files*/
      f_close(&file);    // 关闭文件,必须和f_open函数成对出现
      //write direction
      cmd(0x05);
        data(0x00);
}



    /*Unregister a work area before discard it*/
    f_mount(0, 0);



    return ii;
}

使用特权

评论回复
板凳
yoyowodeai|  楼主 | 2010-7-19 20:50 | 只看该作者
完成以上修改后,编译、调式通过。
OLED循环显示SD卡里面的BMP图片。
刷新频率:2-3副/秒,不算快。
前面我做了测试:OLED刷屏速度可以轻松达到30副/秒。
所以应该显示BMP图片速度慢应该和SPI接口的读取速度有关。
看看能否进行修改。

使用特权

评论回复
地板
yoyowodeai|  楼主 | 2010-7-19 20:51 | 只看该作者
SPI串行时钟速率由SSP0 Control Register 0 (SSP0CR0 - 0x4004 0000)和SSP0 Clock Prescale Register (SSP0CPSR - 0x4004 0010)决定。

3.JPG (11.5 KB)
2010-6-19 11:02




4.JPG (42.47 KB)
2010-6-19 11:02



    位频率=PCLK / (CPSDVSR × [SCR+1])。

    CPSDVSR 、SCR都是在ssp.c文件的SSPInit函数里设置的:

void SSPInit( void )
{

......  
  /* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
  LPC_SSP->CR0 = 0x0707;

  /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
  LPC_SSP->CPSR = 0x2;

......

  return;
}
    上面CPSDVSR=2,SCR=7,位频率为PCLK的1/16。

    先让SCR=0试一试。CPSDVSR必须为2-254之间的偶数,不用变了。

使用特权

评论回复
5
yoyowodeai|  楼主 | 2010-7-19 20:51 | 只看该作者
呵呵!不好意思,白天没有时间试。
我修改程序为:
/* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
LPC_SSP->CR0 = 0x0007;

也就是让SCR=0,结果SD依然正常工作,而且BMP文件更新速度达到10副/秒左右。十分有效果。
当然我只试过我的SD卡。不排除有些SD卡会读不出来的可能性。

使用特权

评论回复
6
yoyowodeai|  楼主 | 2010-7-19 20:51 | 只看该作者
家里还有一张4G的SD卡,我的数码相机竟然不认。但是插到读卡器上有用,一直当作U盘用。
放在这里竟然被开发板认出来了,能够在开发板的最高速下正常工作。

使用特权

评论回复
7
yoyowodeai|  楼主 | 2010-7-19 20:51 | 只看该作者
偶尔一次,发现SD卡竟然没有工作。



    为了提高可靠性,找到SD高速运行的可靠方法:SPI模式下的初始化过程,设置SPI时钟速率在100KHz~400KHz之间。



    为了优化读/写卡片的性能,SPI总线的时钟速率应该尽可能的快,CSD寄存器中的 TRAN_SPEED 域表明了卡片可以接受的最快时钟速率。



    对于MMC来说,最快时钟速率为20MHz,对于SDC来说,大多数情况下,最快时钟速率则为25MHz。







    根据以上要求,我们在初始化过程将SPI时钟速率设置在:LPC_SSP->CR0 = 0x0707;



    完成初始化后调整到可能的最大值:LPC_SSP->CR0 = 0x0007;



    这下应该万无一失。

使用特权

评论回复
8
yoyowodeai|  楼主 | 2010-7-19 20:54 | 只看该作者
我在SD里面拷贝了几十个*.bmp文件(1.bmp,2.bmp,..........A.bmp, ...................U.bmp),然后再循环读取显示:



char tmpname[6]="1.bmp";



    while



   {



             .................



             AppFileRead(tmpname);



             tmpname[0]=tmpname[0]+1;



            if (tmpname[0]>'U') //是否为"U.bmp"



            {



                            tmpname[0]=0x31; //1.bmp



            }



   }



   显示是循环的,然后用手机的秒表功能记录显示一轮需要多少时间。我拷贝了30个文件循环显示议论需要3秒。

使用特权

评论回复
9
yoyowodeai|  楼主 | 2010-7-19 20:54 | 只看该作者
SSP模式下,P0.10和P0.6还有P2.11都是SSP的SCK,我现在接到P0.10后调试不通。
-------------------------------------------------------------------------------

P0.10还是调试用的SWCLK线,好象调试阶段不能随便占用吧,你不怕到时候lpcxpresso
找不到开发板?

SCK功能除了设置相应IO口,还要设置 IOCON SCK位置寄存器(IOCON_SCKLOC,地址0x4004 40B0)。
其实复位以后是选择管脚PIO0_10为SCK功能(IOCON_SCKLOC=0);
但是lpcxpresso的例程里设置在PIO2_11/SCK(IOCON_SCKLOC=1);
你可以选择管脚PIO0_6/USB_CONNECT/SCK的SCK功能(IOCON_SCKLOC=2)。

使用特权

评论回复
10
ayl439| | 2010-7-20 10:39 | 只看该作者
我想问一下 如果不加入SD卡组织 实际项目中敢用SD卡吗?

不加入SD卡组织 网上找到的都是老版本的资料啊

使用特权

评论回复
11
hotpower| | 2010-11-2 09:56 | 只看该作者
学习

使用特权

评论回复
12
vivisa| | 2010-11-4 15:51 | 只看该作者
帮顶了。

使用特权

评论回复
13
bairan168| | 2010-11-4 16:27 | 只看该作者
学习

使用特权

评论回复
14
coco11| | 2010-12-30 14:29 | 只看该作者
学习了。

使用特权

评论回复
15
-自己人| | 2011-1-1 15:14 | 只看该作者
学习

使用特权

评论回复
16
hotpower| | 2011-1-2 01:50 | 只看该作者
农会发放棉裤一条

使用特权

评论回复
17
amini| | 2011-1-6 17:01 | 只看该作者
终于看完了。回个贴吧。

使用特权

评论回复
18
vivisa| | 2011-1-6 17:25 | 只看该作者
看累了。顶。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

191

主题

1265

帖子

2

粉丝