MSP430的SPI通信例程(SD卡初始化-理论解说)

发布者:老实巴交的大叔最新更新时间:2018-05-05 来源: eefocus关键字:MSP430  SPI通信  SD卡初始化 手机看文章 扫描二维码
随时随地手机看文章

最近需要做一个数据存储,发现SD卡这一块还不太好弄 
现在的单片机有相当一部分还不支持SDIO,比如MSP430(据我所知,如果有支持的型号了还请及时告诉我~),所以只好用SPI通信来进行SD卡的操作,虽然后续涉及到更为复杂的FAT等等,但是首先需要解决的仍然是建立通信的问题。

采用的单片机型号为MSP430F5438A,用了一个开发板。

SPI通信基本例程

例程及解释如下:

//===========================================================================//

//                                                                           //

// 文件:  MAIN.C                                                            //

// 说明:  BW-DK5438开发板单片机SPI端口实验程序                              //

//         设置SPI端口工作模式,通过SPI端口发送数据                          //

//         可在P3.1/P3.3端口观察数据、时钟波形                               //

// 编译:  IAR Embedded Workbench IDE for MSP430 v4.21                       //

// 版本:  v1.1                                                              //

// 编写:  JASON.ZHANG                                                       //

// 版权:  北京拓普博维电子技术有限公司                                      //

//                                                                           //

//===========================================================================//


#include "msp430x54x.h"

#include

#include

#include

#include "PIN_DEF.H"


#define  FLL_FACTOR     649                                 // FLL_FACTOR: DCO倍频系数    

char  event, RXBuffer[2]                                  ;



//***************************************************************************//

//                                                                           //

//                 初始化主时钟: MCLK = XT1×(FLL_FACTOR+1)                  //

// 主时钟这部分来说,应该没有什么额外的问题

//                                                                           //

//***************************************************************************//

void Init_CLK(void)

{

  WDTCTL     = WDTPW + WDTHOLD                            ; // 关看门狗

  P7SEL     |= 0x03                                       ; // 端口选择外部低频晶振XT1(32.768kHz)

  UCSCTL6   &=~XT1OFF                                     ; // 使能外部晶振 

  UCSCTL6   |= XCAP_3                                     ; // 设置内部负载电容

  UCSCTL3   |= SELREF_2                                   ; // DCOref = REFO

  UCSCTL4   |= SELA_0                                     ; // ACLK   = XT1  

  __bis_SR_register(SCG0)                                 ; // 关闭FLL控制回路

  UCSCTL0    = 0x0000                                     ; // 设置DCOx, MODx

  UCSCTL1    = DCORSEL_7                                  ; // 设置DCO振荡范围

  UCSCTL2    = FLLD__1 + FLL_FACTOR                       ; // Fdco = ( FLL_FACTOR + 1)×FLLRef = (649 + 1) * 32768 = 21.2992MHz

  __bic_SR_register(SCG0)                                 ; // 打开FLL控制回路                                                            

  __delay_cycles(1024000)                                 ; 

  do

  {

    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // 清除 XT2,XT1,DCO 错误标志                                                            

    SFRIFG1 &= ~OFIFG                                     ; 

  }while(SFRIFG1&OFIFG)                                   ; // 检测振荡器错误标志 

}


//***************************************************************************//

//                                                                           //

//  Init_Port(void): 设置IO端口                                              //

//                                                                           //

//***************************************************************************//

void Init_Port(void)

{

  P5DIR  |= POWER                                         ; // 主电源

  MAIN_POWER_ON                                           ;

  P7DIR  |= LED_PWR                                       ; // 发光二极管电源

  P7OUT  &=~LED_PWR                                       ;

  INTERNAL_PULL_UP                                        ; // 使能键盘端口内部上拉电阻 

  ROW_IN_COL_OUT                                          ; // 设置行输入,列输出0

}


//***************************************************************************//

//                                                                           //

//  Init_SPI(void): 设置SPI端口                                              //

//                                                                           //

//***************************************************************************//

void Init_SPI(void)

{  


//这里对P8的操作很奇怪,似乎并不需要

  P8OUT    |= LCD_NCS                                     ; // SPI端口复用,DisableTFT液晶端口

  P8DIR    |= LCD_NCS                                     ;


//P3的1,2,3是一个SPI端口

  P3OUT    |= NCS25                                       ; 

  P3DIR    |= NCS25                                       ;

  P3SEL    &= 0xF0                                        ;

  P3SEL    |= 0x0E                                        ; // // P3.1/2/3功能选择为SPI


  UCB0CTL1 |= UCSWRST                                     ; // 复位SPI状态机


  UCB0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB                   ; // 3-pin, 8-bit SPI master, Clock polarity high, MSB


  UCB0CTL1 |= UCSSEL_2                                    ; // 选择SCK参考源为SMCLK


  UCB0BR1   = 0                                           ; 

  UCB0CTL1 &=~UCSWRST                                     ; // SPI状态机使能

}



void main( void )

{

  WDTCTL = WDTPW + WDTHOLD                                ;

  Init_CLK()                                              ;

  Init_Port()                                             ;

  Init_SPI()                                              ;

  for(;;)

  {

     UCB0TXBUF = 0x55                                     ; 

     __delay_cycles(280)                                  ; 

  }

}

鉴于CSDN的Markdown代码高亮做的实在是……唉,这里贴一个容易看的吧: 
SPI通信代码

SD卡通信方式

以上是给出的例程,SD卡有自己的一套通信方法: 
这里引述了:

http://elm-chan.org/docs/mmc/mmc_e.html

当中的内容并予以节选翻译,以便日后查找方面。

SD卡和MMC卡接口

MMC卡和SD卡先后推出,接口可以说基本差不多,供电是2.7~3.6V,不要供5V点,否则按照原文说法是“马上坏”(@_@)

SD卡和单片机的电气连接方式如下图 
电气连接方式 
其中有一个上拉电阻有点令人费解

SPI通信模式共有0~3四种,他们的区别是时钟相位和极性。适用于MMC和SD的模式是mode 0(CPHA=0,CPOL=0),但是mode 3多数情况下也管用

SD卡初始化

下面的流程是整个初始化的步骤: 
为了避免翻译出现差错,这里也附上英文原文。

上电或卡刚插入时 
当供电电压达到2.7V以上时,至少等待1ms,将SPI时钟信号的频率设置在100kHz~400kHz之间,并设置DI和CS(片选信号)为高,并向SCLK输入74个以上时钟脉冲,内存卡将会进入到其默认操作模式并做好接收指令准备

软件复位 
保持CS(片选信号)为低电平的情况下,发送一个CMD0指令(就是reset指令,完整指令集的解释附于文后)。SD卡将会在CMD0指令接收之后采样CS信号,如果CS信号为低电平,SD卡将会进入SPI模式,并回复0x01。由于CMD0必须作为:“原生指令”(Native Command)发送,所以CRC部分必须有一个有效(valid)的值(译者注:原生指令中,CRC是固定格式中的一个部分,这里的有效指的是占位还是必须要校验计算不清楚,还要再次确认,这里,CRC作为一个校验位应该和串口的奇偶校验差不多,是只需要选择控制位就可以的,并不需要单独编程计算)。一旦SD卡进入SPI模式之后,这个CRC部分将不再被使用,也不会再被检查。所以,命令中的CRC可以相对固定,但是这个固定值要能够在发送CMD0 和 CMD8 这两个命令(命令参数argument为0的情况下)时保证正确(CMD0的正确CRC,在argument为0的时候是0x95,CMD8待查)。 
另外CRC这个特征也可以使用CMD59进行切换,(切换什么和怎样切换没有详细交代)。

补充说明:CMD8命令的稍微详细一些的介绍可以参看: 
百度文库

Power ON or card insersion 
After supply voltage reached 2.2 volts, wait for one millisecond at least. Set SPI clock rate between 100 kHz and 400 kHz. Set DI and CS high and apply 74 or more clock pulses to SCLK. The card will enter its native operating mode and go ready to accept native command.

Software reset 
Send a CMD0 with CS low to reset the card. The card samples CS signal on a CMD0 is received successfully. If the CS signal is low, the card enters SPI mode and responds R1 with In Idle State bit (0x01). Since the CMD0 must be sent as a native command, the CRC field must have a valid value. When once the card enters SPI mode, the CRC feature is disabled and the CRC is not checked by the card, so that command transmission routine can be written with the hardcorded CRC value that valid for only CMD0 and CMD8 with the argument of zero. The CRC feature can also be switched with CMD59.

初始化 
SD卡在空闲状态下,只接受CMD0,CMD1,ACMD41,CMD58以及CMD59这几个指令,而拒绝其它任何指令。这是,读取OCR寄存器并检查卡片的工作电压范围(似乎通过CMD58进行查询),如果供电超出范围要弹出SD卡。 
卡片在接收到CMD1命令时启动初始化流程,主控芯片需要持续发送CMD1并检测回复以确定初始化过程完成。R1回复从0x01变为0x00(Idle State bit 清零)时,意味着初始化成功。初始化过程可能需要数百ms(卡片存储空间越大时间越长),所以需要考虑一个判定超时的阈值。 
Idle State bit 清零之后,一般的读写命令就可以执行了。此外因为在对SDC进行操作时,ACMD41被推荐代替CMD1,所以首先尝试发送ACMD41,被拒绝之后再试CMD1,这样的一个流程在理想状况下应该能够适应所有的两种卡。

Initialization 
In idle state, the card accepts only CMD0, CMD1, ACMD41,CMD58 and CMD59. Any other commands will be rejected. In this time, read OCR register and check working voltage range of the card. In case of the system sypply voltage is out of working voltage range, the card must be rejected. Note that all cards work at supply voltage range of 2.7 to 3.6 volts at least, so that the host contoller needs not check the OCR if supply voltage is in this range. The card initiates the initialization process when a CMD1 is received. To detect end of the initialization process, the host controller must send CMD1 and check the response until end of the initialization. When the card is initialized successfuly, In Idle State bit in the R1 response is cleared (R1 resp changes 0x01 to 0x00). The initialization process can take hundreds of milliseconds (large cards tend to longer), so that this is a consideration to determin the time out value. After the In Idle State bit cleared, generic read/write commands will able to be accepted. 
Because ACMD41 instead of CMD1 is recommended for SDC, trying ACMD41 first and retry with CMD1 if rejected, is ideal to support both type of the cards.

SCLK频率应该设置的尽可能快,这样可以使得读写的表现更好(应该是速度更快吧)。CSD寄存器中的TRAN_SPEED区域标明了卡片的最大时钟频率。大部分情况下,MMC为20MHz,SDC则为25MHz。注意时钟频率可以是在这两个值之间的值,没有中间出现开集的其它限制。 
在2GB卡上,初始的读写 block length可能是1024,所以block size应该被重新初始化到512(使用CMD16命令)以配合FAT文件系统的工作。

The SCLK rate should be changed to fast as possible to maximize the read/write performance. The TRAN_SPEED field in the CSD register indicates the maximum clock rate of the card. The maximum clock rate is 20MHz for MMC, 25MHz for SDC in most case. Note that the clock rate will able to be fixed to 20/25MHz in SPI mode because there is no open-drain condition that restricts the clock rate. 
The initial read/write block length can be set 1024 on 2GB cards, so that the block size should be re-initialized to 512 with CMD16 to work with FAT file system.

初始化 high-capacity cards (不知道高级在什么地方) 
在发送给卡片一个CMD0指令使其进入空闲模式后,在初始化之前发送一个CMD8(语句为0x000001AA,需要有正确的校验位CRC)。如果CMD8被拒绝(表现是会回复一个命令错误提示0x05),那么这个卡片是一个SDC一代卡或者MMC三代卡。如果命令被接受,会收到一个R7回复(R1(0x10)+32位返回值)。这个32位返回值的低12位意味着这个卡是一个SDC二代卡。(接着又絮叨了一遍电压范围的事儿,似乎没什么意义)。在确认之后,启动初始化:利用带HCS flag(bit30)的ACMD41命令。后面似乎讲的是如果这个bit 30 被置位,则这个卡就是众所周知的SDHC/SDXC卡(但是it is set当中的这个it指的是什么还是有些拿不准)。以下描述的数据读取/写入操作是按照block寻址的而非按照byte寻址。数据block大小固定在512bytes。

Initializing high-capacity cards 
After the card enters idle state with a CMD0, send a CMD8 with argument of 0x000001AA and correct CRC prior to initialization process. If the CMD8 is rejected with illigal command error (0x05), the card is SDC version 1 or MMC version 3. If accepted, R7 response (R1(0x01) + 32-bit return value) will be returned. The lower 12 bits in the return value 0x1AA means that the card is SDC version 2 and it can work at voltage range of 2.7 to 3.6 volts. If not the case, the card should be rejected. And then initiate initialization with ACMD41 with HCS flag (bit 30). After the initialization completed, read OCR register with CMD58 and check CCS flag (bit 30). When it is set, the card is a high-capacity card known as SDHC/SDXC. The data read/write operations described below are commanded in block addressing insted of byte addressing. The size of data block at block addressing mode is fixed to 512 bytes


关键字:MSP430  SPI通信  SD卡初始化 引用地址:MSP430的SPI通信例程(SD卡初始化-理论解说)

上一篇:MSP430 SPI驱动 代码设计流程
下一篇:MSP430 SPI硬件接口

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

MSP430单片机指令周期小谈
MSP430的时钟周期(振荡周期)、机器周期、指令周期之间的关系 时钟周期也称为振荡周期:定义为时钟脉冲的倒数(时钟周期便是直接供内部CPU 使用 的晶振的倒数 , 例如12M的晶振 , 它的时钟周期便是1/12us) , 是 电脑 中的最基本的、最小的时间单位 。 在一个时钟周期内 , CPU仅完成一个最基本的动作 。 时钟脉冲是电脑的基本工作脉冲 , 控制着电脑的工作节奏 。 时钟频率越高 , 工作速度就越快 。 机器周期:在电脑中 , 常把一条指令的执行过程划分为若干个阶段 , 每一个阶段完成一项工作 。 每一项工作称为一个基本操作 , 完成一个基本操作所需要的时间称为机器周期 。 8051系列单片机的一个机器周期由6个
[单片机]
MSP430F5438A中断问题
写一个简单程序进入中断,首先进入中断的条件: 1.时钟源配置好 2.中断的寄存器配置好 3.中断向量表配置好 以上三点都配置好是不是就应该进入中断了?帮忙看看下面的程序进不去中断,我用的是捕获模式,捕获引脚1.4有捕获信号。 #include “msp430.h” void Init_MCLK(void); int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P5DIR |= BIT4; P5OUT |= BIT4; Init_MCLK(); P1DIR &= ~BIT4;
[单片机]
msp430入门学习04
1)、为什么学习MSP430   MSP430是冯-诺伊曼体系结构,地址空间是与特殊功能寄存器(SFRs)、外围设备、RAM和Flash/ROM内存共享,代码访问总是在偶数地址上执行。数据可以以字节或字的形式访问。内存映射如下: 1、   闪存/ROM的起始地址取决于闪存/ROM的数量,并因设备而异。闪存/ROM的最终地址是0FFFFH。闪存既可用于存储代码,也可用于数据。   可以在Flash/ROM中存储和使用Word或字节表,而无需在使用它们之前将表复制到RAM中。   中断向量表被映射到Flash/ROM地址空间的16个单词的上方,最高优先级的中断向量位于最高位置 Flash/ROM单词地址(0FFFEh)。
[单片机]
<font color='red'>msp430</font>入门学习04
基于MSP430F135与DSl8820芯片设计煤矿瓦斯浓度无线监测系统
引言 煤炭作为一种重要的能源,在工业生产等许多方面发挥着举足轻重的作用,关系着国民经济的命脉。煤炭开采中的安全问题一直是受到极大重视的。如果一旦出现安全问题,不仅会造成巨大的经济损失,而且直接威胁到煤炭工人的生命安全。近年来,我国煤炭开采的安全问题形势不容乐观,各地矿难时有发生,特别是一些小煤矿更存在着严重的安全隐患。所以,采取现代安全监测措施势在必行。 随着科学技术的不断进步,煤炭开采中安全监测的现代化步伐也在不断前进。煤矿安全监测的参数有很多,其中瓦斯浓度是个很重要的参数.如果浓度过大,容易造成爆炸危险,后果不堪设想,同样温度也是一个很重要的参数。 很多系统采用有线传输的方式,但存在着布线困难,价格昂贵的缺点。基于以上
[单片机]
基于<font color='red'>MSP430</font>F135与DSl8820芯片设计煤矿瓦斯浓度无线监测系统
20引脚的MSP430G2553引脚功能表
  德州仪器 (TI) MSP430 系列超低功耗微控制器包含多种器件,它们特有面向多种应用的不同外设集。 这种架构与 5 种低功耗模式相组合,专为在便携式测量应用中延长电池使用寿命而优化。 该器件具有一个强大的 16 位 RISC CPU,16 位寄存器和有助于获得最大编码效率的常数发生器。 数字控制振荡器 (DCO) 可在不到 1µs 的时间里完成从低功耗模式至运行模式的唤醒。   MSP430G2x13 和 MSP430G2x53 系列是超低功耗混合信号微控制器,具有内置的 16 位定时器、多达 24 个支持触摸感测的 I/O 引脚、一个多用途模拟比较器以及采用通用串行通信接口的内置通信能力。 此外,MSP430G2x5
[单片机]
20引脚的<font color='red'>MSP430</font>G2553引脚功能表
基于MSP430单片机和CH376USB接口的信号采集存储系统
在现代控制系统中,经常需要在操作现场进行数据采集,以及对数据进行处理来实现现场控制,但是由于单片机数据存贮容量和数据处理能力都较低,因此本文主要介绍了使用USB总线通用接口芯片CH376和16位单片机MSP430对天线发射的信号进行数据采集处理,并且能够将这些大容量的数据以.txt文本格式实时的存储到U盘中,然后能在上位机上方便的打开查看和应用。这样就可以很容易的实现把单片机所采集的数据传送到PC机上,再在PC机上进行数据处理,充分发挥两者各自优势。 本文首先要设计出天线方向图的自动测试系统。通过这个天线参数自动化测量系统准确地发送和接收信号,从而进行数据的采集处理和存储等。早期的天线测试主要依靠手工,误差大、效率低。随着计算机
[单片机]
基于<font color='red'>MSP430</font>单片机和CH376USB接口的信号采集存储系统
三分钟带你了解MSP430F249硬件I2C查询法读写AT24C02
/****************************************************************** ** ** File : I2C.c “ Master Read Write | ** Version : 1.0 ** DescripTIon: I2C 查询法读写24C02 ** Author : LightWu ** Date : 2013-4-26 ** 必须注意多字节数据读取时,发送停止位需要在最后一个字节读取之前 ** 否则数据读取后,停止位发送容易失败,导致从机接收不到停止位。 *****************************************************
[单片机]
三分钟带你了解<font color='red'>MSP430</font>F249硬件I2C查询法读写AT24C02
MSP430系列单片机的复位电路系统设计
  0 引言   TI公司的混合信号处理器MSP430系列单片机以其处理能力强大、外围器件集成度高、功率消耗低、产品系列全面、全系列工业级等特点,作为目前MCU主流市场的产品之一,在电子应用领域中得到广泛应用,被越来越多的电子设计师所青睐。由于复位电路设计问题而导致的系统出现上电后不工作或状态不正确是很多MSP430单片机电路设计者们在设计、调试和应用中曾遇到过的问题,尽管这种情况发生的几率很低,但对于可靠性要求较高的应用场合,这个现象仍需引起电子设计人员的足够重视。   为此,本文对MSP430全系列单片机的复位系统和复位机制进行了详细深入的分析,并针对性地提出了具体的外围复位电路设计方案和有关电子元器件的详细介绍,以供同行
[单片机]
<font color='red'>MSP430</font>系列单片机的复位电路系统设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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