主题中讨论的其他器件:CSD、 MSP430F169、 MSP430F149
我正在尝试初始化 SD 卡、以便我可以向其写入一些可以在以后读取的数据。 我不需要任何特殊的文件系统、因为我只向卡写入无符号字符。 我附上以下相关代码:
头文件定义:
#define CS (P3DIR |= BIT1)//将 CS 设置为输出
#define CS_H (P3OUT |= BIT1)//将 CS 设置为非活动(低电平有效)
#define CS_L (P3OUT |=~BIT1)//将 CS 设置为有效(低电平有效)
#define TX UCA1TXBUF //Tx 缓冲器
#define RX UCA1RXBUF //Rx 缓冲器
#define TX_READY (UCA1IFG & 0x0002)//忙时为0,就绪时为1
#define RX_READY (UCA1IFG & 0x0001)//空时为0、满时为1
#define SPI_SEND (x) UCA1TXBUF = x
//宏定义
#define HIGH (A)(((A>>>8)&0xFF)// Word 中的高字节
#define LOW (A)(A&0xFF)//字的低字节
#define 虚拟0xFF
//命令48位:[47]:起始(0);[46]:TX 位(1);[45:40] CMD 索引;[39:8]参数;[7:1] CRC7;[0]:结束(1)
#define GO_IDLE_STATE 0x40 //重置 SD 存储卡(CMD0)
#define SEND_OP_COND 0x41 //发送主机容量支持信息并激活卡的初始化过程(CMD1)
#define SWITCH_FUNE 0x46 //检查可切换功能(模式0)和切换卡功能(模式1)(CMD6)
#define SEND_IF_COND 0x48 //发送包含主机电源电压信息的 SD 存储卡接口条件,并询问存取的卡是否在该范围内运行(CMD8)
#define SEND_CSD 0x49 //要求所选卡发送其特定于卡的数据(CSD)(CMD9)
#define SEND_CID 0x4A //要求所选卡发送其卡 ID (CID)(CMD10)
#define STOP_TRANS 0x4C //强制卡在多块读取操作(CMD12)中停止传输
#define SEND_STATUS 0x4D //要求所选卡发送其状态寄存器(CMD13)
#define SET_BLOCKLEN 0x50 //设置 LOCK_UNLOCK 命令的长度(块大小否则锁定为512字节)(CMD16)
#define READ_SINGLE_LOCK 0x51 //读取大小为512字节的块(CMD17)
#define READ_MULT_blocks 0x52 //读取多个块 unil STOP_TRANS 命令问题(CMD18)
#define WRITE_BLOCK 0x58 //写入大小为512字节的块(CMD24)
#define WRITE_MULT_blocks 0x59 //在发出 STOP_TRANS 命令之前写入多个数据块(CMD25)
#define program_cSD 0x5B //对 CSD 的可编程位进行编程(CMD27)
#define ERASE_W_SA 0x60 //设置要擦除的第一个写入块的地址(CMD32)
#define ERASE_W_EA 0x61 //设置要擦除的最后一个写入块的地址(CMD33)
#define 擦除0x66 //擦除所有之前选择的写入块(CMD38)
#define LOCK_UNLOCK 0x6A //用于设置/重置密码或锁定/解锁卡。 传输的数据块包括所有命令详细信息。
//数据块锁定/未锁定的大小由 SET_BLOCKLEN (CMD42)设置
#define APP_CMD 0x77 //向卡定义下一个命令是 ACMD (CMD55)
#define GEN_CMD 0x78 //用于将数据块传输到卡或从卡获取数据块以用于通用/应用特定命令(CMD56)
#define READ_OCR 0x7A //读取卡的 OCR 寄存器,CCS 位被分配给 OCR[30]。 (CMD58)
#define CRC_ON_OFF 0x7B //打开或关闭 CRC 选项。 CRC 选项位中的"1"将开启该选项、"0"将关闭该选项(CMD59)
//特定于应用的命令(ACMD)、始终按 CMD55执行、设置与 CMD 相同
#define APP_SD_STATUS 0x4D //发送 SD 状态(ACMD13)
#define APP_NUM_W_BKS 0x56 //发送正确写入的(无错误)块的编号。 具有32位+ CRC 数据块的响应(ACMD22)
#define APP_SET_W_BLK_ER_N 0x57 //设置写入前要预擦除的写入块数量(用于更快的多块 WR 命令)(ACMD23)
#define APP_START_INIT 0x69 //发送主机容量支持信息并激活卡的初始化过程。 保留位应设置为"0"(ACMD41)
#define APP_SET_CLR_CARD_D 0x6A//Connect[1]/Disconnect [0]卡 CS (引脚1)上的50k Ω 上拉电阻器。 上拉电阻器可用于卡检测(ACMD42)
#define APP_SEND_SCR 0x73 //读取 SD 配置寄存器(SCR)
相关功能
void sd_Send_Cmd (const char cmd、unsigned long 数据、const char CRC)
{
unsigned char frame[6];
字符温度;
int i;
FRAME[0]=(CMD|0x40);
for (i = 3;i >=0;i---)
{
temp =(char)(data>>>(8*I));
FRAME[4-I]=(温度);
}
帧[5]= CRC;
SD_Send_SPI_Frame (帧、6);
}
unsigned char getResponse()
{
int i = 0;
unsigned char 响应;
while (i <= 25000)
{
响应= SD_Send_SPI_Char (虚拟);
if (RESPONSE == 0x00) break;
if (RESPONSE == 0x01) break;
i++;
}
退货响应;
}
空 SD_Card_Init()
{
CSCTL5 |= 0x0003 | 0x0030;//MCLK 和 SMCLK 因 SD 卡功能而减少
CS_H;//在加电期间将 CS 设置为 OFF (至少74个时钟周期)
unsigned int i;
for (i = 0;i <= 9;i++)
{
SD_Send_SPI_Char (虚拟);//8位* 10 = 80个时钟周期
}
goIdle();
CSCTL5 &=~(0x0003)|(0x0030);//将时钟恢复到所需速度
}
unsigned char goIdle()
{
无符号字符响应= 0x01;
CS_L;
SD_Send_Cmd (GO_IDLE_STATE、0、0x95);
if (getResponse()!= 0x01)
{
退货(2);
}
while (响应= 0x01)
{
CS_H;
SD_Send_SPI_Char (虚拟);
CS_L;
SD_Send_Cmd (SEND_OP_COND、0x00、0xff);
响应= getResponse();
}
CS_H;
SD_Send_SPI_Char (虚拟);
返回(1);
}
unsigned char sd_Send_SPI_Char (unsigned char x)
{
while (TX_READY = 0);//等待 TXBuffer 变为 Free
SPI_SEND (x);
while (RX_READY = 0);//等待接收数据
返回(RX);
}
unsigned long SD_Send_SPI_Frame (unsigned char* pbuffer、unsigned int SZ)
{
unsigned int i;
对于(I = 0;I < SZ;I++)
{
while (TX_READY = 0);
SPI_SEND (pbuffer[i]);
while (RX_READY = 0);
pbuffer[i]= RX;
}
返回(0);
}
主函数
void main (void)
{
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
//根据 MCLK 的器件数据表的要求配置一个 FRAM 等待状态
//在配置时钟系统之前在8MHz 以上运行。
FRCTL0 = FRCTLPW | NWAITS_1;
_bis_SR_register (SCG0);//禁用 FLL
CSCTL3 |= SELREF_REFOCLK;//将 REFO 设置为 FLL 基准源
CSCTL0 = 0;//清除 DCO 和 MOD 寄存器
CSCTL1 &=~(DCORSEL_7);//首先清除 DCO 频率选择位
CSCTL1 |= DCORSEL_5;//设置 DCO = 16MHz
CSCTL2 = FLLD_0 + 487;// DCOCLKDIV = 16MHz
_DELAY_CYCLES (3);
_BIC_SR_register (SCG0);//启用 FLL
while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));// FLL 锁定
CSCTL4 = SELMS_DCOCLKDIV | SELA_REFOCLK;//将默认 REFO (~32768Hz)设置为 ACLK 源、ACLK = 32768Hz
//默认 DCOCLKDIV 为 MCLK 和 SMCLK 源
CSCTL5 |= 0x0003 | 0x0030;//MCLK 和 SMCLK 因 SD 卡功能而减少
P1DIR |= BIT7;//将 MCLK 设置为输出
SDI;
SCLK;
Lat;//初始
//开始 SPI 设置
P2SEL0 |= BIT4 | BIT5 | BIT6;//设置 CLK、SOMI、MOSI (UCA1)
P3SEL0 |= BIT1;//设置 GPIO 作为 CS
UCA0CTLW0 |= UCSWRST;
UCA1CTLW0 |= UCMST|UCSYNC|UCCKPL|UCMSB|UCSTEM;
UCA1CTLW0 |= UCSSEL_SMCLK;
UCA1BR0 = 0x01;
UCA1BR1 = 0;
UCA1MCTLW = 0;
UCA1CTLW0 &=~UCSWRST;
UCA1IE |= UCRXIE | UCTXIE;
PM5CTL0 &=~LOCKLPM5;//禁用 GPIO 上电默认高阻抗模式
//激活先前配置的端口设置
FC1_write (7、511、511、511);
P1SEL1 |= BIT7;//将 MCLK 引脚设置为第二功能->GCLK=16MHz
unsigned int ij;
for (ij = 0;ij < 16;ij++)
{
DATA[ij]= 0x11111111111111;//亮度设置
}
同时(1)//测试//14.88m
{
SD_Card_Init();
/*由于缺乏相关性而导致的其余代码剪切(以下代码已经过测试并正常工作)*/
我最初在不调整初始化周期时钟的情况下放入代码、并且我一直得到0xFF 用于响应。 我添加了在 SD 初始化期间将 SMCLK 降至~250kHz 的代码。 但是、我在响应线中一直得到0xFF。 我已经查看了 MSP430F169的 MMC/SD 卡示例代码、并认为我对 MSP430FR2633进行了必要的更改、但我一直遇到问题。
如果我尝试启动 SD 卡时才获得0xFF、那么对我为什么要获得0xFF 有任何帮助、将会非常有帮助!
在 Advanced 中感谢您的任何帮助!
