本帖最后由 suncat0504 于 2024-7-14 22:27 编辑
按照计划,使用N947驱动SD卡设备,从SD卡中读取文件信息。但这几天一直卡在SD卡的初始化处理上了。我手里有两种SD卡模块,
分别使用SD卡和TF卡。模块提供了SPO接口模式。
这两种模块我是用STM32开发板以及ESP8266都可以正常实现初始化及获取SD卡的信息。唯独在MCX N947上没有成功。使用MCX N947时,目前是用GPIO口模拟SPI方式操作的。使用等是开饭上J6所在的接口位置,并且和TF显示屏共用某些IO端口。 按照SD卡的通讯协议,在发出74个时钟脉冲后,之后经过一定延时,接着发送CMD0指令,使SD卡进入SPI通信模式。目前就卡在初始化后的CMD0处理上。如果处理正常,在主机发出CMD0指令后,应该受到0x01,视为正常应答,从而继续后面的操作。但目前我测试的结果是: 1、如果在发送了74个初始化时钟后,延时2ms,接着发送CMD0的话,后续在不断获取来自SD卡模块的应答信息的时候,得到的是0xFE。偶尔是0,也·算是有一定规律,但一直没有出现0x01这个值1. 2、如果在发送了74个初始化时钟后,延时5s,接着发送CMD0的话,后续不断获取来自SD卡模块的应答信息是0x00。 有伙伴遇到这样的问题吗? 测试代码:- int main(void) {
- uint8_t tmp=0;
- uint32_t cnt = 0, i=0, j=0;
- char str[32] = {'\0'};
- uint8_t dat = 0;
- unsigned char pCMD0[6] ={0x40,0x00,0x00,0x00,0x00,0x95}; //CMD0,将SD卡从默认上电后的SD模式切换到SPI模式,使SD卡进入IDLE状态
-
-
- /* Board pin init */
- CLOCK_EnableClock(kCLOCK_Gpio0);
- CLOCK_EnableClock(kCLOCK_Gpio1);
- CLOCK_EnableClock(kCLOCK_Gpio3);
- BOARD_InitPins();
- BOARD_BootClockFRO12M();
-
- /* Initialize the systick module. */
- //SysTick_Config(12000000UL);
- SysTick_Config(12000UL);
-
- // LED_RED_INIT(LOGIC_LED_OFF);
- // LED_GREEN_INIT(LOGIC_LED_ON);
-
- // 重新设置输入输出方向
- ioinit_dir();
-
- Lcd_Init();
-
- // 清屏
- Lcd_Clear(BLACK);
-
- init_state = 0;
-
- delay_ms(100); //延时100mS等待卡上电
-
- //SD_Init();
-
- tmp=0;
- while (1) {
- // 输出74个脉冲
- SD_MOSI_SET;
- SD_CS_SET;
- println("Send 74 Clock.");
- GPIO_PinWrite(SD_SCK_PORT, SD_SCK, 1);
- for (i=0; i<74; i++) {
- SD_MOSI_CLR;
- delay_ms(1);
- SD_MOSI_SET;
- delay_ms(1);
- }
-
- // 延迟一段时间
- //delay_ms(10);
-
- // 发送CMD0,进入SPI模式
- SD_CS_CLR;
- println("Send CMD0.");
-
- //依次写入命令,参数,校验码
- for (j=0; j<6; j++) {
- dat = pCMD0[j];
- for(i=0; i<8; i++) {
- // 变低电平
- SD_SCK_CLR;
- // 准备数据
- if(dat&0x80) {
- SD_MOSI_SET; //输出数据
-
- } else {
- SD_MOSI_CLR;
-
- }
- delay_ms(1);
-
- // 发出上升沿,输出数据
- SD_SCK_SET;
- delay_ms(1);
-
- dat<<=1;
- }
-
- SD_SCK_CLR;
- }
-
- SD_MOSI_SET;
- // 发送8个缓冲时钟
- for(i=8;i>0;i--) {
- // 上升沿
- SD_SCK_CLR;
- delay_ms(1);
- // 下降沿
- SD_SCK_SET;
- delay_ms(1);
- }
-
- // 等待回复
- cnt = 200;
- while (cnt-->0) {
- tmp=0xFF;
- for(i=8;i>0;i--) {
- // 下降沿
- SD_SCK_CLR;
- delay_ms(1);
-
- // 上升沿
- SD_SCK_SET;
- delay_ms(1);
-
- if(ReadSD())
- tmp|=1;
-
- tmp<<=1;
- }
-
- sprintf(str, "value=%d", tmp);
- println(str);
-
- //if (((~tmp) & 0x01) == 0x01) {
- if ((tmp & 0x01) == 0x01) {
- println("CMD0 OK.");
- break;
- }
- }
- if (cnt>= 200) {
- println("CMD0 NG.");
- }
-
- SD_CS_SET;
-
- // 发送8个缓冲时钟
- SD_MOSI_SET;
- for(i=8;i>0;i--) {
- // 上升沿
- SD_SCK_CLR;
- delay_ms(1);
- // 下降沿
- SD_SCK_SET;
- delay_ms(1);
- }
- }
- }
复制代码
|