STM32F429 Discovery开发板应用:实现SPI-SD Card文件写入(搭载FatFS文件系统)_天天热推荐
MCU:STM32F429ZIT6开发环境:STM32CubeMX+MDK5
外购了一个SPI接口的SD Card模块,想要实现SD卡存储数据的功能。
(相关资料图)
首先需要打开STM32CubeMX工具。输入开发板MCU对应型号,找到开发板对应封装的MCU型号,双击打开(图中第三)。
此时,双击完后会关闭此界面,然后打开一个新界面。
然后,我们开始基本配置。
现在我们选择一个LED作为系统LED,该步骤可以忽略,只是本人喜欢这样子。以硬件原理图的LD3为例子。
基本配置除了时钟树外,基本上已经配置好了。
现在配置时钟树
基本配置已经配置完,现在开始配置实验使用的内容。
配置USART1,重定向printf函数作为串口输出。
然后配置SPI1,作为驱动SD Card读写的接口。
然后配置文件系统,可以让文件的使用更方便。
现在配置按键,触发中断处理一些事情。
配置完成,完善工程,生成工程。
到此,STM32CubeMX工具的使用结束!可以发现在桌面已经生成了SDCard_rw工程。
使用MDK5打开SDCard_rw工程打开。点击魔法棒,勾选微库。选择对应的下载器,勾选下载完复位允许。USB线一端接开发板USB_Device,一端接PC。
现在可以开始实验了
在usart.c中重定向printf函数,并在usart.h中声明。
1 //重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数2 int fputc(int ch, FILE *f)3 {4 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000); 5 return (ch);6 }
在sdcard_write工程下创建UserCode文件夹,编写drive_spisd.c和drive_spisd.h。
然后在MDK5这里的SDCard_rw工程添加一个新文件夹UserCode,装入drive_spisd.c。并在魔法棒这里加入头文件路径。
drive_spisd.c如下
1 /* Includes ------------------------------------------------------------------*/ 2 #include "drive_spisd.h" 3 /* Private includes ----------------------------------------------------------*/ 4 #include "spi.h" 5 #include "ff.h" 6 #include "usart.h" 7 /* Private typedef -----------------------------------------------------------*/ 8 9 /* Private define ------------------------------------------------------------*/ 10 11 /* Private macro -------------------------------------------------------------*/ 12 13 /* Private variables ---------------------------------------------------------*/ 14 uint8_t test; 15 uint8_t SD_TYPE = 0x00; 16 MSD_CARDINFO SD0_CardInfo; 17 char SD_FileName[] = "hello.txt"; 18 /* Private function prototypes -----------------------------------------------*/ 19 static int SD_SendCMD(uint8_t cmd, uint32_t arg, uint8_t crc); 20 static uint8_t SD_ReceiveData(uint8_t *data, uint16_t len); 21 static uint8_t SD_SendBlock(uint8_t*buf, uint8_t cmd); 22 /* Private user code ---------------------------------------------------------*/ 23 24 /** 25 * @brief SPI_CS片选 26 * @note None 27 * @retval None 28 */ 29 void SPISD_CS(uint8_t p) 30 { 31 HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, (p==0)?GPIO_PIN_SET:GPIO_PIN_RESET); 32 } 33 34 /** 35 * @brief 发送命令(CMD0~CMD63),发完释放 36 * @note 命令格式:0+传输标志(1-命令、0-响应)+CONTENT(6+32)+7CRC+1 37 * @retval None 38 */ 39 static int SD_SendCMD(uint8_t cmd, uint32_t arg, uint8_t crc) 40 { 41 uint8_t r1,retry; 42 43 SPISD_CS(0); //取消片选 44 HAL_Delay(20); 45 SPISD_CS(1); //选通 46 47 //SD卡的SPI通信协议规定,每个命令操作之前都需要发送至少8个时钟周期 48 do 49 { 50 retry = SPI_ReadWrite(0xFF); 51 }while(retry != 0xFF); 52 53 SPI_ReadWrite(cmd | 0x40); 54 SPI_ReadWrite(arg >> 24); 55 SPI_ReadWrite(arg >> 16); 56 SPI_ReadWrite(arg >> 8); 57 SPI_ReadWrite(arg); 58 SPI_ReadWrite(crc); 59 60 if(cmd == CMD12) 61 SPI_ReadWrite(0xFF); 62 do 63 { 64 r1 = SPI_ReadWrite(0xFF); 65 }while(r1 & 0x80); 66 67 return r1; 68 } 69 70 //SD卡初始化 71 uint8_t SD_Init(void) 72 { 73 uint8_t r1,i; 74 uint8_t buff[6] = {0}; 75 uint16_t retry; 76 77 SPI_SetSpeed(SPI_BAUDRATEPRESCALER_256); 78 SPISD_CS(0); 79 for(retry=0;retry<10;retry++) 80 SPI_ReadWrite(0xFF); 81 82 //SD卡进入IDLE状态 83 do 84 { 85 r1 = SD_SendCMD(CMD0 ,0, 0x95); 86 }while(r1 != 0x01); 87 88 //查看SD卡的类型 89 SD_TYPE = 0; 90 r1 = SD_SendCMD(CMD8, 0x1AA, 0x87); 91 if(r1 == 0x01) 92 { 93 for(i=0;i<4;i++) 94 buff[i] = SPI_ReadWrite(0xFF); //Get trailing return value of R7 resp 95 if( buff[2]==0X01 && buff[3]==0XAA ) //卡是否支持2.7~3.6V 96 { 97 retry = 0XFFFE; 98 do 99 { 100 SD_SendCMD(CMD55, 0, 0X01); //发送CMD55101 r1 = SD_SendCMD(CMD41, 0x40000000, 0X01); //发送CMD41102 }while(r1&&retry--);103 104 if(retry && SD_SendCMD(CMD58, 0, 0X01) == 0) //鉴别SD2.0卡版本开始105 {106 for(i=0;i<4;i++)107 buff[i] = SPI_ReadWrite(0XFF); //得到OCR值108 SD_TYPE = (buff[0]&0x40) ? V2HC:V2; 109 }110 }else111 {112 SD_SendCMD(CMD55, 0, 0X01); //发送CMD55113 r1 = SD_SendCMD(CMD41, 0, 0X01); //发送CMD41114 if(r1<=1)115 { 116 SD_TYPE = V1;117 retry = 0XFFFE;118 do //等待退出IDLE模式119 {120 SD_SendCMD(CMD55, 0, 0X01); //发送CMD55121 r1 = SD_SendCMD(CMD41, 0, 0X01); //发送CMD41122 }while(r1&&retry--);123 }else //MMC卡不支持CMD55+CMD41识别124 {125 SD_TYPE = MMC; //MMC V3126 retry = 0XFFFE;127 do //等待退出IDLE模式128 { 129 r1 = SD_SendCMD(CMD1, 0, 0X01); //发送CMD1130 }while(r1&&retry--); 131 }132 if( retry==0 || SD_SendCMD(CMD16, 512, 0X01)!=0 )133 SD_TYPE = ERR; //错误的卡134 }135 }136 SPISD_CS(0);137 SPI_SetSpeed(SPI_BAUDRATEPRESCALER_4);138 139 return SD_TYPE?0:1;140 }141 142 void FileSystem_Init(void)143 {144 FATFS *fs;145 DWORD fre_clust, AvailableSize, UserSize; 146 uint8_t res;147 uint8_t *work;148 uint16_t TotalSpace;149 150 res = SD_Init(); 151 if(res == 1)152 printf("SD卡初始化失败! \r\n"); 153 154 res = f_mount(&USERFatFS, USERPath, 1); //挂载155 if(res == FR_NO_FILESYSTEM) //没有文件系统,格式化156 {157 printf("没有文件系统! \r\n"); 158 159 work = malloc(_MIN_SS);160 res = f_mkfs(USERPath, FM_FAT, 0, work, _MIN_SS); //格式化sd卡161 free(work);162 163 if(res == FR_OK)164 { 165 res = f_mount(NULL, USERPath, 1); //格式化后先取消挂载166 res = f_mount(&USERFatFS, USERPath, 1); //重新挂载 167 if(res == FR_OK)168 {169 printf("SD卡已经成功挂载,可以进进行文件写入测试! \r\n");170 } 171 }172 else173 {174 printf("格式化失败! \r\n"); 175 }176 }else if(res == FR_OK)177 {178 printf("挂载成功! \r\n"); 179 }else180 {181 printf("挂载失败! (%d)\r\n", res);182 } 183 184 res = f_getfree(USERPath, &fre_clust, &fs); /* 根目录 */185 if ( res == FR_OK ) 186 {187 TotalSpace = (uint16_t)(((fs->n_fatent - 2) * fs->csize ) / 2 /1024);188 AvailableSize = (uint16_t)((fre_clust * fs->csize) / 2 /1024);189 UserSize = TotalSpace - AvailableSize; 190 /* Print free space in unit of MB (assuming 512 bytes/sector) */191 printf("\r\n%d MB total drive space.\r\n%ld MB available.\r\n%ld MB used.\r\n",TotalSpace, AvailableSize, UserSize);192 }193 else 194 {195 printf("Get SDCard Capacity Failed (%d)\r\n", res);196 } 197 // f_mount(NULL, USERPath, 1); //取消挂载198 } 199 200 /**201 * @brief 读取指定长度数据202 * @note None203 * @retval None204 */205 static uint8_t SD_ReceiveData(uint8_t *data, uint16_t len)206 {207 uint8_t r1;208 209 SPISD_CS(1); 210 do211 { 212 r1 = SPI_ReadWrite(0xFF); 213 HAL_Delay(100);214 }while(r1 != 0xFE); 215 216 while(len--)217 {218 *data = SPI_ReadWrite(0xFF);219 data++;220 }221 SPI_ReadWrite(0xFF);222 SPI_ReadWrite(0xFF); 223 224 return 0;225 }226 227 /**228 * @brief 向SD卡写入一个数据包(512字节)的内容229 * @note None230 * @retval None231 */232 static uint8_t SD_SendBlock(uint8_t*buf, uint8_t cmd)233 { 234 uint8_t r1; 235 uint16_t t; 236 237 do{238 r1 = SPI_ReadWrite(0xFF);239 }while(r1!=0xFF);240 241 SPI_ReadWrite(cmd);242 if(cmd != 0XFD) //不是结束指令243 {244 for(t=0; t<512; t++)245 SPI_ReadWrite(buf[t]); //提高速度,减少函数传参时间246 SPI_ReadWrite(0xFF); //忽略crc247 SPI_ReadWrite(0xFF);248 t = SPI_ReadWrite(0xFF); //接收响应249 if( (t&0x1F) != 0x05 )250 return 2; //响应错误 251 }252 253 return 0; //写入成功254 }255 256 /**257 * @brief CSD,卡的操作条件信息,128bit258 * @note None259 * @retval None260 */261 uint8_t SD_GetCSD(uint8_t *csd_data)262 {263 uint8_t r1; 264 265 r1 = SD_SendCMD(CMD9, 0, 0x01); //读取CSD寄存器266 if(r1 == 0x00)267 r1 = SD_ReceiveData(csd_data, 16); //接收16个字节的数据 268 SPISD_CS(0); //取消片选269 270 return r1?1:0;271 }272 273 /**274 * @brief CID,卡识别号,128bit275 * @note None276 * @retval None277 */278 uint8_t SD_GetCID(uint8_t *cid_data)279 {280 uint8_t r1;281 282 r1 = SD_SendCMD(CMD10, 0, 0x01); //读取CID寄存器283 if(r1==0x00)284 r1 = SD_ReceiveData(cid_data, 16); //接收16个字节的数据 285 SPISD_CS(0); //取消片选286 287 return r1?1:0;288 }289 290 //获取SD卡的总扇区数291 uint32_t SD_GetSectorCount(void)292 {293 uint8_t n;294 uint8_t csd[16];295 uint16_t csize;296 uint32_t Capacity; 297 298 if(SD_GetCSD(csd) != 0) //取CSD信息,如果期间出错,返回0299 return 0; 300 301 if( (csd[0]&0xC0) == 0x40 ) //如果为SDHC卡,按照下面方式计算。V2.00的卡302 { 303 csize = csd[9] + ((uint16_t)csd[8] << 8) + 1;304 Capacity = (uint32_t)csize << 10; //得到扇区数 305 }else //V1.xx的卡306 { 307 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;308 csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;309 Capacity = (uint32_t)csize << (n - 9); //得到扇区数 310 }311 312 return Capacity;313 }314 315 int MSD0_GetCardInfo(PMSD_CARDINFO SD0_CardInfo)316 {317 uint8_t r1;318 uint8_t CSD_Tab[16], CID_Tab[16];319 320 /* Send CMD9, Read CSD */321 r1 = SD_SendCMD(CMD9, 0, 0xFF);322 if(r1 != 0x00)323 return r1;324 if(SD_ReceiveData(CSD_Tab, 16))325 return 1;326 327 /* Send CMD10, Read CID */328 r1 = SD_SendCMD(CMD10, 0, 0xFF);329 if(r1 != 0x00)330 return r1; 331 if(SD_ReceiveData(CID_Tab, 16))332 return 2;333 334 /* Byte 0 */335 SD0_CardInfo->CSD.CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;336 SD0_CardInfo->CSD.SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;337 SD0_CardInfo->CSD.Reserved1 = CSD_Tab[0] & 0x03;338 /* Byte 1 */339 SD0_CardInfo->CSD.TAAC = CSD_Tab[1] ;340 /* Byte 2 */341 SD0_CardInfo->CSD.NSAC = CSD_Tab[2];342 /* Byte 3 */343 SD0_CardInfo->CSD.MaxBusClkFrec = CSD_Tab[3];344 /* Byte 4 */345 SD0_CardInfo->CSD.CardComdClasses = CSD_Tab[4] << 4;346 /* Byte 5 */347 SD0_CardInfo->CSD.CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;348 SD0_CardInfo->CSD.RdBlockLen = CSD_Tab[5] & 0x0F;349 /* Byte 6 */350 SD0_CardInfo->CSD.PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;351 SD0_CardInfo->CSD.WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;352 SD0_CardInfo->CSD.RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;353 SD0_CardInfo->CSD.DSRImpl = (CSD_Tab[6] & 0x10) >> 4;354 SD0_CardInfo->CSD.Reserved2 = 0; /* Reserved */355 SD0_CardInfo->CSD.DeviceSize = (CSD_Tab[6] & 0x03) << 10;356 /* Byte 7 */357 SD0_CardInfo->CSD.DeviceSize |= (CSD_Tab[7]) << 2;358 /* Byte 8 */359 SD0_CardInfo->CSD.DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;360 SD0_CardInfo->CSD.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;361 SD0_CardInfo->CSD.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);362 /* Byte 9 */363 SD0_CardInfo->CSD.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;364 SD0_CardInfo->CSD.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;365 SD0_CardInfo->CSD.DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;366 /* Byte 10 */367 SD0_CardInfo->CSD.DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;368 SD0_CardInfo->CSD.EraseGrSize = (CSD_Tab[10] & 0x7C) >> 2;369 SD0_CardInfo->CSD.EraseGrMul = (CSD_Tab[10] & 0x03) << 3;370 /* Byte 11 */371 SD0_CardInfo->CSD.EraseGrMul |= (CSD_Tab[11] & 0xE0) >> 5;372 SD0_CardInfo->CSD.WrProtectGrSize = (CSD_Tab[11] & 0x1F);373 /* Byte 12 */374 SD0_CardInfo->CSD.WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;375 SD0_CardInfo->CSD.ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;376 SD0_CardInfo->CSD.WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;377 SD0_CardInfo->CSD.MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;378 /* Byte 13 */379 SD0_CardInfo->CSD.MaxWrBlockLen |= (CSD_Tab[13] & 0xc0) >> 6;380 SD0_CardInfo->CSD.WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;381 SD0_CardInfo->CSD.Reserved3 = 0;382 SD0_CardInfo->CSD.ContentProtectAppli = (CSD_Tab[13] & 0x01);383 /* Byte 14 */384 SD0_CardInfo->CSD.FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;385 SD0_CardInfo->CSD.CopyFlag = (CSD_Tab[14] & 0x40) >> 6;386 SD0_CardInfo->CSD.PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;387 SD0_CardInfo->CSD.TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;388 SD0_CardInfo->CSD.FileFormat = (CSD_Tab[14] & 0x0C) >> 2;389 SD0_CardInfo->CSD.ECC = (CSD_Tab[14] & 0x03);390 /* Byte 15 */391 SD0_CardInfo->CSD.CSD_CRC = (CSD_Tab[15] & 0xFE) >> 1;392 SD0_CardInfo->CSD.Reserved4 = 1;393 394 if(SD0_CardInfo->CardType == V2HC)395 {396 /* Byte 7 */397 SD0_CardInfo->CSD.DeviceSize = (uint16_t)(CSD_Tab[8]) *256;398 /* Byte 8 */399 SD0_CardInfo->CSD.DeviceSize += CSD_Tab[9] ;400 }401 402 SD0_CardInfo->Capacity = SD0_CardInfo->CSD.DeviceSize * MSD_BLOCKSIZE * 1024;403 SD0_CardInfo->BlockSize = MSD_BLOCKSIZE;404 405 /* Byte 0 */406 SD0_CardInfo->CID.ManufacturerID = CID_Tab[0];407 /* Byte 1 */408 SD0_CardInfo->CID.OEM_AppliID = CID_Tab[1] << 8;409 /* Byte 2 */410 SD0_CardInfo->CID.OEM_AppliID |= CID_Tab[2];411 /* Byte 3 */412 SD0_CardInfo->CID.ProdName1 = CID_Tab[3] << 24;413 /* Byte 4 */414 SD0_CardInfo->CID.ProdName1 |= CID_Tab[4] << 16;415 /* Byte 5 */416 SD0_CardInfo->CID.ProdName1 |= CID_Tab[5] << 8;417 /* Byte 6 */418 SD0_CardInfo->CID.ProdName1 |= CID_Tab[6];419 /* Byte 7 */420 SD0_CardInfo->CID.ProdName2 = CID_Tab[7];421 /* Byte 8 */422 SD0_CardInfo->CID.ProdRev = CID_Tab[8];423 /* Byte 9 */424 SD0_CardInfo->CID.ProdSN = CID_Tab[9] << 24;425 /* Byte 10 */426 SD0_CardInfo->CID.ProdSN |= CID_Tab[10] << 16;427 /* Byte 11 */428 SD0_CardInfo->CID.ProdSN |= CID_Tab[11] << 8;429 /* Byte 12 */430 SD0_CardInfo->CID.ProdSN |= CID_Tab[12];431 /* Byte 13 */432 SD0_CardInfo->CID.Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;433 /* Byte 14 */434 SD0_CardInfo->CID.ManufactDate = (CID_Tab[13] & 0x0F) << 8;435 /* Byte 15 */436 SD0_CardInfo->CID.ManufactDate |= CID_Tab[14];437 /* Byte 16 */438 SD0_CardInfo->CID.CID_CRC = (CID_Tab[15] & 0xFE) >> 1;439 SD0_CardInfo->CID.Reserved2 = 1;440 441 return 0; 442 }443 444 445 //写SD卡446 //buf:数据缓存区447 //sector:起始扇区448 //cnt:扇区数449 //返回值:0,ok;其他,失败.450 uint8_t SD_WriteDisk(uint8_t *buf, uint32_t sector, uint8_t cnt)451 {452 uint8_t r1;453 454 if(SD_TYPE != V2HC)455 sector *= 512; //转换为字节地址456 if(cnt == 1)457 {458 r1 = SD_SendCMD(CMD24, sector, 0x01); //读命令459 if(r1 == 0) //指令发送成功460 r1=SD_SendBlock(buf, 0xFE); //写512个字节 461 }else462 {463 if(SD_TYPE != MMC)464 {465 SD_SendCMD(CMD55, 0, 0x01); 466 SD_SendCMD(CMD23, cnt, 0x01); //发送指令 467 }468 r1 = SD_SendCMD(CMD25, sector, 0x01); //连续读命令469 if(r1 == 0)470 {471 do472 {473 r1 = SD_SendBlock(buf,0xFC); //接收512个字节 474 buf += 512; 475 }while(--cnt && r1==0);476 r1 = SD_SendBlock(0,0xFD); //接收512个字节 477 }478 } 479 SPISD_CS(0); //取消片选480 481 return r1;482 } 483 484 //读SD卡485 //buf:数据缓存区486 //sector:扇区487 //cnt:扇区数488 //返回值:0,ok;其他,失败.489 uint8_t SD_ReadDisk(uint8_t*buf,uint32_t sector,uint8_t cnt)490 {491 uint8_t r1;492 493 if(SD_TYPE != V2HC)494 sector <<= 9; //转换为字节地址495 if(cnt == 1)496 {497 r1 = SD_SendCMD(CMD17, sector, 0x01); //读命令498 if(r1 == 0) 499 r1 = SD_ReceiveData(buf, 512); //接收512个字节 500 }else501 {502 r1 = SD_SendCMD(CMD18, sector, 0x01); //连续读命令503 do504 {505 r1 = SD_ReceiveData(buf, 512); //接收512个字节 506 buf += 512; 507 }while(--cnt && r1==0); 508 SD_SendCMD(CMD12, 0, 0x01); //发送停止命令509 } 510 SPISD_CS(0); //取消片选511 512 return r1;513 }514 515 uint8_t SPI_ReadWrite(uint8_t Txdata)516 {517 uint8_t Rxdata; 518 HAL_SPI_TransmitReceive(&hspi1, &Txdata, &Rxdata, 1, 100);519 return Rxdata;520 }521 522 //SPI1波特率设置523 void SPI_SetSpeed(uint8_t speed)524 {525 hspi1.Init.BaudRatePrescaler = speed;526 if (HAL_SPI_Init(&hspi1) != HAL_OK)527 {528 Error_Handler();529 }530 }531 ///////////////////////////END//////////////////////////////////////
drive_spisd.h如下
1 /* Define to prevent recursive inclusion -------------------------------------*/ 2 #ifndef __DRIVE_SPISD_H 3 #define __DRIVE_SPISD_H 4 5 #ifdef __cplusplus 6 extern "C" { 7 #endif 8 9 /* Includes ------------------------------------------------------------------*/ 10 #include "main.h" 11 /* Private includes ----------------------------------------------------------*/ 12 #include "fatfs.h" 13 /* Exported types ------------------------------------------------------------*/ 14 enum _CD_HOLD 15 { 16 HOLD = 0, 17 RELEASE = 1, 18 }; 19 20 typedef struct /* Card Specific Data */ 21 { 22 uint8_t CSDStruct; /* CSD structure */ 23 uint8_t SysSpecVersion; /* System specification version */ 24 uint8_t Reserved1; /* Reserved */ 25 uint8_t TAAC; /* Data read access-time 1 */ 26 uint8_t NSAC; /* Data read access-time 2 in CLK cycles */ 27 uint8_t MaxBusClkFrec; /* Max. bus clock frequency */ 28 uint16_t CardComdClasses; /* Card command classes */ 29 uint8_t RdBlockLen; /* Max. read data block length */ 30 uint8_t PartBlockRead; /* Partial blocks for read allowed */ 31 uint8_t WrBlockMisalign; /* Write block misalignment */ 32 uint8_t RdBlockMisalign; /* Read block misalignment */ 33 uint8_t DSRImpl; /* DSR implemented */ 34 uint8_t Reserved2; /* Reserved */ 35 uint32_t DeviceSize; /* Device Size */ 36 uint8_t MaxRdCurrentVDDMin; /* Max. read current @ VDD min */ 37 uint8_t MaxRdCurrentVDDMax; /* Max. read current @ VDD max */ 38 uint8_t MaxWrCurrentVDDMin; /* Max. write current @ VDD min */ 39 uint8_t MaxWrCurrentVDDMax; /* Max. write current @ VDD max */ 40 uint8_t DeviceSizeMul; /* Device size multiplier */ 41 uint8_t EraseGrSize; /* Erase group size */ 42 uint8_t EraseGrMul; /* Erase group size multiplier */ 43 uint8_t WrProtectGrSize; /* Write protect group size */ 44 uint8_t WrProtectGrEnable; /* Write protect group enable */ 45 uint8_t ManDeflECC; /* Manufacturer default ECC */ 46 uint8_t WrSpeedFact; /* Write speed factor */ 47 uint8_t MaxWrBlockLen; /* Max. write data block length */ 48 uint8_t WriteBlockPaPartial; /* Partial blocks for write allowed */ 49 uint8_t Reserved3; /* Reserded */ 50 uint8_t ContentProtectAppli; /* Content protection application */ 51 uint8_t FileFormatGrouop; /* File format group */ 52 uint8_t CopyFlag; /* Copy flag (OTP) */ 53 uint8_t PermWrProtect; /* Permanent write protection */ 54 uint8_t TempWrProtect; /* Temporary write protection */ 55 uint8_t FileFormat; /* File Format */ 56 uint8_t ECC; /* ECC code */ 57 uint8_t CSD_CRC; /* CSD CRC */ 58 uint8_t Reserved4; /* always 1*/ 59 }MSD_CSD; 60 61 typedef struct /*Card Identification Data*/ 62 { 63 uint8_t ManufacturerID; /* ManufacturerID */ 64 uint16_t OEM_AppliID; /* OEM/Application ID */ 65 uint32_t ProdName1; /* Product Name part1 */ 66 uint8_t ProdName2; /* Product Name part2*/ 67 uint8_t ProdRev; /* Product Revision */ 68 uint32_t ProdSN; /* Product Serial Number */ 69 uint8_t Reserved1; /* Reserved1 */ 70 uint16_t ManufactDate; /* Manufacturing Date */ 71 uint8_t CID_CRC; /* CID CRC */ 72 uint8_t Reserved2; /* always 1 */ 73 }MSD_CID; 74 75 typedef struct 76 { 77 MSD_CSD CSD; 78 MSD_CID CID; 79 uint32_t Capacity; /* Card Capacity */ 80 uint32_t BlockSize; /* Card Block Size */ 81 uint16_t RCA; 82 uint8_t CardType; 83 uint32_t SpaceTotal; /* Total space size in file system */ 84 uint32_t SpaceFree; /* Free space size in file system */ 85 }MSD_CARDINFO, *PMSD_CARDINFO; 86 87 extern MSD_CARDINFO SD0_CardInfo; 88 /* Exported constants --------------------------------------------------------*/ 89 90 /* Exported macro ------------------------------------------------------------*/ 91 //SD卡类型 92 #define ERR 0x00 93 #define MMC 0x01 94 #define V1 0x02 95 #define V2 0x04 96 #define V2HC 0x06 97 98 #define DUMMY_BYTE 0xFF 99 #define MSD_BLOCKSIZE 512100 101 /*102 CMD定义103 bc:发送到所有卡,不返回响应104 bcr:发送到所有卡,同时接收所有卡的响应105 ac:发送到选定卡,无数据传输106 adtc:发送到选定卡,有数据传输107 */108 #define CMD0 0 //bc,卡复位到IDLE状态109 #define CMD1 1 110 #define CMD8 8 //bcr,读SD卡接口条件,包含主机支持的电压信息,并询问卡是否支持111 #define CMD9 9 //ac,读CSD数据112 #define CMD10 10 //ac,读CID数据113 #define CMD12 12 //ac,停止数据传输114 #define CMD16 16 //ac,设置块长度(对于SDHC卡块命令长度固定为512字节) 应返回0x00115 #define CMD17 17 //adtc,读单个块116 #define CMD18 18 //adtc,读多个块。连续读块,直到被CMD12中断。117 #define CMD23 23 //设置多sector写入前预先擦除N个block118 #define CMD24 24 //adtc,写单个块119 #define CMD25 25 //adtc,写多个块。连续写块,直到被CMD12中断。120 #define CMD41 41 //应返回0x00121 #define CMD55 55 //ac,指定下个命令为特定应用命令(ACMD),不是标准命令,应返回0x01122 #define CMD58 58 //读OCR信息123 #define CMD59 59 //使能/禁止CRC,应返回0x00124 125 //数据写入回应字意义126 #define MSD_DATA_OK 0x05127 #define MSD_DATA_CRC_ERROR 0x0B128 #define MSD_DATA_WRITE_ERROR 0x0D129 #define MSD_DATA_OTHER_ERROR 0xFF130 131 //SD卡回应标记字132 #define MSD_RESPONSE_NO_ERROR 0x00133 #define MSD_IN_IDLE_STATE 0x01134 #define MSD_ERASE_RESET 0x02135 #define MSD_ILLEGAL_COMMAND 0x04136 #define MSD_COM_CRC_ERROR 0x08137 #define MSD_ERASE_SEQUENCE_ERROR 0x10138 #define MSD_ADDRESS_ERROR 0x20139 #define MSD_PARAMETER_ERROR 0x40140 #define MSD_RESPONSE_FAILURE 0xFF141 142 /* Exported functions prototypes ---------------------------------------------*/143 void SPISD_CS(uint8_t p);144 uint8_t SD_Init(void);145 void WritetoSD(BYTE write_buff[],uint8_t bufSize);146 void FileSystem_Init(void);147 uint32_t SD_GetSectorCount(void);148 uint8_t SD_GetCID(uint8_t *cid_data);149 uint8_t SD_GetCSD(uint8_t *csd_data);150 int MSD0_GetCardInfo(PMSD_CARDINFO SD0_CardInfo);151 uint8_t SD_ReadDisk(uint8_t*buf, uint32_t sector, uint8_t cnt);152 uint8_t SD_WriteDisk(uint8_t*buf, uint32_t sector, uint8_t cnt);153 void SPI_SetSpeed(uint8_t speed);154 uint8_t SPI_ReadWrite(uint8_t Txdata);155 156 /* Private defines -----------------------------------------------------------*/157 extern uint8_t SD_TYPE;158 #ifdef __cplusplus159 }160 #endif161 162 #endif /* __DRIVE_SPISD_H */163 164 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
然后在文件系统文件夹里修改内容。
user_diskio.c如下
1 /* USER CODE BEGIN Header */ 2 /** 3 ****************************************************************************** 4 * @file user_diskio.c 5 * @brief This file includes a diskio driver skeleton to be completed by the user. 6 ****************************************************************************** 7 * @attention 8 * 9 * Copyright (c) 2023 STMicroelectronics. 10 * All rights reserved. 11 * 12 * This software is licensed under terms that can be found in the LICENSE file 13 * in the root directory of this software component. 14 * If no LICENSE file comes with this software, it is provided AS-IS. 15 * 16 ****************************************************************************** 17 */ 18 /* USER CODE END Header */ 19 20 #ifdef USE_OBSOLETE_USER_CODE_SECTION_0 21 /* 22 * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0) 23 * To be suppressed in the future. 24 * Kept to ensure backward compatibility with previous CubeMx versions when 25 * migrating projects. 26 * User code previously added there should be copied in the new user sections before 27 * the section contents can be deleted. 28 */ 29 /* USER CODE BEGIN 0 */ 30 /* USER CODE END 0 */ 31 #endif 32 33 /* USER CODE BEGIN DECL */ 34 35 /* Includes ------------------------------------------------------------------*/ 36 #include37 #include "ff_gen_drv.h" 38 39 /* Private typedef -----------------------------------------------------------*/ 40 #include "drive_spisd.h" 41 /* Private define ------------------------------------------------------------*/ 42 43 /* Private variables ---------------------------------------------------------*/ 44 /* Disk status */ 45 static volatile DSTATUS Stat = STA_NOINIT; 46 47 /* USER CODE END DECL */ 48 49 /* Private function prototypes -----------------------------------------------*/ 50 DSTATUS USER_initialize (BYTE pdrv); 51 DSTATUS USER_status (BYTE pdrv); 52 DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count); 53 #if _USE_WRITE == 1 54 DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count); 55 #endif /* _USE_WRITE == 1 */ 56 #if _USE_IOCTL == 1 57 DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff); 58 #endif /* _USE_IOCTL == 1 */ 59 60 Diskio_drvTypeDef USER_Driver = 61 { 62 USER_initialize, 63 USER_status, 64 USER_read, 65 #if _USE_WRITE 66 USER_write, 67 #endif /* _USE_WRITE == 1 */ 68 #if _USE_IOCTL == 1 69 USER_ioctl, 70 #endif /* _USE_IOCTL == 1 */ 71 }; 72 73 /* Private functions ---------------------------------------------------------*/ 74 75 /** 76 * @brief Initializes a Drive 77 * @param pdrv: Physical drive number (0..) 78 * @retval DSTATUS: Operation status 79 */ 80 DSTATUS USER_initialize ( 81 BYTE pdrv /* Physical drive nmuber to identify the drive */ 82 ) 83 { 84 /* USER CODE BEGIN INIT */ 85 uint8_t res; 86 res = SD_Init(); 87 if(res) //STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常 88 { 89 SPI_SetSpeed(SPI_BAUDRATEPRESCALER_256); 90 SPI_ReadWrite(0xff); //提供额外的8个时钟 91 SPI_SetSpeed(SPI_BAUDRATEPRESCALER_4); 92 } 93 if(res) 94 return STA_NOINIT; 95 else 96 return RES_OK; 97 /* USER CODE END INIT */ 98 } 99 100 /**101 * @brief Gets Disk Status102 * @param pdrv: Physical drive number (0..)103 * @retval DSTATUS: Operation status104 */105 DSTATUS USER_status (106 BYTE pdrv /* Physical drive number to identify the drive */107 )108 {109 /* USER CODE BEGIN STATUS */110 switch (pdrv)111 {112 case 0 :113 return RES_OK;114 case 1 :115 return RES_OK;116 case 2 :117 return RES_OK;118 default:119 return STA_NOINIT;120 }121 /* USER CODE END STATUS */122 }123 124 /**125 * @brief Reads Sector(s)126 * @param pdrv: Physical drive number (0..)127 * @param *buff: Data buffer to store read data128 * @param sector: Sector address (LBA)129 * @param count: Number of sectors to read (1..128)130 * @retval DRESULT: Operation result131 */132 DRESULT USER_read (133 BYTE pdrv, /* Physical drive nmuber to identify the drive */134 BYTE *buff, /* Data buffer to store read data */135 DWORD sector, /* Sector address in LBA */136 UINT count /* Number of sectors to read */137 )138 {139 /* USER CODE BEGIN READ */140 uint8_t res;141 if( !count )142 { 143 return RES_PARERR; /* count不能等于0,否则返回参数错误 */144 }145 switch (pdrv)146 {147 case 0:148 res = SD_ReadDisk(buff,sector,count); 149 if(res == 0)150 return RES_OK;151 else152 return RES_ERROR; 153 default:154 return RES_ERROR;155 }156 /* USER CODE END READ */157 }158 159 /**160 * @brief Writes Sector(s)161 * @param pdrv: Physical drive number (0..)162 * @param *buff: Data to be written163 * @param sector: Sector address (LBA)164 * @param count: Number of sectors to write (1..128)165 * @retval DRESULT: Operation result166 */167 #if _USE_WRITE == 1168 DRESULT USER_write (169 BYTE pdrv, /* Physical drive nmuber to identify the drive */170 const BYTE *buff, /* Data to be written */171 DWORD sector, /* Sector address in LBA */172 UINT count /* Number of sectors to write */173 )174 {175 /* USER CODE BEGIN WRITE */176 /* USER CODE HERE */177 uint8_t res;178 if( !count )179 return RES_PARERR; /* count不能等于0,否则返回参数错误 */180 switch (pdrv)181 {182 case 0:183 res=SD_WriteDisk((uint8_t *)buff,sector,count);184 if(res == 0)185 return RES_OK;186 else187 return RES_ERROR; 188 default:189 return RES_ERROR;190 }191 /* USER CODE END WRITE */192 }193 #endif /* _USE_WRITE == 1 */194 195 /**196 * @brief I/O control operation197 * @param pdrv: Physical drive number (0..)198 * @param cmd: Control code199 * @param *buff: Buffer to send/receive control data200 * @retval DRESULT: Operation result201 */202 #if _USE_IOCTL == 1203 DRESULT USER_ioctl (204 BYTE pdrv, /* Physical drive nmuber (0..) */205 BYTE cmd, /* Control code */206 void *buff /* Buffer to send/receive control data */207 )208 {209 /* USER CODE BEGIN IOCTL */210 DRESULT res;211 switch(cmd)212 {213 case CTRL_SYNC:214 SPISD_CS(1);215 do{216 HAL_Delay(20);217 }while(SPI_ReadWrite(0xFF)!=0xFF);218 res=RES_OK;219 SPISD_CS(0);220 break; 221 case GET_SECTOR_SIZE:222 *(WORD*)buff = 512;223 res = RES_OK;224 break; 225 case GET_BLOCK_SIZE:226 *(WORD*)buff = 8;227 res = RES_OK;228 break; 229 case GET_SECTOR_COUNT:230 *(DWORD*)buff = SD_GetSectorCount();231 res = RES_OK;232 break;233 default:234 res = RES_PARERR;235 break;236 }237 return res;238 /* USER CODE END IOCTL */239 }240 #endif /* _USE_IOCTL == 1 */
main.c
1 /* USER CODE BEGIN Header */ 2 /** 3 ****************************************************************************** 4 * @file : main.c 5 * @brief : Main program body 6 ****************************************************************************** 7 * @attention 8 * 9 * Copyright (c) 2023 STMicroelectronics. 10 * All rights reserved. 11 * 12 * This software is licensed under terms that can be found in the LICENSE file 13 * in the root directory of this software component. 14 * If no LICENSE file comes with this software, it is provided AS-IS. 15 * 16 ****************************************************************************** 17 */ 18 /* USER CODE END Header */ 19 /* Includes ------------------------------------------------------------------*/ 20 #include "main.h" 21 #include "fatfs.h" 22 #include "spi.h" 23 #include "usart.h" 24 #include "gpio.h" 25 26 /* Private includes ----------------------------------------------------------*/ 27 /* USER CODE BEGIN Includes */ 28 #include "drive_spisd.h" 29 /* USER CODE END Includes */ 30 31 /* Private typedef -----------------------------------------------------------*/ 32 /* USER CODE BEGIN PTD */ 33 34 /* USER CODE END PTD */ 35 36 /* Private define ------------------------------------------------------------*/ 37 /* USER CODE BEGIN PD */ 38 /* USER CODE END PD */ 39 40 /* Private macro -------------------------------------------------------------*/ 41 /* USER CODE BEGIN PM */ 42 43 /* USER CODE END PM */ 44 45 /* Private variables ---------------------------------------------------------*/ 46 47 /* USER CODE BEGIN PV */ 48 uint8_t status = 0; 49 uint8_t writeBuf[] = "demo program forever no bug!!!\r\n"; 50 /* USER CODE END PV */ 51 52 /* Private function prototypes -----------------------------------------------*/ 53 void SystemClock_Config(void); 54 /* USER CODE BEGIN PFP */ 55 56 /* USER CODE END PFP */ 57 58 /* Private user code ---------------------------------------------------------*/ 59 /* USER CODE BEGIN 0 */ 60 61 /* USER CODE END 0 */ 62 63 /** 64 * @brief The application entry point. 65 * @retval int 66 */ 67 int main(void) 68 { 69 /* USER CODE BEGIN 1 */ 70 UINT Bw; 71 FIL file; 72 uint16_t cb_task = 0; 73 uint8_t res1 = 0, res2 = 0; 74 /* USER CODE END 1 */ 75 76 /* MCU Configuration--------------------------------------------------------*/ 77 78 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 79 HAL_Init(); 80 81 /* USER CODE BEGIN Init */ 82 83 /* USER CODE END Init */ 84 85 /* Configure the system clock */ 86 SystemClock_Config(); 87 88 /* USER CODE BEGIN SysInit */ 89 90 /* USER CODE END SysInit */ 91 92 /* Initialize all configured peripherals */ 93 MX_GPIO_Init(); 94 MX_SPI1_Init(); 95 MX_USART1_UART_Init(); 96 MX_FATFS_Init(); 97 /* USER CODE BEGIN 2 */ 98 FileSystem_Init(); //初始化文件系统 99 100 status = 1;101 res1 = f_open(&file, "sdRW1.txt", FA_OPEN_ALWAYS | FA_WRITE);102 if((res1 & FR_DENIED) == FR_DENIED)103 printf("卡存储已满,写入失败! \r\n");104 /* USER CODE END 2 */105 106 /* Infinite loop */107 /* USER CODE BEGIN WHILE */108 while (1)109 {110 /* USER CODE END WHILE */111 112 /* USER CODE BEGIN 3 */113 if(status == 1)114 {115 if(res1 == FR_OK)116 {117 f_lseek(&file, f_size(&file)); //确保写入不会覆盖之前的数据118 res2 = f_write(&file, writeBuf, sizeof(writeBuf), &Bw); //写数据到SD卡 119 if(res2 != FR_OK)120 {121 printf("文件写入失败! \r\n");122 HAL_GPIO_WritePin(User_led_GPIO_Port, User_led_Pin, GPIO_PIN_RESET);123 }else124 {125 HAL_GPIO_WritePin(User_led_GPIO_Port, User_led_Pin, GPIO_PIN_SET);126 } 127 }128 else129 {130 printf("打开文件失败! %d\r\n",res1);131 } 132 if(++cb_task%4096==0)133 f_sync(&file); 134 }else if(status == 2)135 {136 f_close(&file);137 f_mount(NULL, USERPath, 1); //取消挂载138 HAL_GPIO_WritePin(User_led_GPIO_Port, User_led_Pin, GPIO_PIN_RESET);139 status = 0;140 }141 HAL_Delay(10);142 }143 /* USER CODE END 3 */144 }145 146 /**147 * @brief System Clock Configuration148 * @retval None149 */150 void SystemClock_Config(void)151 {152 RCC_OscInitTypeDef RCC_OscInitStruct = {0};153 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};154 155 /** Configure the main internal regulator output voltage156 */157 __HAL_RCC_PWR_CLK_ENABLE();158 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);159 /** Initializes the RCC Oscillators according to the specified parameters160 * in the RCC_OscInitTypeDef structure.161 */162 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;163 RCC_OscInitStruct.HSEState = RCC_HSE_ON;164 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;165 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;166 RCC_OscInitStruct.PLL.PLLM = 4;167 RCC_OscInitStruct.PLL.PLLN = 168;168 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;169 RCC_OscInitStruct.PLL.PLLQ = 4;170 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)171 {172 Error_Handler();173 }174 /** Initializes the CPU, AHB and APB buses clocks175 */176 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK177 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;178 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;179 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;180 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;181 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;182 183 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)184 {185 Error_Handler();186 }187 }188 189 /* USER CODE BEGIN 4 */190 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)191 {192 if(GPIO_Pin == User_Key_Pin)193 {194 status = 2;195 }196 }197 /* USER CODE END 4 */198 199 /**200 * @brief This function is executed in case of error occurrence.201 * @retval None202 */203 void Error_Handler(void)204 {205 /* USER CODE BEGIN Error_Handler_Debug */206 /* User can add his own implementation to report the HAL error return state */207 __disable_irq();208 while (1)209 {210 }211 /* USER CODE END Error_Handler_Debug */212 }213 214 #ifdef USE_FULL_ASSERT215 /**216 * @brief Reports the name of the source file and the source line number217 * where the assert_param error has occurred.218 * @param file: pointer to the source file name219 * @param line: assert_param error line source number220 * @retval None221 */222 void assert_failed(uint8_t *file, uint32_t line)223 {224 /* USER CODE BEGIN 6 */225 /* User can add his own implementation to report the file name and line number,226 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */227 /* USER CODE END 6 */228 }229 #endif /* USE_FULL_ASSERT */
实测是可以的,但是写速度并没有网上说的1M/s那么快,也有可能是我引线的问题。
关键词:
相关阅读
-
STM32F429 Discovery开发板应用:实现S...
MCU:STM32F429ZIT6开发环境:STM32CubeMX+MDK5外购了一个SPI接口的SDC -
2023年智能雨伞行业市场分析:国内智能...
智能雨伞按照市场应用可以分为个人用途和商业用途这两种,在相关技术的 -
维峰电子:6月6日融资净买入134.23万元...
6月6日,维峰电子(301328)融资买入180 93万元,融资偿还46 71万元, -
国内商品期市午盘涨跌不一 花生跌超4%
6月7日午盘,国内商品期货主力合约涨跌互现。截至11:30,20号胶、橡胶 -
澄迈生态环境和资源保护工作力度大 立...
新海南客户端、南海网6月7日消息(记者苏靓)6月6日,澄迈县人民检察院 -
如何下载植物大战僵尸花园战争_如何下载...
1、要在网上搜安卓(版)植物大战僵尸下载就行了!注:要看手机的UBS有
精彩推送
-
STM32F429 Discovery开发板应用:实现S...
MCU:STM32F429ZIT6开发环境:STM32CubeMX+MDK5外购了一个SPI接口的SDC -
全球看热讯:新时装新玩法 《魔域手游2...
各位冒险者大家好,《魔域手游2》奇幻园游会活动仍在火热进行中,现在 -
全球简讯:暗黑4诅咒加码之威能介绍
暗黑4诅咒加码之威能是很多暗黑玩家都关注的,暗黑4是最新才发售的暴雪 -
2023年智能雨伞行业市场分析:国内智能...
智能雨伞按照市场应用可以分为个人用途和商业用途这两种,在相关技术的 -
小学六年级上册语文爷爷的芦笛说课稿-天...
乐乐学教研网精心为你收集整理了小学六年级上册语文爷爷的芦笛说课稿( -
记者:别无选择,梅西需要耐心等待,球...
来自国外的多位媒体记者表态,巴萨现在还不能立刻马上签下梅西,因为巴 -
华人健康:6月6日融资买入425.33万元,...
6月6日,华人健康(301408)融资买入425 33万元,融资偿还584 91万元, -
网传克扣供应商10%货款 长安汽车发声明...
网传克扣供应商10%货款长安汽车发声明:从未收到申诉函、已报案 -
维峰电子:6月6日融资净买入134.23万元...
6月6日,维峰电子(301328)融资买入180 93万元,融资偿还46 71万元, -
天天快消息!ST恒久(002808)6月7日11...
6月7日盘中消息,11点8分ST恒久(002808)触及涨停板。目前价格6 44, -
上市不到1个月 要打比亚迪宋的哈弗枭龙...
上市不到1个月要打比亚迪宋的哈弗枭龙系列有优惠了:立省6000块! -
男子花147万买保时捷提车2天就坏了!4S...
男子花147万买保时捷提车2天就坏了!4S店:赔8000元代金券 -
美国商标和专利局曝光苹果新 iPad 专利
据业内信息报道,美国商标和专利局(USPTO)近日公示的清单里显示苹果获 -
下回还敢?一司机超速驾驶被罚92万:吊...
下回还敢?一司机超速驾驶被罚92万:吊销驾照10天 -
【环球时快讯】塞尔达传说王国之泪格鲁...
《塞尔达传说:王国之泪》是任天堂新推出的一款顶级作品。格鲁德之枪✨ -
国内商品期市午盘涨跌不一 花生跌超4%
6月7日午盘,国内商品期货主力合约涨跌互现。截至11:30,20号胶、橡胶 -
澄迈生态环境和资源保护工作力度大 立...
新海南客户端、南海网6月7日消息(记者苏靓)6月6日,澄迈县人民检察院 -
王传福留的活路 李书福堵死了|全球热点
王传福留的活路李书福堵死了 -
焦点播报:烟台市莱山区志愿者到烟台大学...
6月6日,烟台大学附属中学石明校区学校附近出现了莱山区志愿者的身影, -
【天天时快讯】发布 Vision Pro 后,...
据业内信息报道,苹果在昨天的WWDC23大会上刚刚发布了其AR头显设备Visi -
维修眼镜、防暑药品… 渠县这些“爱心...
维修眼镜、防暑药品…渠县这些“爱心护考”服务实用又暖心 -
飞凡巴赫座舱来了:全球首创主动式座椅...
飞凡巴赫座舱来了:全球首创主动式座椅可自动充气放气 -
亚马逊云科技re:Inforce 2023全球大会...
北京——2023年6月7日全球云安全领域的行业盛会亚马逊云科技re:Inforce -
世界快报:球王下家已定!记者:梅西将在...
由于梅西本赛季还能在五大联赛交出准220+数据的球员,在整个五大联赛也 -
新款特斯拉Model 3实车曝光:全新大灯...
新款特斯拉Model3实车曝光:全新大灯、辅助驾驶能力再升级 -
哮喘病人能去高原吗_哮喘病人能活多久 ...
1、哮喘对人的生存和生活影响相对较小,哮喘一般不会致命。2、但是哮喘 -
EDG野辅粉丝互怼图,jiejie和meiko争论...
在最近公布的战队语音中,edg战队的两名冠军选手似乎出现了意识上的分 -
如何下载植物大战僵尸花园战争_如何下载...
1、要在网上搜安卓(版)植物大战僵尸下载就行了!注:要看手机的UBS有 -
668万户的815大停电后,台湾能源政策如何...
8月15日因中油供气给台电大潭隔离站发生操作失误,造成全台大跳电,对产 -
环球速递!环球时报社评:高考的精神内...
2023年全国高考于7日拉开帷幕。这不仅是1291万考生和他们家庭的重要时 -
眼病应早筛查早诊治 多项义诊讲座等你...
2023年6月6日是全国第28个爱眼日,今年主题为“关注普遍的眼健康”... -
安徽补充耕地即将“大起底”
记者6月6日从安徽省自然资源厅获悉,为进一步压实市县耕地保护主体责任, -
苹果 Vision Pro 头显融合三大交互,...
IT之家6月7日消息,苹果iPhone的亮点之一,就是更直观的交互方式,极低 -
世界热消息:广西出台《质量强国建设纲...
【原标题】我区出台《质量强国建设纲要》实施方案提出到2025年全区经济 -
世界最资讯丨真遥遥领先!比亚迪汉唐家...
真遥遥领先!比亚迪汉唐家族累计销量破100万:单车型均超50万 -
ARM处理器是由哪些基本体系进行构成的?...
ARM公司是微处理器行业的一家知名企业,它是知识产权供应商,设计基于A -
特斯拉索赔 500 万今日开庭,车顶维权...
特斯拉诉车顶维权张女士名誉权纠纷一案,今天早上在上海市青浦区人民法 -
全新Logo神似丰田皇冠 郑州日产帕拉丁...
全新Logo神似丰田皇冠郑州日产帕拉丁复活了:真的可以开进沙漠! -
每日速读!河南省二手车出口试点企业评审...
河南省二手车出口试点企业评审结果公示,28家企业在列【大河财立方消息 -
一个小孔可能致发动机起火 福特汽车召...
一个小孔可能致发动机起火福特汽车召回12 5万辆汽车 -
可怕!一比亚迪唐司机疲劳驾驶追尾大货...
可怕!一比亚迪唐司机疲劳驾驶追尾大货:半截被撕毁、整车报废 -
识条铁咩什么意思_铁咩是什么意思日语 ...
想必现在有很多小伙伴对于铁咩是什么意思日语方面的知识都比较想要了解 -
双g的logo是什么品牌_双g是什么品牌两个...
想必现在有很多小伙伴对于双g是什么品牌,两个G的品牌是什么方面的知识 -
透明jk水手服_空气裙是什么意思jk什么叫...
想必现在有很多小伙伴对于空气裙是什么意思jk,什么叫jk空气裙方面的知 -
23家公司发布股票回购相关公告 威胜信...
Wind数据显示,6月7日,共23家公司发布股票回购相关公告。其中,10家公 -
新乡市政务服务“跨省通办”合作再添伙...
新乡市政务服务“跨省通办”合作再添伙伴近日,新乡市与陕西省铜川... -
环球聚焦:五菱缤果减配ESC、自动驻车被...
五菱缤果减配ESC、自动驻车被投诉车主:看海鸥卖的好了才加上 -
每日消息!统计和分享有哪些厂商推出了AR...
ARMCortex-M0+处理器作为ARMCortex处理器系列的最新成员,32位Cortex-M -
环球热讯:侵犯特斯拉名誉权败诉后博主拒...
侵犯特斯拉名誉权败诉后博主拒不道歉陶琳无奈发文 -
全力备战巴黎奥运会丨中国男排3:2胜保加...
全力备战巴黎奥运会丨中国男排3:2胜保加利亚取得世联赛开门红---人民网 -
全球热议:清杂物 生命通道不堵了
本报5月19日以《怎么老有人给生命通道“添堵”》为题,对景泰西里西... -
环球滚动:京粮控股(000505.SZ)4115.99万...
智通财经APP讯,京粮控股(000505)(000505 SZ)公告,公司本次限售股份实 -
焦点信息:雅化集团:公司是其4680电池的...
雅化集团(002497)06月06日在投资者关系平台上答复了投资者关心的问题。 -
淮安市以政策护航高校毕业生等青年就业扬帆
淮安市以政策护航高校毕业生等青年就业扬帆促进高校毕业生等青年就业创 -
支持和规范队伍发展 海门区推进社会应...
支持和规范队伍发展海门区推进社会应急力量建设为进一步加强全区社会应 -
安德烈·布利兹尼琴科-环球观点
1、安德烈·布利兹尼琴科,1994年7月24日出生,乌克兰足球运动员。2、 -
美股快速拉升_天天观热点
美股快速拉升:美股快速拉升,纳指涨0 3%。纳斯达克中国金龙指数涨1 8% -
华宝新能:Jackery电小二销量和销售额位...
华宝新能:Jackery电小二销量和销售额位于户外电源品类第一:华宝新能 -
波罗的海干散货运价指数录得3月中以来最...
波罗的海干散货运价指数录得3月中以来最大单日涨幅:波罗的海干散货运 -
安德烈·梅斯基塔|每日速看
1、安德烈·梅斯基塔。2、葡萄牙职业足球运动员。文章到此就分享结... -
爱心送考,护航莘莘学子,六个核桃助力...
文:向善财经作者:刘能高考对每个学子来说都是一次人生考验。十年寒窗 -
发力年轻职场用户群体,联想发布多款昭...
新京报贝壳财经讯(记者许诺)6月6日,联想在北京举办了2023联想商用产 -
安德烈·沃隆科夫
1、安德烈·沃隆科夫是一名白俄罗斯籍足球运动员。2、球场位置是前... -
恒立实业回复深交所关注函:第一和第二...
6月6日,恒立实业就深交所此前下发的关注函进行回复,内容包括相关股东 -
海目星:公司拟回购不超过279.72万股公...
海目星6月7日发布股份回购公告,公司拟于2023年6月3日至2024年6月2日完 -
吉利解盘:炒股的最高境界是会等待时机...
这两天怎么又不发文了?上周五写了“注意开始调整的及时落袋”周一... -
海贼王1086:炽天使老沙、明哥和莫利亚...
海贼王1086话 海贼王漫画1086话,内容真的太过丰富了,五老星名字曝光 -
每日头条!双侧附件囊肿怎么引起的_左侧...
1、左侧附件囊肿是指左侧卵巢囊肿,可发生于任何年龄,多发生于生育年 -
安德烈·波佐 全球讯息
1、安德烈·波佐是一位意大利画家。文章到此就分享结束,希望对大家... -
富邦保险官网电话_富邦保险官网
1、富邦是一家台资企业,在国了解的人不是太多,但服务及保障对我们车 -
最重要的遇见作文800字初一_遇见作文800...
1、遇见不一样的自己在二十岁之前,我们可以抱怨生活的种种不公,抱怨 -
安德烈·古辛
1、安德烈·古辛于1972年12月11日出生,作为一个进攻型中场队员,他帮 -
今日快看!乳房一个大一个小正常吗?_乳房...
1、乳房有大有小,在正常人身上也能看到,与发育有关,受家族遗传因素 -
全球实时:形容夏天的美好景象的成语_形...
1、火轮高吐:太阳在空中,发散炽热旳温度。2、 2、冬日夏云:冬天 -
安德烈·德尔沃
1、《安德烈·德尔沃》是华东师范大学出版社出版的图书。2、作者是... -
加计扣除100%怎么计算_加计扣除 每日热点
1、这是税法上的概念会计上无此概念如企业安置残疾人全年支付工资12000 -
热点在线丨广东用海用岛政策将向县域主...
今年6月8日是第十五个“世界海洋日”和第十六个“全国海洋宣传日”... -
法拉第常数怎么算出来的_法拉第常数|全...
1、最新数据为96485 3383物理化学计算中用96500即可。本文分享完毕,希 -
李炯毅|大道至简—2023年度中国书画名...
【个人简介】李炯毅,博士。博士毕业于中国艺术研究院山水画实践类,师 -
每天早上吃生姜的功效与作用_早上吃生姜...
1、古人云:“早上吃姜,胜过吃参汤;晚上吃姜,等于吃砒霜(早上吃... -
世界实时:生吃苦瓜的功效与作用中医_生...
生吃苦瓜的功效与作用:1 生吃苦瓜,最大限度保留苦瓜中所含的维生素C -
环球热讯:比亚迪已成立方程豹汽车销售公司
比亚迪F品牌或定名方程豹 据报道,比亚迪此前宣布将推全新“F品... -
天天关注:眼睛酸痛怎么办怎么缓解_烧电...
1、病情分析:电焊后眼睛疼痛往往是电光性眼炎引起的。2、这种情况不要 -
【播资讯】艾滋病患者舌头是什么样的_艾...
1、艾滋病患者的舌苔上没有什么特别的症状。艾滋病患者在急性感染艾滋 -
世界热头条丨酒品代表国家文化?这4大不...
酒品代表国家文化?这4大不同国家的饮酒文化差异,太有趣了!你是否曾 -
网络语不感冒是什么意思 对某人某事不...
想必现在有很多小伙伴对于网络语不感冒是什么意思(对某人某事不太感冒 -
义理易学分为_义理 天天观点
1、【日文】義理(ぎり)【中文】翻译成礼仪廉耻的道德常识比较可以理 -
朗进科技:于2023年1月至6月与欧洲客户A...
朗进科技:于2023年1月至6月与欧洲客户A签订三份《设备采购合同》:朗 -
全球热讯:中泰化学(002092.SZ)控股股东...
智通财经APP讯,中泰化学(002092)(002092 SZ)公告,公司控股股东中泰集 -
福特汽车公司即将达成一项出售德国工厂...
福特汽车公司即将达成一项出售德国工厂的协议,据悉两个来自中国的汽车 -
天天最资讯丨贵州省黔西南布依族苗族自...
音频解说一、贵州省黔西南布依族苗族自治州望谟县天气预报1、望谟县气 -
安德烈·汉森
1、安德烈·汉森,是一名挪威足球运动员。2、2022年5月24日,入选挪威 -
今日播报!云南省红河哈尼族彝族自治州泸...
音频解说一、云南省红河哈尼族彝族自治州泸西县天气预报1、泸西县气象 -
安德烈·古尔斯基
1、安德烈·古尔斯基是乌克兰的一名惯用右脚的后卫足球运动员。文章... -
民间出口商报告向西班牙出口销售16.5万...
民间出口商报告向西班牙出口销售16 5万吨大豆金十期货6月6日讯,美国农 -
广东省河源市2023-06-06 16:14发布雷雨...
音频解说一、广东省河源市天气预报受不断生成北抬的对流云团影响,预计 -
全球实时:随着工人返岗,马来西亚棕榈...
随着工人返岗,马来西亚棕榈油产量料大幅上升金十期货6月6日讯,据外媒 -
手绘板绘画教程网_手绘板绘画教程
1、那啥……不习惯用手绘板这种情况也不是你一个人才有的,所有人都... -
【世界热闻】14万元的比亚迪在海外乱杀...
14万元的比亚迪在海外乱杀比国内贵十几万依然销量第一 -
扑朔迷离!长安汽车回应克扣10%货款:不...
扑朔迷离!长安汽车回应克扣10%货款:不知道谁发的