基于ARM含SD控制器的SD卡的SDIO模式驱动解析

发布者:北极星小鹏最新更新时间:2016-08-06 来源: eefocus关键字:ARM  SD控制器  SDIO模式 手机看文章 扫描二维码
随时随地手机看文章
SD卡由日本松下东芝及美国SanDisk公司于1999年8月共同开发研制。

SD卡的结构能保证数字文件传送的安全性,也很容易重新格式化,因此越来越多的被应用的嵌入式系统中。

SD卡的使用非常方便,常见的有两种工作模式:SPI和SDIO。SPI是串行的工作模式,速度相对较低,但是使用方便,只要MCU含有SPI接口均可使用。SDIO模式,可以最多4线传输,因此速度比较快,由于SD卡的普及,越来越多的MCU内部集成了SDIO控制器,简化了我们的工作。本文以三星s3c2410为例介绍。

 

1.    SD卡的接口电路

 

 

基于ARM含SD控制器的SD卡的SDIO模式驱动解析 - 梧桐雨 - 梧桐雨的博客

2.    SD卡的协议

SD卡的控制指令非常强大,支持SPI,SDIO模式,兼容MMC等。而且不同的

指令有不同的响应(3种),这在我们使用指令是要注意的。我在附件里面放了一个SD卡的中文协议,包括数据包介绍,指令索引介绍,反馈介绍等。

 

3.    S3C2410 SD卡控制器的介绍

SD卡控制器帮我们完成了协议上的很多工作,我们只需要按照协议配置寄存器

以及按照协议流程对SD卡操作就可以完成SD卡的功能了。

   SDICON:完成SD卡基础配置,包括大小端,中断允许,模式选择,时钟使能等。

   SDIPRE:对SDCLK的配置。

   SDICARG:指令的参数存放在这里

   SDICCON:控制指令形式的寄存器,配置SPI还是SDI指令,指令的反馈长度,是否等待反馈,是否运行指令,指令的索引等

   SDICSTA:指令状态寄存器,指令是否超时,传送,结束,CRC是否正确等

   SDIRSPO:反映SD的状态

   SDITIMER:设置超时时间

   SDIBSIZE:block的大小

   SDIDCON:数据控制寄存器,配置是几线传输,数据发送方向,数据传送方式等。

   SDIDSTA: 数据状态寄存器,数据是否发送完,CRC效验,超时等

   SDIFSTA: FIFO状态积存器,DMA传输时否判断FIFO

   SDIMSK:中断屏蔽

 

4.    SD卡SDIO模式的驱动分析

4.1 SD卡的初始化

步骤是:1)配置时钟,慢速一般为400K,设置工作模式

        2)发送CMD0,进入空闲态,该指令没有反馈

        3)发送CMD55+ACMD41,判断SD卡的上电是否正确,短反馈

        4)发送CMD2,验证SD卡是否接入,长反馈

        5)发送CMD3,读取SD卡的RCA(地址),短反馈

        6)发送CMD7,使能SD卡

        7)配置高速时钟,准备数据传输,一般20M~25M

        8)发送CMD55+ACMD6配置为4bit数据传输模式

 

代码如下:

int SD_card_init(void)

{

    int i;

    char key;

    rSDIPRE=PCLK/(2*INICLK)-1;        //时钟 400KHz

    rSDICON=(1<<4)|(1<<1)|1;               // Type B, FIFO reset, clk enable

    rSDIBSIZE=0x200;                    // 512byte(128word)

    rSDIDTIMER=0xffff;                        // Set timeout count

 

    for(i=0;i<0x1000;i++);                // Wait 74SDCLK for MMC card

 

    CMD0();                           //进入idle

                                      //-- Check SD card OCR

    if(Chk_SD_OCR())                  //发送AM41,判断电压正确否

        ;

    else

    {

      ;

        return 0;

    }

 

RECMD2:

rSDICARG=0x0;                     

 // CMD2(stuff bit),判断连接

rSDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; 

//lng_resp, wait_resp, start, CMD2

    //-- Check end of CMD2

if(!Chk_CMDend(2, 1))                //查询反馈是否正确

 

goto RECMD2;

   

RECMD3:

    //--Send RCA,得到SD卡的地址

rSDICARG=MMC<<16;                        

// CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ)

rSDICCON=(0x1<<9)|(0x1<<8)|0x43;          

// sht_resp, wait_resp, start, CMD3

 

    //-- Check end of CMD3

    if(!Chk_CMDend(3, 1))

goto RECMD3;

    //--Publish RCA

   

RCA=( rSDIRSP0 & 0xffff0000 )>>16;

   

    //--State(stand-by) check

if( rSDIRSP0 & 0x1e00!=0x600 )           

  // CURRENT_STATE check  验证反馈

goto RECMD3;

  

   

rSDIPRE=PCLK/(2*NORCLK)-1;                    

// 设置高速时钟Normal clock="25MHz"

    Card_sel_desel(1);              // Select SD

   Set_4bit_bus();             //设置为4bit模式

}

 

void Set_4bit_bus(void)

{

    Wide=1;

    SetBus();

}

void SetBus(void)

{

SET_BUS:

    CMD55();                                        

// Make ACMD

    //-- CMD6 implement

    rSDICARG=Wide<<1;                         

      //Wide 0: 1bit, 1: 4bit

    rSDICCON=(0x1<<9)|(0x1<<8)|0x46;             

   //sht_resp, wait_resp, start, CMD55

    if(!Chk_CMDend(6, 1))                   // ACMD6

     goto SET_BUS;

   

}

 

4.2SD卡的读与写

读写就是正反向的问题,这里只分析读

步骤:1)读单block CMD17 多block CMD18

       (写单block CMD24 多block CMD25)

      2)发送CMD12,终止数据传输

 

程序如下:采用DMA模式

void Rd_Block(void)

{

    int status;

    rd_cnt=0;   

    rSDICON |= rSDICON|(1<<1);          // FIFO reset

    rSDICARG=0x0;                      // CMD17/18(addr参数)

RERDCMD:

          pISR_DMA0=(unsigned)DMA_end;   //DMA的相关配置

          rINTMSK = ~(BIT_DMA0);

          rDISRC0=(int)(SDIDAT);               // SDIDAT

          rDISRCC0=(1<<1)+(1<<0);             // APB, fix

          rDIDST0=(U32)(Rx_buffer);            // Rx_buffer

          rDIDSTC0=(0<<1)+(0<<0);              // AHB, inc

          rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;

  //handshake, sync PCLK, TC int, single tx, single service, SDI, H/W request,

//auto-reload off, word, 128blk*num

          rDMASKTRIG0=(0<<2)+(1<<1)+0;                  

//no-stop, DMA2 channel on, no-sw trigger

 

          rSDIDCON=(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(2<<12)|(block<<0);

            // Rx after rsp, blk, 4bit bus, dma enable, Rx start, blk num

          if(block<2)                                          // SINGLE_READ

          {

           rSDICCON=(0x1<<9)|(0x1<<8)|0x51;      

          // sht_resp, wait_resp, dat, start, CMD17

           if(!Chk_CMDend(17, 1))                        

     //-- Check end of CMD17

               goto RERDCMD;      

          }

          else                           // MULTI_READ

          {

           rSDICCON=(0x1<<9)|(0x1<<8)|0x52;              

  // sht_resp, wait_resp, dat, start, CMD18

           if(!Chk_CMDend(18, 1))                           

      //-- Check end of CMD18

               goto RERDCMD;

          }

          while(!TR_end);

           rINTMSK |= (BIT_DMA0);

          TR_end=0;

          rDMASKTRIG0=(1<<2);                 //DMA0 stop

          break;

      default:

          break;

    }

    //-- Check end of DATA

    if(!Chk_DATend())

      ;

    rSDIDSTA=0x10;                     // Clear data Tx/Rx end

 

    if(block>1)

    {

RERCMD12:   

      //--Stop cmd(CMD12)

      rSDICARG=0x0;                           //CMD12(stuff bit)

      rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;          

  //sht_resp, wait_resp, start, CMD12

      //-- Check end of CMD12

      if(!Chk_CMDend(12, 1))

          goto RERCMD12;

          }

}

 

4.3上面用到的响应判断函数

 

主要完成对反馈状态的分析。

函数如下:

 

int Chk_CMDend(int cmd, int be_resp)         //指令反馈判断函数

{

    int finish0;

    if(!be_resp)                              // No response

    {

        finish0=rSDICSTA;

      while((finish0&0x800)!=0x800)             // 验证指令是不是发送

          finish0=rSDICSTA;

      rSDICSTA=finish0;                        // Clear cmd end state

      return 1;

    }

    else                                     // With response

    {

        finish0=rSDICSTA;

  while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) ))       

   // 验证反馈响应完成

            finish0=rSDICSTA;

 

      if(cmd==1 | cmd==9 | cmd==41)                 // CRC no check

      {

          if( (finish0&0xf00) != 0xa00 )            // CRC是否错误

          {

           rSDICSTA=finish0;                    // Clear error state

 

           if(((finish0&0x400)==0x400))          // 验证超时

 

               return 0;                                 }

          rSDICSTA=finish0;                        

 // Clear cmd & rsp end state

      }

      else                                        // CRC check

      {

          if( (finish0&0x1f00) != 0xa00 )            // Check error

          {

           ;

           rSDICSTA=finish0;                   // Clear error state

 

           if(((finish0&0x400)==0x400))

               return 0;                        // Timeout error

            }

          rSDICSTA=finish0;

      }

      return 1;

    }

}

 

int Chk_DATend(void)

{

    int finish;

 

    finish=rSDIDSTA;

    while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) ))    

                                                      // Chek timeout or data end

      finish=rSDIDSTA;

 

    if( (finish&0xfc) != 0x10 )

    {

       

        rSDIDSTA=0xec;                              // Clear error state

        return 0;

    }

    return 1;

}

 

int Chk_BUSYend(void)              //数据反馈判断函数

{

    int finish;

    finish=rSDIDSTA;

    while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))

      finish=rSDIDSTA;             //等待数据发送完成或超时

 

    if( (finish&0xfc) != 0x08 )

    {

        rSD

IDSTA=0xf4;         //clear error state

        return 0;

    }

    return 1;

}

关键字:ARM  SD控制器  SDIO模式 引用地址:基于ARM含SD控制器的SD卡的SDIO模式驱动解析

上一篇:S3C44B0的UART波特率计算公式---分频设置
下一篇:ARM指令学习笔记

推荐阅读最新更新时间:2024-03-16 15:03

arm中R0-R15寄存器的作用
根据 ARM-thumb 过程调用标准 : r0-r3 用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。 被调用函数在返回之前不必恢复 r0-r3。如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。 r4-r11 被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。 r12 是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。 在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复 r12。 13 是栈指针 sp。它不能用于任何其它用途。
[单片机]
放眼Apple与Intel的未来,相爱还是相杀?
2011年时就有分析人士指出,很快Mac会采用 Apple 设计的ARM芯片。在经历从PowerPC芯片转到英特尔的成功后, Apple 也会做出类似的转变,这次是转向A4后以ARM为基础的芯片,并由 Apple 设计, Samsung 加工。 高端的15寸MacBook Pro上i7芯片售价378美元,低端上的i7价格估计约300美元。如果 Apple 用ARM芯片,成本会大大降低。ARM处理器构造更为简洁,造价成本较低。由于流动设备市场的激烈竞争,价格拉得越来越低,而且在流动市场Wintel那一套不适用。   成本是首因,但能耗很重要 新格局需要新的拓展,但由于微软的反向兼容性,因此保留原有的东西很有必要(这
[单片机]
基于ARM的某机载电台检测控制器的设计
   机载电台 担负着空空和地空之间通信,为保证电台性能,需要对其进行定检。基于单片机的检测仪存在测量速度慢、可扩展性差的问题;而基于PXI仪器或VXI仪器的检测仪存在着功耗大、体积大、价格高等缺点。为解决上述问题,利用基于 ARM 处理器来实现电台检测控制器成为重要的发展方向,ARM是一种高性能、低功耗的RISC结构处理器,由于其出色的性能被广泛应用于 工业控制 、无线通讯、成像和安全、网络应用等方面,采用基于ARM的电台检测控制器具有可移植性强、可扩展性好、抗干扰能力强等优点。 1 硬件设计   良好的硬件设计是是解决基于单片机、PXI、VXI等系统的电台检测仪问题的关键。为实现硬件结构的模块化设计,硬件主要分为两大部分
[安防电子]
基于<font color='red'>ARM</font>的某机载电台检测<font color='red'>控制器</font>的设计
MarS Board- 你不知道的ARM DIY 计算机平台
随着Raspberry Pi的火热,各种卡片式电脑如雨后春笋的出现,CPU由AM11架构到Cortex-A8再到Cortex-A9架构,单核到多核,系统覆盖Linux、Ubuntu、Android,客户创意越来越多,需求越来越高。在这种环境下,超级ARM DIY计算机平台MarS Board应运而生。   MarS Board是深圳市英蓓特科技有限公司推出的基于飞思卡尔(Freescale Semiconductor)i.MX 6Dual处理器的超级ARM DIY计算机平台。i.MX 6Dual处理器集成了高达1GHz的 ARM Cortex™-A9 内核、2D和3D图形处理器和3D 1080p视频处理器。MarS Board具
[模拟电子]
MarS Board- 你不知道的<font color='red'>ARM</font> DIY 计算机平台
基于ARM的中英文翻译器设计
  为了改进某焊接设备只能输出打印英文单据的情况,设计了由高性能ARM7控制器——LPC2214为核心的英文转中文翻译器,详细论述了具体的硬件电路和优化的软件算法的设计原理,实验结果表明,翻译器对输入的英文数据量的大小无任何限制,能够显著降低系统硬件资源需求且能大大提升打印速度。大体概念外观如下图所示。   基于某焊接设备存储大量数据需要通过打印机输出,但由于该设备及其配套的微型热敏打印机只能英文打印,不能中文打印的问题,从而影响用户阅读。另外,原有的配套英文打印机具有打印速度缓慢、每一组数据间隔过大,浪费纸张等缺点。因此,为了解决上述问题,根据实际工程项目应用需要,提出一种基于ARM的英文转中文的翻译器设计方案,该设计是在原
[单片机]
基于<font color='red'>ARM</font>的中英文翻译器设计
ARM的未来低功耗系统设计发展之路
每一名系统设计人员都理解功耗和性能的相对关系:您的应用需要的计算性能越高,设计的功耗也就越高。但是,新一类应用对这一规则发出了挑战。智能电话设计人员希望同时实现PC级峰值应用速率以及更长的电池使用寿命。嵌入式系统规划采用智能传感器以满足严格的数据分析要求,安全的连接互联网,但是要求最大限度的降低功耗。在传统的思路中,这些明显是无法实现的。但是,ARM工程师在6月份设计自动化大会(DAC)上的发言表明,CPU知识产权(IP)带头企业的发展方向却是将这些不可能变为可能。 当然,ARM从开始出现便一直专用于低功耗计算。在其DAC主题发言中,ARM创始人之一Mike Muller从小剑桥计算机业余爱好供应商Acorn Compute
[模拟电子]
<font color='red'>ARM</font>的未来低功耗系统设计发展之路
便携式多点温度同步采集系统设计
0 引言     目前在工业控制及野外勘测等领域经常需要同步测量不同地点的温度参数,并进行长时间记录,完成后将时间同步的温度数据载入计算机进行分析。但实现精度较高的时间同步一般采用有线同步技术,这样就非常不便于应用。因此设计一种便携式的、基于无线同步技术的多点温度同步采集与存储系统就显得尤为重要。本文给出了基于STM32F103VC微控制器和无线同步技术相结合的温度采集系统,能够根据事先设定好的模式对温度参数进行采集,并将同步时间及温度数据存入SD卡进行长期存储。系统采用电池供电,特别适合不便于取市电的应用场合。 1 硬件组成及原理     置于不同位置的温度采集系统硬件结构上完全相同,只是不同系统有唯一的ID号,ID号可人为设置。
[单片机]
ARM7与FPGA相结合的应用
  ARM7与FPGA相结合在工业控制和故障检测中的应用   工业控制中往往需要完成多通道故障检测及多通道命令控制(这种多任务设置非常普遍),单独的CPU芯片由于其外部控制接口数量有限而难以直接完成多路检控任务,故利用ARM芯片与FPGA相结合来扩展检控通道是一个非常好的选择。这里介绍用Atmel公司ARM7处理器(AT91FR40162)和ALTERA公司的低成本FPGA芯片(cyclone2)结合使用完成多通道检控任务的一种实现方法。    各部分功能简介   图1为此系统的结构连接框图。如图所示,ARM芯片与FPGA芯片之间通过数据总线、地址总线及读写控制线相连,而与终端PC则通过串口通信;FPGA与目标设备通过命令控
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved