asrpro softspi SD卡读写

采样 50M 1M;采样时间足够长,采样频率1M 避免信息遗漏

引脚  cs pa2 mosi pa3 sck pa5 miso pa6 vcc ->5v gnd ->gnd 

ARDUINO SD库与移植(原本是打算移值tw ch32v103的sd库的,但没有对比,只能选择arduino ; 

对 #define USE_SPI_LIB   ;USE_SPI_LIB进行注释 ,不使用原代码 ,再进行修改(原为使用硬件 与软件 spi代码 

对 sd2card.h cpp 进行修改 修改send recv 函数,替换

注释 #include "arduino.h"

及其它一些细节 

注释  //#error Architecture or board not supported.

1.问题 io口导致的 ;逻辑分析仪查看输出 对比arduino 输出 

模拟spi输出 波形(逻辑分析仪查看) 产生额外的干扰波纹,导致无法初始化成功;

混乱的输出与digitalWrite(xx,1);

输出引脚

  pinMode(2,output);  //cssetPinFun(2,0);digitalWrite(2,1);pinMode(3,output);  //mosisetPinFun(3,0);digitalWrite(3,1);pinMode(5,output);  //scksetPinFun(5,0);digitalWrite(5,1);pinMode(6,input);  //misodpmu_set_io_pull(pinToFun[6],DPMU_IO_PULL_UP);

移值arduino SD2时 修改 sd2card.cpp sd2card.h ;(可以使用官方的 asr_softspi库 进行修改 ,模拟为1 ,1 ;sck 之后添加 延时 delay100us; 

对主要函数  spiRec spiSend 进行修改 (速度与调整delay) 或用sleep1;(*delay5us 可以 sleep1(100)不行 

void sleep1(uint8_t t)
{while(t>0)t--;
}//------------------------------------------------------------------------------
/** Soft SPI receive */
uint8_t spiRec(void) {uint8_t data = 0;// no interrupts during byte receive - about 8 us// cli();//eclic_global_interrupt_disable();//eclic_global_interrupt_disable();// output pin high - like sending 0XFFdigitalWrite(SPI_MOSI_PIN, HIGH);//sleep1(speed);for (uint8_t i = 0; i < 8; i++) {digitalWrite(SPI_SCK_PIN, HIGH);// adjust so SCK is nicenop;nop;//sleep1(speed);data <<= 1;if (digitalRead(SPI_MISO_PIN)) {data |= 1;}digitalWrite(SPI_SCK_PIN, LOW);delay100us();}// enable interrupts//sei();// eclic_global_interrupt_enable();return data;
}
//------------------------------------------------------------------------------
/** Soft SPI send */
void spiSend(uint8_t data) {// no interrupts during byte send - about 8 us// cli();for (uint8_t i = 0; i < 8; i++) {digitalWrite(SPI_SCK_PIN, LOW);//sleep1(speed);delay100us();digitalWrite(SPI_MOSI_PIN, data & 0X80);delay100us();data <<= 1;digitalWrite(SPI_SCK_PIN, HIGH);//sleep1(speed);delay100us();}// hold SCK high for a few nsnop;nop;nop;nop;digitalWrite(SPI_SCK_PIN, LOW);delay100us();delay100us();// enable interrupts//sei();//eclic_global_interrupt_enable();
}

------------------------------------------------------------------------------------------------------------------------------

复制arduino sd库目录下的

到 asrpro myLib 下

1.修改 office 下地的  source_file.prj  添加如下语句

source-file: ../myLib/Sd2Card.cpp (原名SdCard
source-file: ../myLib/SdFile.cpp
source-file: ../myLib/SdVolume.cpp

2 asr.cpp 测试代码 如下

3.修改 sdCard.cpp

#include "asr.h"
extern "C"{ void * __dso_handle = 0 ;}
#include "setup.h"
//#include "SD2Card.h"
#include "SD2.h"uint32_t snid;
void ASR_CODE();
Sd2Card card;
SdVolume volume;
SdFile root;//{speak:小蝶-清新女声,vol:10,speed:10,platform:haohaodada}
//{playid:10001,voice:欢迎使用语音助手,用天问五幺唤醒我。}
//{playid:10002,voice:我退下了,用天问五幺唤醒我}/*描述该功能...
*/
void ASR_CODE(){//本函数是语音识别成功钩子程序//运行时间越短越好,复杂控制启动新线程运行//唤醒时间设置必须在ASR_CODE中才有效set_state_enter_wakeup(10000);//用switch分支选择,根据不同的识别成功的ID执行相应动作,点击switch左上齿轮//可以增加分支项switch (snid) {case 1:digitalWrite(4,0);break;case 2:digitalWrite(4,1);break;}//除了switch分支选择,也可用如果判断识别ID的值来执行动作if((snid) == 3){digitalWrite(4,0);}if((snid) == 4){digitalWrite(4,1);}//采用如果判断模块,可更方便复制}int chipSelect = 2;void hardware_init(){//需要操作系统启动后初始化的内容//音量范围1-7vol_set(1);Serial.begin(9600);delay(200);Serial.print("\nInitializing SD card...");// we'll use the initialization code from the utility libraries// since we're just testing if the card is working!if (!card.init(SPI_HALF_SPEED, chipSelect)) {Serial.println("initialization failed. Things to check:");Serial.println("* is a card inserted?");Serial.println("* is your wiring correct?");Serial.println("* did you change the chipSelect pin to match your shield or module?");while (1);} else {Serial.println("Wiring is correct and a card is present.");}// print the type of cardSerial.println();Serial.print("Card type:         ");switch (card.type()) {case SD_CARD_TYPE_SD1:Serial.println("SD1");break;case SD_CARD_TYPE_SD2:Serial.println("SD2");break;case SD_CARD_TYPE_SDHC:Serial.println("SDHC");break;default:Serial.println("Unknown");}//  Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32if (!volume.init(card)) {Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");while (1);}Serial.print("Clusters:          ");Serial.println(volume.clusterCount());Serial.print("Blocks x Cluster:  ");Serial.println(volume.blocksPerCluster());Serial.print("Total Blocks:      ");Serial.println(volume.blocksPerCluster() * volume.clusterCount());Serial.println();// print the type and size of the first FAT-type volumeuint32_t volumesize;Serial.print("Volume type is:    FAT");Serial.println(volume.fatType(), DEC);volumesize = volume.blocksPerCluster();    // clusters are collections of blocksvolumesize *= volume.clusterCount();       // we'll have a lot of clustersvolumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)Serial.print("Volume size (Kb):  ");Serial.println(volumesize);Serial.print("Volume size (Mb):  ");volumesize /= 1024;Serial.println(volumesize);Serial.print("Volume size (Gb):  ");Serial.println((float)volumesize / 1024.0);Serial.println("\nFiles found on the card (name, date and size in bytes): ");root.openRoot(volume);// list all files in the card with date and sizeroot.ls(LS_R | LS_DATE | LS_SIZE);vTaskDelete(NULL);
}void setup()
{//需要操作系统启动前初始化的内容//播报音下拉菜单可以选择,合成音量是指TTS生成文件的音量//欢迎词指开机提示音,可以为空//退出语音是指休眠时提示音,可以为空//休眠后用唤醒词唤醒后才能执行命令,唤醒词最多5个。回复语可以空。ID范围为0-9999//{ID:0,keyword:"唤醒词",ASR:"天问五幺",ASRTO:"我在"}//{ID:1,keyword:"命令词",ASR:"打开灯光",ASRTO:"好的,马上打开灯光"}//{ID:2,keyword:"命令词",ASR:"关闭灯光",ASRTO:"好的,马上关闭灯光"}//{ID:3,keyword:"命令词",ASR:"灯光打开",ASRTO:"好的,马上打开灯光"}//{ID:4,keyword:"命令词",ASR:"灯光关闭",ASRTO:"好的,马上关闭灯光"}pinMode(2,output);  //cssetPinFun(2,0);digitalWrite(2,1);pinMode(3,output);  //mosisetPinFun(3,0);digitalWrite(3,1);pinMode(5,output);  //scksetPinFun(5,0);digitalWrite(5,1);pinMode(6,input);  //misodpmu_set_io_pull(pinToFun[6],DPMU_IO_PULL_UP);}
//Sd2Card.cpp#include "Sd2Card.h"//#define chipSelectPin_ 4  // 4 5 6 7 #ifndef __SD2Card 
#define __SD2Card// #define SPI_MOSI_PIN 3
// #define SPI_SCK_PIN 5
// #define SPI_MISO_PIN 6//------------------------------------------------------------------------------// functions for hardware SPI
/** Send a byte to the card */
// static void spiSend(uint8_t b) {
//   #ifndef USE_SPI_LIB
//   SPDR = b;
//   while (!(SPSR & (1 << SPIF)))
//     ;
//   #else
//   SDCARD_SPI.transfer(b);
//   #endif
// }
// /** Receive a byte from the card */
// static  uint8_t spiRec(void) {
//   #ifndef USE_SPI_LIB
//   spiSend(0XFF);
//   return SPDR;
//   #else
//   return SDCARD_SPI.transfer(0xFF);
//   #endif
// }
// #else  // 
void usleep(uint8_t t)
{while(t>0)t--;}
//----------------------SOFTWARE_SPI--------------------------------------------------------
/** nop to tune soft SPI timing */
#define nop asm volatile ("nop\n\t")
//------------------------------------------------------------------------------
/** Soft SPI receive */
void sleep1(uint8_t t)
{while(t>0)t--;
}//------------------------------------------------------------------------------
/** Soft SPI receive */
uint8_t spiRec(void) {uint8_t data = 0;// no interrupts during byte receive - about 8 us// cli();//eclic_global_interrupt_disable();//eclic_global_interrupt_disable();// output pin high - like sending 0XFFdigitalWrite(SPI_MOSI_PIN, HIGH);//sleep1(speed);for (uint8_t i = 0; i < 8; i++) {digitalWrite(SPI_SCK_PIN, HIGH);// adjust so SCK is nicenop;nop;//sleep1(speed);data <<= 1;if (digitalRead(SPI_MISO_PIN)) {data |= 1;}digitalWrite(SPI_SCK_PIN, LOW);delay100us();}// enable interrupts//sei();// eclic_global_interrupt_enable();return data;
}
//------------------------------------------------------------------------------
/** Soft SPI send */
void spiSend(uint8_t data) {// no interrupts during byte send - about 8 us// cli();for (uint8_t i = 0; i < 8; i++) {digitalWrite(SPI_SCK_PIN, LOW);//sleep1(speed);delay100us();digitalWrite(SPI_MOSI_PIN, data & 0X80);delay100us();data <<= 1;digitalWrite(SPI_SCK_PIN, HIGH);//sleep1(speed);delay100us();}// hold SCK high for a few nsnop;nop;nop;nop;digitalWrite(SPI_SCK_PIN, LOW);delay100us();delay100us();// enable interrupts//sei();//eclic_global_interrupt_enable();
}//------------------------------------------------------------------------------
// send command and return error code.  Return zero for OK
uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {// end read if in partialBlockRead modereadEnd();// select cardchipSelectLow();// wait up to 300 ms if busywaitNotBusy(300);// send commandspiSend(cmd | 0x40);// send argumentfor (int8_t s = 24; s >= 0; s -= 8) {spiSend(arg >> s);}// send CRCuint8_t crc = 0XFF;if (cmd == CMD0) {crc = 0X95;  // correct crc for CMD0 with arg 0}if (cmd == CMD8) {crc = 0X87;  // correct crc for CMD8 with arg 0X1AA}spiSend(crc);// wait for responsefor (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++);return status_;
}
//------------------------------------------------------------------------------
/**Determine the size of an SD flash memory card.\return The number of 512 byte data blocks in the cardor zero if an error occurs.
*/
uint32_t Sd2Card::cardSize(void) {csd_t csd;if (!readCSD(&csd)) {return 0;}if (csd.v1.csd_ver == 0) {uint8_t read_bl_len = csd.v1.read_bl_len;uint16_t c_size = (csd.v1.c_size_high << 10)| (csd.v1.c_size_mid << 2) | csd.v1.c_size_low;uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1)| csd.v1.c_size_mult_low;return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7);} else if (csd.v2.csd_ver == 1) {uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16)| (csd.v2.c_size_mid << 8) | csd.v2.c_size_low;return (c_size + 1) << 10;} else {error(SD_CARD_ERROR_BAD_CSD);return 0;}
}
//------------------------------------------------------------------------------
static uint8_t chip_select_asserted = 0;void Sd2Card::chipSelectHigh(void) {digitalWrite(chipSelectPin_, HIGH);// #ifdef USE_SPI_LIB// if (chip_select_asserted) {//   chip_select_asserted = 0;//   SDCARD_SPI.endTransaction();// }// #endif
}
//------------------------------------------------------------------------------
void Sd2Card::chipSelectLow(void) {// #ifdef USE_SPI_LIB// if (!chip_select_asserted) {//   chip_select_asserted = 1;//   SDCARD_SPI.beginTransaction(settings);// }// #endifdigitalWrite(chipSelectPin_, LOW);
}
//------------------------------------------------------------------------------
/** Erase a range of blocks.\param[in] firstBlock The address of the first block in the range.\param[in] lastBlock The address of the last block in the range.\note This function requests the SD card to do a flash erase for arange of blocks.  The data on the card after an erase operation iseither 0 or 1, depends on the card vendor.  The card must supportsingle block erase.\return The value one, true, is returned for success andthe value zero, false, is returned for failure.
*/
uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {if (!eraseSingleBlockEnable()) {error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);goto fail;}if (type_ != SD_CARD_TYPE_SDHC) {firstBlock <<= 9;lastBlock <<= 9;}if (cardCommand(CMD32, firstBlock)|| cardCommand(CMD33, lastBlock)|| cardCommand(CMD38, 0)) {error(SD_CARD_ERROR_ERASE);goto fail;}if (!waitNotBusy(SD_ERASE_TIMEOUT)) {error(SD_CARD_ERROR_ERASE_TIMEOUT);goto fail;}chipSelectHigh();return true;fail:chipSelectHigh();return false;
}
//------------------------------------------------------------------------------
/** Determine if card supports single block erase.\return The value one, true, is returned if single block erase is supported.The value zero, false, is returned if single block erase is not supported.
*/
uint8_t Sd2Card::eraseSingleBlockEnable(void) {csd_t csd;return readCSD(&csd) ? csd.v1.erase_blk_en : 0;
}
//------------------------------------------------------------------------------
/**Initialize an SD flash memory card.\param[in] sckRateID SPI clock rate selector. See setSckRate().\param[in] chipSelectPin SD chip select pin number.\return The value one, true, is returned for success andthe value zero, false, is returned for failure.  The reason for failurecan be determined by calling errorCode() and errorData().
*/
uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;chipSelectPin_ = chipSelectPin;// 16-bit init start time allows over a minuteuint32_t arg;// set pin modes// pinMode(chipSelectPin_, OUTPUT);// pinMode(SPI_MISO_PIN, INPUT);// pinMode(SPI_MOSI_PIN, OUTPUT);// pinMode(SPI_SCK_PIN, OUTPUT);digitalWrite(chipSelectPin_, HIGH);// #ifndef USE_SPI_LIB//*********for (uint8_t i = 0; i < 10; i++) {spiSend(0XFF);}unsigned int t0 = millis();chipSelectLow();// command to go idle in SPI modewhile ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {unsigned int d = millis() - t0;if (d > SD_INIT_TIMEOUT) {error(SD_CARD_ERROR_CMD0);goto fail;}}// check SD versionif ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {type(SD_CARD_TYPE_SD1);} else {// only need last byte of r7 responsefor (uint8_t i = 0; i < 4; i++) {status_ = spiRec();}if (status_ != 0XAA) {error(SD_CARD_ERROR_CMD8);goto fail;}type(SD_CARD_TYPE_SD2);}// initialize card and send host supports SDHC if SD2arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {// check for timeoutunsigned int d = millis() - t0;if (d > SD_INIT_TIMEOUT) {error(SD_CARD_ERROR_ACMD41);goto fail;}}// if SD2 read OCR register to check for SDHC cardif (type() == SD_CARD_TYPE_SD2) {if (cardCommand(CMD58, 0)) {error(SD_CARD_ERROR_CMD58);goto fail;}if ((spiRec() & 0XC0) == 0XC0) {type(SD_CARD_TYPE_SDHC);}// discard rest of ocr - contains allowed voltage rangefor (uint8_t i = 0; i < 3; i++) {spiRec();}}chipSelectHigh();// #ifndef SOFTWARE_SPI//return setSckRate(sckRateID);// #else  // SOFTWARE_SPIreturn true;// #endif  // SOFTWARE_SPIfail:chipSelectHigh();return false;
}//   errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
//   chipSelectPin_ = chipSelectPin;
//   // 16-bit init start time allows over a minute
//   unsigned int t0 = millis();
//   uint32_t arg;//   // set pin modes
//   pinMode(chipSelectPin_, OUTPUT);
//   digitalWrite(chipSelectPin_, HIGH);
//  // #ifndef USE_SPI_LIB
//   pinMode(SPI_MISO_PIN, INPUT);
//   pinMode(SPI_MOSI_PIN, OUTPUT);
//   pinMode(SPI_SCK_PIN, OUTPUT);
//  // #endif//   // #ifndef SOFTWARE_SPI
//   // #ifndef USE_SPI_LIB
//   // // SS must be in output mode even it is not chip select
//   // pinMode(SS_PIN, OUTPUT);
//   // digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
//   // // Enable SPI, Master, clock rate f_osc/128
//   // SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
//   // // clear double speed
//   // SPSR &= ~(1 << SPI2X);
//   // #else // USE_SPI_LIB
//   // SDCARD_SPI.begin();
//   // settings = SPISettings(250000, MSBFIRST, SPI_MODE0);
//   // #endif // USE_SPI_LIB
//   // #endif // SOFTWARE_SPI//   // // must supply min of 74 clock cycles with CS high.
//   // #ifdef USE_SPI_LIB
//   // SDCARD_SPI.beginTransaction(settings);
//   // #endif
//   for (uint8_t i = 0; i < 10; i++) {
//     spiSend(0XFF);
//   }
//   // #ifdef USE_SPI_LIB
//   // SDCARD_SPI.endTransaction();
//   // #endif//   chipSelectLow();//   // command to go idle in SPI mode
//   while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
//     unsigned int d = millis() - t0;
//     if (d > SD_INIT_TIMEOUT) {
//       error(SD_CARD_ERROR_CMD0);
//       goto fail;
//     }
//   }
//   // check SD version
//   if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
//     type(SD_CARD_TYPE_SD1);
//   } else {
//     // only need last byte of r7 response
//     for (uint8_t i = 0; i < 4; i++) {
//       status_ = spiRec();
//     }
//     if (status_ != 0XAA) {
//       error(SD_CARD_ERROR_CMD8);
//       goto fail;
//     }
//     type(SD_CARD_TYPE_SD2);
//   }
//   // initialize card and send host supports SDHC if SD2
//   arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;//   while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
//     // check for timeout
//     unsigned int d = millis() - t0;
//     if (d > SD_INIT_TIMEOUT) {
//       error(SD_CARD_ERROR_ACMD41);
//       goto fail;
//     }
//   }
//   // if SD2 read OCR register to check for SDHC card
//   if (type() == SD_CARD_TYPE_SD2) {
//     if (cardCommand(CMD58, 0)) {
//       error(SD_CARD_ERROR_CMD58);
//       goto fail;
//     }
//     if ((spiRec() & 0XC0) == 0XC0) {
//       type(SD_CARD_TYPE_SDHC);
//     }
//     // discard rest of ocr - contains allowed voltage range
//     for (uint8_t i = 0; i < 3; i++) {
//       spiRec();
//     }
//   }
//   chipSelectHigh();//   #ifndef SOFTWARE_SPI
//   return setSckRate(sckRateID);
//   #else  // SOFTWARE_SPI
//   return true;
//   #endif  // SOFTWARE_SPI// fail:
//   chipSelectHigh();
//   return false;
// }
//------------------------------------------------------------------------------
/**Enable or disable partial block reads.Enabling partial block reads improves performance by allowing a blockto be read over the SPI bus as several sub-blocks.  Errors may occurif the time between reads is too long since the SD card may timeout.The SPI SS line will be held low until the entire block is read orreadEnd() is called.Use this for applications like the Adafruit Wave Shield.\param[in] value The value TRUE (non-zero) or FALSE (zero).)
*/
void Sd2Card::partialBlockRead(uint8_t value) {readEnd();partialBlockRead_ = value;
}
//------------------------------------------------------------------------------
/**Read a 512 byte block from an SD card device.\param[in] block Logical block to be read.\param[out] dst Pointer to the location that will receive the data.\return The value one, true, is returned for success andthe value zero, false, is returned for failure.
*/
uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) {return readData(block, 0, 512, dst);
}
//------------------------------------------------------------------------------
/**Read part of a 512 byte block from an SD card.\param[in] block Logical block to be read.\param[in] offset Number of bytes to skip at start of block\param[out] dst Pointer to the location that will receive the data.\param[in] count Number of bytes to read\return The value one, true, is returned for success andthe value zero, false, is returned for failure.
*/
uint8_t Sd2Card::readData(uint32_t block,uint16_t offset, uint16_t count, uint8_t* dst) {if (count == 0) {return true;}if ((count + offset) > 512) {goto fail;}if (!inBlock_ || block != block_ || offset < offset_) {block_ = block;// use address if not SDHC cardif (type() != SD_CARD_TYPE_SDHC) {block <<= 9;}if (cardCommand(CMD17, block)) {error(SD_CARD_ERROR_CMD17);goto fail;}if (!waitStartBlock()) {goto fail;}offset_ = 0;inBlock_ = 1;}#ifdef OPTIMIZE_HARDWARE_SPI// start first spi transferSPDR = 0XFF;// skip data before offsetfor (; offset_ < offset; offset_++) {while (!(SPSR & (1 << SPIF)));SPDR = 0XFF;}// transfer datan = count - 1;for (uint16_t i = 0; i < n; i++) {while (!(SPSR & (1 << SPIF)));dst[i] = SPDR;SPDR = 0XFF;}// wait for last bytewhile (!(SPSR & (1 << SPIF)));dst[n] = SPDR;#else  // OPTIMIZE_HARDWARE_SPI// skip data before offsetfor (; offset_ < offset; offset_++) {spiRec();}// transfer datafor (uint16_t i = 0; i < count; i++) {dst[i] = spiRec();}#endif  // OPTIMIZE_HARDWARE_SPIoffset_ += count;if (!partialBlockRead_ || offset_ >= 512) {// read rest of data, checksum and set chip select highreadEnd();}return true;fail:chipSelectHigh();return false;
}
//------------------------------------------------------------------------------
/** Skip remaining data in a block when in partial block read mode. */
void Sd2Card::readEnd(void) {if (inBlock_) {// skip data and crc#ifdef OPTIMIZE_HARDWARE_SPI// optimize skip for hardwareSPDR = 0XFF;while (offset_++ < 513) {while (!(SPSR & (1 << SPIF)));SPDR = 0XFF;}// wait for last crc bytewhile (!(SPSR & (1 << SPIF)));#else  // OPTIMIZE_HARDWARE_SPIwhile (offset_++ < 514) {spiRec();}#endif  // OPTIMIZE_HARDWARE_SPIchipSelectHigh();inBlock_ = 0;}
}
//------------------------------------------------------------------------------
/** read CID or CSR register */
uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {uint8_t* dst = reinterpret_cast<uint8_t*>(buf);if (cardCommand(cmd, 0)) {error(SD_CARD_ERROR_READ_REG);goto fail;}if (!waitStartBlock()) {goto fail;}// transfer datafor (uint16_t i = 0; i < 16; i++) {dst[i] = spiRec();}spiRec();  // get first crc bytespiRec();  // get second crc bytechipSelectHigh();return true;fail:chipSelectHigh();return false;
}
//------------------------------------------------------------------------------
/**Set the SPI clock rate.\param[in] sckRateID A value in the range [0, 6].The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximumSPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128for \a scsRateID = 6.\return The value one, true, is returned for success and the value zero,false, is returned for an invalid value of \a sckRateID.
*/
uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {if (sckRateID > 6) {error(SD_CARD_ERROR_SCK_RATE);return false;}// #ifndef USE_SPI_LIB// // see avr processor datasheet for SPI register bit definitions// if ((sckRateID & 1) || sckRateID == 6) {//   SPSR &= ~(1 << SPI2X);// } else {//   SPSR |= (1 << SPI2X);// }// SPCR &= ~((1 << SPR1) | (1 << SPR0));// SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)//         | (sckRateID & 2 ? (1 << SPR0) : 0);// #else // USE_SPI_LIB// switch (sckRateID) {//   case 0:  settings = SPISettings(25000000, MSBFIRST, SPI_MODE0); break;//   case 1:  settings = SPISettings(4000000, MSBFIRST, SPI_MODE0); break;//   case 2:  settings = SPISettings(2000000, MSBFIRST, SPI_MODE0); break;//   case 3:  settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); break;//   case 4:  settings = SPISettings(500000, MSBFIRST, SPI_MODE0); break;//   case 5:  settings = SPISettings(250000, MSBFIRST, SPI_MODE0); break;//   default: settings = SPISettings(125000, MSBFIRST, SPI_MODE0);// }// #endif // USE_SPI_LIBreturn true;
}
#ifdef USE_SPI_LIB
//------------------------------------------------------------------------------
// set the SPI clock frequency
uint8_t Sd2Card::setSpiClock(uint32_t clock) {// settings = SPISettings(clock, MSBFIRST, SPI_MODE0);return true;
}
#endif
//------------------------------------------------------------------------------
// wait for card to go not busy
uint8_t Sd2Card::waitNotBusy(unsigned int timeoutMillis) {unsigned int t0 = millis();unsigned int d;do {if (spiRec() == 0XFF) {return true;}d = millis() - t0;} while (d < timeoutMillis);return false;
}
//------------------------------------------------------------------------------
/** Wait for start block token */
uint8_t Sd2Card::waitStartBlock(void) {unsigned int t0 = millis();while ((status_ = spiRec()) == 0XFF) {unsigned int d = millis() - t0;if (d > SD_READ_TIMEOUT) {error(SD_CARD_ERROR_READ_TIMEOUT);goto fail;}}if (status_ != DATA_START_BLOCK) {error(SD_CARD_ERROR_READ);goto fail;}return true;fail:chipSelectHigh();return false;
}
//------------------------------------------------------------------------------
/**Writes a 512 byte block to an SD card.\param[in] blockNumber Logical block to be written.\param[in] src Pointer to the location of the data to be written.\param[in] blocking If the write should be blocking.\return The value one, true, is returned for success andthe value zero, false, is returned for failure.
*/
uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src, uint8_t blocking) {#if SD_PROTECT_BLOCK_ZERO// don't allow write to first blockif (blockNumber == 0) {error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);goto fail;}#endif  // SD_PROTECT_BLOCK_ZERO// use address if not SDHC cardif (type() != SD_CARD_TYPE_SDHC) {blockNumber <<= 9;}if (cardCommand(CMD24, blockNumber)) {error(SD_CARD_ERROR_CMD24);goto fail;}if (!writeData(DATA_START_BLOCK, src)) {goto fail;}if (blocking) {// wait for flash programming to completeif (!waitNotBusy(SD_WRITE_TIMEOUT)) {error(SD_CARD_ERROR_WRITE_TIMEOUT);goto fail;}// response is r2 so get and check two bytes for nonzeroif (cardCommand(CMD13, 0) || spiRec()) {error(SD_CARD_ERROR_WRITE_PROGRAMMING);goto fail;}}chipSelectHigh();return true;fail:chipSelectHigh();return false;
}
//------------------------------------------------------------------------------
/** Write one data block in a multiple block write sequence */
uint8_t Sd2Card::writeData(const uint8_t* src) {// wait for previous write to finishif (!waitNotBusy(SD_WRITE_TIMEOUT)) {error(SD_CARD_ERROR_WRITE_MULTIPLE);chipSelectHigh();return false;}return writeData(WRITE_MULTIPLE_TOKEN, src);
}
//------------------------------------------------------------------------------
// send one block of data for write block or write multiple blocks
uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {#ifdef OPTIMIZE_HARDWARE_SPI// send data - optimized loopSPDR = token;// send two byte per iterationfor (uint16_t i = 0; i < 512; i += 2) {while (!(SPSR & (1 << SPIF)));SPDR = src[i];while (!(SPSR & (1 << SPIF)));SPDR = src[i + 1];}// wait for last data bytewhile (!(SPSR & (1 << SPIF)));#else  // OPTIMIZE_HARDWARE_SPIspiSend(token);for (uint16_t i = 0; i < 512; i++) {spiSend(src[i]);}#endif  // OPTIMIZE_HARDWARE_SPIspiSend(0xff);  // dummy crcspiSend(0xff);  // dummy crcstatus_ = spiRec();if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {error(SD_CARD_ERROR_WRITE);chipSelectHigh();return false;}return true;
}
//------------------------------------------------------------------------------
/** Start a write multiple blocks sequence.\param[in] blockNumber Address of first block in sequence.\param[in] eraseCount The number of blocks to be pre-erased.\note This function is used with writeData() and writeStop()for optimized multiple block writes.\return The value one, true, is returned for success andthe value zero, false, is returned for failure.
*/
uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {#if SD_PROTECT_BLOCK_ZERO// don't allow write to first blockif (blockNumber == 0) {error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);goto fail;}#endif  // SD_PROTECT_BLOCK_ZERO// send pre-erase countif (cardAcmd(ACMD23, eraseCount)) {error(SD_CARD_ERROR_ACMD23);goto fail;}// use address if not SDHC cardif (type() != SD_CARD_TYPE_SDHC) {blockNumber <<= 9;}if (cardCommand(CMD25, blockNumber)) {error(SD_CARD_ERROR_CMD25);goto fail;}return true;fail:chipSelectHigh();return false;
}
//------------------------------------------------------------------------------
/** End a write multiple blocks sequence.\return The value one, true, is returned for success andthe value zero, false, is returned for failure.
*/
uint8_t Sd2Card::writeStop(void) {if (!waitNotBusy(SD_WRITE_TIMEOUT)) {goto fail;}spiSend(STOP_TRAN_TOKEN);if (!waitNotBusy(SD_WRITE_TIMEOUT)) {goto fail;}chipSelectHigh();return true;fail:error(SD_CARD_ERROR_STOP_TRAN);chipSelectHigh();return false;
}
//------------------------------------------------------------------------------
/** Check if the SD card is busy\return The value one, true, is returned when is busy andthe value zero, false, is returned for when is NOT busy.
*/
uint8_t Sd2Card::isBusy(void) {chipSelectLow();char b = spiRec();  //****chipSelectHigh();return (b != 0XFF);
}#endif

加快编译速度的方法 

删除asr_pro_sdk\projects\offline_asr_sample\project_file\build\objs 下对应的 中间文件;

使用./build 一下 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15848.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java进阶学习笔记22——泛型方法、通配符和上下限

泛型方法&#xff1a; package cn.ensource.d11_generics_method;public class Test {public static void main(String[] args) {// 泛型方法String res test("Java");System.out.println(res);Dog dog1 test(new Dog());System.out.println(dog1);}// 泛型方法pub…

手机上制作证件照

最近由于需要给老姐弄一组证件照&#xff0c;找了一通手机上的软件&#xff0c;找到一款性价比较高的&#xff0c;详细流程记录下来。vx小程序上搜索"泰世茂证件照"&#xff0c;打开首页如下图所示∶ 单击"开始制作" &#xff0c;选择一个证件照类别&#…

Paddle 傅里叶变换基础及领域应用

Paddle 傅里叶变换基础及领域应用 1. 傅里叶变换基础 1.1 傅里叶变换简介 傅里叶变换是一种重要的信号处理技术&#xff0c;它可以将一个信号从时域转换到频域。在频域中&#xff0c;信号的频率特性更加明显&#xff0c;有利于分析和处理。傅里叶变换的基本思想是将一个信号…

基于Rsoft的Fullwave仿真模块进行双芯波导能量耦合与波分复用

Rsoft中的Fullwave仿真模块可以更精确的仿真微小结构&#xff0c;按照建立模型&#xff0c;设置参数&#xff0c;监测能量&#xff0c;优化结构的思路对其进行仿真。图1是在Fullwave模块中建立的双芯波导仿真模型。在模型中设置好折射率、光源、光路、监测器等便可以进行仿真。…

【竞技宝】英超:滕哈格命真硬!足总杯夺冠获欧联资格

足总杯决赛结束,曼联爆冷2比1击败联赛冠军曼城夺冠,滕哈格再一次用顶级理解带队拿到杯赛冠军。赛前曼彻斯特当地有媒体爆料,曼联管理层已经决定要在足总杯决赛之后解雇滕哈格,这个消息让不少球迷都很担心滕哈格的状态。但是荷兰主帅凭借强大的内心,带领球队击败了不可一世的曼城…

买房送户口!多城加入“抢人大战”

业内人士认为&#xff0c;近期&#xff0c;多地推出的购房落户政策已区别于此前的人才落户政策&#xff0c;更聚焦于住房消费&#xff0c;降低了落户门槛&#xff0c;体现了各地对导入人口的重视&#xff0c;有利于人才流动&#xff0c;推动新型城镇化建设。 千万人口城市“后…

echarts配置记录,一些已经废弃的写法

1、normal&#xff0c;4.0以后无需将样式写在normal中了 改前&#xff1a; 改后&#xff1a; DEPRECATED: normal hierarchy in labelLine has been removed since 4.0. All style properties are configured in labelLine directly now. 2、axisLabel中的文字样式无需使用te…

文本处理工具grep及sed

文章目录 一、grep文本处理工具二、sed文本处理工具基本用法sed脚本格式搜索替代 一、grep文本处理工具 选项含义-color对匹配到的文本着色显示-m 次数匹配到规定的次数后停止-v显示不被命令匹配到的行,即取反-i忽略字符大小写-n显示匹配的行号-c统计匹配的行数-o仅显示匹配到…

log4j2远程代码执行

漏洞复现 漏洞复现2 这个框架不是web框架了&#xff0c;不是服务器web网站框架了&#xff0c;是java日志框架&#xff0c;就是记录日志信息&#xff0c;每一个程序都有一个日志文件&#xff0c;这个就是java里面记录日志的一个框架&#xff0c;它存在的点也是日志框架那几个代…

我用LLaMA-Factory微调大模型来实现商品评论情感分析,准确率高达91.70%

大家好&#xff0c;我是程序锅。 最近在modelscope上闲逛的时候&#xff0c;在数据集板块发现有一个商品评论情感预测数据集。这个数据集源自一个比赛&#xff0c;它的目的是为了预测电商平台顾客的评论是好评还是差评。 数据示例如下所示&#xff08;其中0代表差评&#xff…

Go 和 Delphi 定义可变参数函数的对比

使用可变参数函数具有灵活性、重用性、简化调用等优点&#xff0c;各个语言有各自定义可变参数函数的方法&#xff0c;也有通用的处理方法&#xff0c;比如使用数组、定义参数结构体、使用泛型等。 这里总结记录一下 go、delphi 的常用的定义可变参数函数的方式&#xff01; 一…

基于图卷积网络的人体3D网格分割

深度学习在 2D 视觉识别任务上取得了巨大成功。十年前被认为极其困难的图像分类和分割等任务&#xff0c;现在可以通过具有类似人类性能的神经网络来解决。这一成功归功于卷积神经网络 (CNN)&#xff0c;它取代了手工制作的描述符。 NSDT工具推荐&#xff1a; Three.js AI纹理开…

1301-习题1-1高等数学

1. 求下列函数的自然定义域 自然定义域就是使函数有意义的定义域。 常见自然定义域&#xff1a; 开根号 x \sqrt x x ​&#xff1a; x ≥ 0 x \ge 0 x≥0自变量为分式的分母 1 x \frac{1}{x} x1​&#xff1a; x ≠ 0 x \ne 0 x0三角函数 tan ⁡ x cot ⁡ x \tan x \cot x …

C++奇迹之旅:vector使用方法以及操作技巧

文章目录 &#x1f4dd;前言&#x1f320; 熟悉vector&#x1f309;使用vector &#x1f320;构造函数&#x1f309;vector遍历 &#x1f320;operator[]&#x1f309;迭代器 &#x1f320;Capacity容量操作&#x1f309; size()&#x1f309; capacity()&#x1f309;resize()…

C语言中的七种常用排序

今天&#xff0c;为大家整理了C语言中几种常用的排序&#xff0c;以及他们在实际中的运用&#xff08;有Bug请在下方评论&#xff09;&#xff1a; 一.桶排序 #include <stdio.h> int main() {int book[1001],i,j,t,n;for(i0;i<1000;i)book[i]0;scanf("%d"…

二进制中1的个数c++

题目描述 计算鸭给定一个十进制非负整数 NN&#xff0c;求其对应 22 进制数中 11 的个数。 输入 输入包含一行&#xff0c;包含一个非负整数 NN。(N < 10^9) 输出 输出一行&#xff0c;包含一个整数&#xff0c;表示 NN 的 22 进制表示中 11 的个数。 样例输入 100 …

001集—创建、写入、读取文件fileopen函数——vb.net

此实例为在指定路径下创建一个txt文本文件&#xff0c;在文本文件内输入文字&#xff0c;并弹窗显示输入文字&#xff0c;代码如下&#xff1a; Public Class Form1Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.ClickDim testcontent As Str…

英语学习笔记26——Where is it?

Where is it? 它在那里&#xff1f; 课文部分

springboot+vue+mybatis校园兼职平台+PPT+论文+讲解+售后

社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个学生的使用。互联网具有便利性&#xff0c;速度快&#xff0c;效率高&#xff0c;成本低等优点。 因此&#xff0c;构建符合自己要…