KamilSafin 0 2 марта, 2017 Опубликовано 2 марта, 2017 · Жалоба Пытаюсь общаться по SPI с внешней флеш памятью at45db081 Инициализация SPI: void spi_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); port.GPIO_Mode = GPIO_Mode_AF_PP; port.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; port.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &port); port.GPIO_Mode = GPIO_Mode_Out_PP; port.GPIO_Pin = GPIO_Pin_4; port.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &port); SPI_StructInit(&spi); spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex; spi.SPI_Mode = SPI_Mode_Master; spi.SPI_DataSize = SPI_DataSize_8b; spi.SPI_CPOL = SPI_CPOL_Low; spi.SPI_CPHA = SPI_CPHA_2Edge; spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; spi.SPI_FirstBit = SPI_FirstBit_MSB; spi.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &spi); SPI_Cmd(SPI1, ENABLE); SPI_DataSizeConfig(SPI1, ENABLE); } отсылка и прием байта данных: uint8_t sendByte(uint8_t byteToSend) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, byteToSend); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return (uint8_t)SPI_I2S_ReceiveData(SPI1); } В main пробую записать в начало памяти одну страницу данных (команда 0x85, три байта адреса и посылка), прочитать статусный регистр (команда 0xD7 - регистр читается, память не занята), а потом пробую читать с самого начала памяти (команда 0xE8, три байта адреса и 4 незначащих) - но принимаются одни и те же данные, независимого от того, что писал, т.е. это даже не прием данных: int main(void) { SetSysClockTo72(); spi_init(); uint8_t data= 0; GPIO_ResetBits(GPIOA, GPIO_Pin_4); data = sendByte(0x85); data = sendByte(0x00); data = sendByte(0x00); data = sendByte(0x00); for (int i = 0; i < 264; i++) { data = sendByte(0xEE); } GPIO_SetBits(GPIOA, GPIO_Pin_4); for (int i = 0; i < 1000; i++); GPIO_ResetBits(GPIOA, GPIO_Pin_4); sendByte(0xD7); data = sendByte(DUMMY); // чтение статусного регистра GPIO_SetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_4); sendByte(0xE8); sendByte(0x00); sendByte(0x00); sendByte(0x00); sendByte(0x00); sendByte(0x00); sendByte(0x00); sendByte(0x00); while(1) { data = sendByte(DUMMY); } } прием проверяю через debug в CooCox гугление и поиск по форуму не помогли, не могу найти видимо какую то глупую ошибку Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lmx2315 2 2 марта, 2017 Опубликовано 2 марта, 2017 · Жалоба Я сам не применял, но вроде код ниже это для общения с подобной флешкой: u8 SPI_Send(u8 data) { WDG_func(); SPI_I2S_SendData(SPI2, data); // отправили данные while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){Circl_FUNC ();}; // ждём, пока данные не отправятся while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){Circl_FUNC ();}; // ждём пока данные появятся u8 received = SPI_I2S_ReceiveData(SPI2); return received; } //Dataflash opcodes #define FlashPageRead 0x52 // Main memory page read #define FlashToBuf1Transfer 0x53 // Main memory page to buffer 1 transfer #define Buf1Read 0x54 // Buffer 1 read #define FlashToBuf2Transfer 0x55 // Main memory page to buffer 2 transfer #define Buf2Read 0x56 // Buffer 2 read #define StatusReg 0x57 // Status register #define AutoPageReWrBuf1 0x58 // Auto page rewrite through buffer 1 #define AutoPageReWrBuf2 0x59 // Auto page rewrite through buffer 2 #define FlashToBuf1Compare 0x60 // Main memory page to buffer 1 compare #define FlashToBuf2Compare 0x61 // Main memory page to buffer 2 compare #define ContArrayRead 0x68 // Continuous Array Read (Note : Only A/B-parts supported) #define FlashProgBuf1 0x82 // Main memory page program through buffer 1 #define Buf1ToFlashWE 0x83 // Buffer 1 to main memory page program with built-in erase #define Buf1Write 0x84 // Buffer 1 write #define FlashProgBuf2 0x85 // Main memory page program through buffer 2 #define Buf2ToFlashWE 0x86 // Buffer 2 to main memory page program with built-in erase #define Buf2Write 0x87 // Buffer 2 write #define Buf1ToFlash 0x88 // Buffer 1 to main memory page program without built-in erase #define Buf2ToFlash 0x89 // Buffer 2 to main memory page program without built-in erase // Constants //Look-up table for these sizes -> 512k, 1M, 2M, 4M, 8M, 16M, 32M, 64M unsigned char DF_pagebits[] ={ 9, 9, 9, 9, 9, 10, 10, 11}; //index of internal page address bits // Globals unsigned char PageBits; // Functions /***************************************************************************** * * Function name : DF_SPI_init * * Returns : None * * Parameters : None * * Purpose : Sets up the HW SPI in Master mode, Mode 3 * Note -> Uses the SS line to control the DF CS-line. * ******************************************************************************/ //Set SS high //Set SS, MOSI and SCK as outputs //Enable SPI in Master mode, mode 3 /***************************************************************************** * * Function name : Read_DF_status * * Returns : One status byte. Consult Dataflash datasheet for further * decoding info * * Parameters : None * * Purpose : Status info concerning the Dataflash is busy or not. * Status info concerning compare between buffer and flash page * Status info concerning size of actual device * ******************************************************************************/ unsigned char Read_DF_status (void) { unsigned char result,index_copy; DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder result = SPI_Send(StatusReg); //send status register read op-code result = SPI_Send(0x00); //dummy write to get result index_copy = ((result & 0x38) >> 3); //get the size info from status register PageBits = DF_pagebits[index_copy]; //get number of internal page address bits from look-up table Transf("Read_DF_status:"); sprintf(strng,"%x",result); Transf(strng); Transf("\r\n"); Transf("PageBits:"); sprintf(strng,"%x",PageBits); Transf(strng); Transf("\r\n"); Transf("index_copy:"); sprintf(strng,"%x",index_copy); Transf(strng); Transf("\r\n"); return result; //return the read status register value } /***************************************************************************** * * Function name : Page_To_Buffer * * Returns : None * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * PageAdr -> Address of page to be transferred to buffer * * Purpose : Transfers a page from flash to dataflash SRAM buffer * ******************************************************************************/ void Page_To_Buffer (unsigned int PageAdr, unsigned char BufferNo) { DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder if (1 == BufferNo) //transfer flash page to buffer 1 { SPI_Send(FlashToBuf1Transfer); //transfer to buffer 1 op-code SPI_Send((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address SPI_Send((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address SPI_Send(0x00); //don't cares } else if (2 == BufferNo) //transfer flash page to buffer 2 { SPI_Send(FlashToBuf2Transfer); //transfer to buffer 2 op-code SPI_Send((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address SPI_Send((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address SPI_Send(0x00); //don't cares } DF_CS_inactive(); //initiate the transfer DF_CS_active(); while(!(Read_DF_status() & 0x80)); //monitor the status register, wait until busy-flag is high } /***************************************************************************** * * Function name : Buffer_Read_Byte * * Returns : One read byte (any value) * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * IntPageAdr -> Internal page address * * Purpose : Reads one byte from one of the dataflash * internal SRAM buffers * ******************************************************************************/ unsigned char Buffer_Read_Byte (unsigned char BufferNo, unsigned int IntPageAdr) { unsigned char data; DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder if (1 == BufferNo) //read byte from buffer 1 { SPI_Send(Buf1Read); //buffer 1 read op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8)); //upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address SPI_Send(0x00); //don't cares data = SPI_Send(0x00); //read byte } else if (2 == BufferNo) //read byte from buffer 2 { SPI_Send(Buf2Read); //buffer 2 read op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address SPI_Send(0x00); //don't cares data = SPI_Send(0x00); //read byte }; return data; //return the read data byte } /***************************************************************************** * * Function name : Buffer_Read_Str * * Returns : None * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * IntPageAdr -> Internal page address * No_of_bytes -> Number of bytes to be read * *BufferPtr -> address of buffer to be used for read bytes * * Purpose : Reads one or more bytes from one of the dataflash * internal SRAM buffers, and puts read bytes into * buffer pointed to by *BufferPtr * ******************************************************************************/ void Buffer_Read_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr) { unsigned int i; DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder if (1 == BufferNo) //read byte(s) from buffer 1 { SPI_Send(Buf1Read); //buffer 1 read op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address SPI_Send(0x00); //don't cares for( i=0; i<No_of_bytes; i++) { *(BufferPtr) = SPI_Send(0x00); //read byte and put it in AVR buffer pointed to by *BufferPtr BufferPtr++; //point to next element in AVR buffer } } else if (2 == BufferNo) //read byte(s) from buffer 2 { SPI_Send(Buf2Read); //buffer 2 read op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address SPI_Send(0x00); //don't cares for( i=0; i<No_of_bytes; i++) { *(BufferPtr) = SPI_Send(0x00); //read byte and put it in AVR buffer pointed to by *BufferPtr BufferPtr++; //point to next element in AVR buffer } } } //NB : Sjekk at (IntAdr + No_of_bytes) < buffersize, hvis ikke blir det bare ball.. /***************************************************************************** * * Function name : Buffer_Write_Enable * * Returns : None * * Parameters : IntPageAdr -> Internal page address to start writing from * BufferAdr -> Decides usage of either buffer 1 or 2 * * Purpose : Enables continous write functionality to one of the dataflash buffers * buffers. NOTE : User must ensure that CS goes high to terminate * this mode before accessing other dataflash functionalities * ******************************************************************************/ void Buffer_Write_Enable (unsigned char BufferNo, unsigned int IntPageAdr) { DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder if (1 == BufferNo) //write enable to buffer 1 { SPI_Send(Buf1Write); //buffer 1 write op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address } else if (2 == BufferNo) //write enable to buffer 2 { SPI_Send(Buf2Write); //buffer 2 write op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8)); //upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address } } /***************************************************************************** * * Function name : Buffer_Write_Byte * * Returns : None * * Parameters : IntPageAdr -> Internal page address to write byte to * BufferAdr -> Decides usage of either buffer 1 or 2 * Data -> Data byte to be written * * Purpose : Writes one byte to one of the dataflash * internal SRAM buffers * ******************************************************************************/ void Buffer_Write_Byte (unsigned char BufferNo, unsigned int IntPageAdr, unsigned char Data) { DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder if (1 == BufferNo) //write byte to buffer 1 { SPI_Send(Buf1Write); //buffer 1 write op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address SPI_Send(Data); //write data byte } else if (2 == BufferNo) //write byte to buffer 2 { SPI_Send(Buf2Write); //buffer 2 write op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address SPI_Send(Data); //write data byte } } /***************************************************************************** * * Function name : Buffer_Write_Str * * Returns : None * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * IntPageAdr -> Internal page address * No_of_bytes -> Number of bytes to be written * *BufferPtr -> address of buffer to be used for copy of bytes * from AVR buffer to dataflash buffer 1 (or 2) * * Purpose : Copies one or more bytes to one of the dataflash * internal SRAM buffers from AVR SRAM buffer * pointed to by *BufferPtr * ******************************************************************************/ void Buffer_Write_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr) { unsigned int i; DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder if (1 == BufferNo) //write byte(s) to buffer 1 { SPI_Send(Buf1Write); //buffer 1 write op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8)); //upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address for( i=0; i<No_of_bytes; i++) { SPI_Send(*(BufferPtr)); //write byte pointed at by *BufferPtr to dataflash buffer 1 location BufferPtr++; //point to next element in AVR buffer } } else if (2 == BufferNo) //write byte(s) to buffer 2 { SPI_Send(Buf2Write); //buffer 2 write op-code SPI_Send(0x00); //don't cares SPI_Send((unsigned char)(IntPageAdr>>8)); //upper part of internal buffer address SPI_Send((unsigned char)(IntPageAdr)); //lower part of internal buffer address for( i=0; i<No_of_bytes; i++) { SPI_Send(*(BufferPtr)); //write byte pointed at by *BufferPtr to dataflash buffer 2 location BufferPtr++; //point to next element in AVR buffer } } } //NB : Monitorer busy-flag i status-reg. //NB : Sjekk at (IntAdr + No_of_bytes) < buffersize, hvis ikke blir det bare ball.. /***************************************************************************** * * Function name : Buffer_To_Page * * Returns : None * * Parameters : BufferAdr -> Decides usage of either buffer 1 or 2 * PageAdr -> Address of flash page to be programmed * * Purpose : Transfers a page from dataflash SRAM buffer to flash * ******************************************************************************/ void Buffer_To_Page (unsigned char BufferNo, unsigned int PageAdr) { DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder if (1 == BufferNo) //program flash page from buffer 1 { SPI_Send(Buf1ToFlashWE); //buffer 1 to flash with erase op-code SPI_Send((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address SPI_Send((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address SPI_Send(0x00); //don't cares } else if (2 == BufferNo) //program flash page from buffer 2 { SPI_Send(Buf2ToFlashWE); //buffer 2 to flash with erase op-code SPI_Send((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address SPI_Send((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address SPI_Send(0x00); //don't cares } DF_CS_inactive(); //initiate flash page programming DF_CS_active(); while(!(Read_DF_status() & 0x80)); //monitor the status register, wait until busy-flag is high } /***************************************************************************** * * Function name : Cont_Flash_Read_Enable * * Returns : None * * Parameters : PageAdr -> Address of flash page where cont.read starts from * IntPageAdr -> Internal page address where cont.read starts from * * Purpose : Initiates a continuous read from a location in the DataFlash * ******************************************************************************/ void Cont_Flash_Read_Enable (unsigned int PageAdr, unsigned int IntPageAdr) { DF_CS_inactive(); //make sure to toggle CS signal in order DF_CS_active(); //to reset dataflash command decoder SPI_Send(ContArrayRead); //Continuous Array Read op-code SPI_Send((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address SPI_Send((unsigned char)((PageAdr << (PageBits - 8))+ (IntPageAdr>>8))); //lower part of page address and MSB of int.page adr. SPI_Send((unsigned char)(IntPageAdr)); //LSB byte of internal page address SPI_Send(0x00); //perform 4 dummy writes SPI_Send(0x00); //in order to intiate DataFlash SPI_Send(0x00); //address pointers SPI_Send(0x00); } // *****************************[ End Of DATAFLASH.c]************************* ..хотя может я фигню вам написал, что-то команды не совпадают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 24 2 марта, 2017 Опубликовано 2 марта, 2017 · Жалоба Пытаюсь общаться по SPI с внешней флеш памятью at45db081 В main пробую записать в начало памяти одну страницу данных (команда 0x85, три байта адреса и посылка), прочитать статусный регистр (команда 0xD7 - регистр читается, память не занята), а потом пробую читать с самого начала памяти (команда 0xE8, три байта адреса и 4 незначащих) - но принимаются одни и те же данные, независимого от того, что писал, т.е. это даже не прием данных: прием проверяю через debug в CooCox гугление и поиск по форуму не помогли, не могу найти видимо какую то глупую ошибку Я писал страницы at45db321d командой 0x82, только предварительно их стерев 0x81 и между адресом и посылкой я снимал CS на 100мс Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 2 марта, 2017 Опубликовано 2 марта, 2017 (изменено) · Жалоба Вот из работающего проекта кусочек... посмотрите, что получится. Работало с AT26DF081A На мой взгляд, Вы не делаете кучи обязательных действий (снять защиту записи, например). И задержки "от балды" вовсе не требуются - все процессы в микросхеме отражаются в статусном регистре. dataflash.c.txt Изменено 2 марта, 2017 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 3 марта, 2017 Опубликовано 3 марта, 2017 (изменено) · Жалоба Давно работаю с этой флешкой - весч удобная и надежная. Обратите внимание на следующее: 1. Запись в флеш (если страница заранее стерта и не используется команда "запись со встроенным стиранием") 1.1. записать данные в буфер (1 или 2) SRAM флеш. (ожидание завершение записи не требуется) 1.2. дать команду флеш на запись буфера (1 или 2) в флеш-массив. После записи флеш будет занята этй операцией, кажется несколько миллисекунд 4-5 мс. 2. Чтение. Есть чтение через буфер и чтение массива напрямую. Операция выполняется без ожидания. Так как цикл работы и проверки состоит из 2 фаз - чтение и запись - Вам сильно помог бы программатор, который позволяет считать (или записать) флешку "гарантированным" способом. Для отладки чтения (это проще всего проверяется) я заполнял на программаторе флеш паттерном с инкриментом (номер страницы+номер байта в странице) До работы с флеш проверьте что SPI настроен и работает (закольцуйте MISO-MOSI) ps // Считать из флеш содержимое буфера // 1-номер буфера (1 2) // 2-адрес в BF-SRAM, с которого начать чтение // 3-кол-во байт, которые требуется считать // 4-указатель внешней памяти (dest, куда) // 5-проверять-ждать готовность флеш int AT45_ReadBuf( char n_buf, int a_addr, int n_size, char *to_ptr, int test_ready) { char cmd_45 = C45_RD_BUFF_1; // 054x 0x56 по умолчанию if( n_buf == AT45_BUFF_2 ) cmd_45 = C45_RD_BUFF_2; // ошибки не обрабатываются if( n_size > 264 ) return( -2 ); // Err 2 AT45_TEST_READY( test_ready ); // ---------------------- SET_CS0_AT45; SPI_TX( cmd_45 ); // 54/56 Read430<--Buf(1,2) SPI_TX(0); SPI_TX( A16_HI(a_addr) ); // старший байт адреса SPI_TX( A16_LO(a_addr) ); SPI_TX(0x00); // Additional byte for( int i=0; i<n_size; i++) { *to_ptr = SPI_TX(0x00); to_ptr++; } CS_ALL_1; // ---------------------- return(1); }//f Изменено 3 марта, 2017 пользователем k155la3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KamilSafin 0 3 марта, 2017 Опубликовано 3 марта, 2017 (изменено) · Жалоба MOSI и MISO закольцовывал - все нормально, что отправляется, то и доходит Сейчас какая-то странная проблема - память как будто не стабильно работает, т.е. запускаю отладку один раз - все работает, пишется через 82h и читается через E8h, но иногда при запуске программа застревает в цикле проверки регистра статуса - память просто не выдает регистр, переменная равна 0. И работает память только при значении предделителя 8 (т.е. на 9 MHz), хотя при более низких частотах же тоже должна работать. Может это быть проблемой настройки SPI или подключения? Уже который день пытаюсь настроить нормально работу, но все в одних и тех же ошибках. Изменено 7 марта, 2017 пользователем Herz Избыточное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 3 марта, 2017 Опубликовано 3 марта, 2017 (изменено) · Жалоба какой SPI MODE - 0, 1, 2 или 3 выбрано? spi.SPI_CPOL = SPI_CPOL_Low; spi.SPI_CPHA = SPI_CPHA_2Edge; какому оно соответствует? из четырех возможных допустимы только два (0 или 3, кажется). Изменено 3 марта, 2017 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 24 5 марта, 2017 Опубликовано 5 марта, 2017 · Жалоба но иногда при запуске программа застревает в цикле проверки регистра статуса - память просто не выдает регистр, переменная равна 0. Поэтому я не проверял этот регистр, а ставил паузу. Может нужна пауза при проверке статуса... И работает память только при значении предделителя 8 (т.е. на 9 MHz), хотя при более низких частотах же тоже должна работать. Там ещё все ножки должны быть припаяны, даже брюхо и кондёр по питанию рядом. Ну и качество питания при включении платы. Флешка не на проводах? На одной плате с контроллером? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 6 марта, 2017 Опубликовано 6 марта, 2017 · Жалоба . . . . Может это быть проблемой настройки SPI или подключения? Уже который день пытаюсь настроить нормально работу, но все в одних и тех же ошибках. Это цепочка из правильной настройки SPI, правильного обращения к AT45 и правильного алгоритма работы с состояниями AT45. Для проверки сначала поработайте с буфером (первым или вторым) SRAM - без записи в массив флеш. Буфер не требует ожидания готовности (так как это оперативная память). Соотв-но флешка "всегда готова". Если все будет норм. - значит SPI и алгоритм обращения на AT45 правильный. Если не читается регистр статуса - а он должен читаться ВСЕГДА - то чтото с SPI или Вашим алгоритмом. Все блоки команд дожны отделятся "своим" CS. Вам надо контролировать работу с "освобождением" сдвигового регистра, возможно еще не ушла первая команда, а Вы шлете следующую. //читаем статус char AT45_StatusGet(void) { SET_CS0_AT45; wrSPI( C45_RD_STATUS ); wrSPI(0); CS_ALL_1; return( UCB0RXBUF ); } char AT45_Ready(void) { if( AT45_StatusGet() & 0x80 ) // return(1); // Ready else return(0); // ! Ready } // здесь следует добавить временную задержку delay(n) или Sleep(n) // чтобы не лезть непрерывно на SPI и флеш #define AT45_TEST_READY( t_rdy ) \ if( t_rdy ) \ { int n_times = 0; \ while( ! AT45_Ready() ) \ if( n_times > 10000 ) \ return(-1); \ else \ n_times++; \ } \ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 6 марта, 2017 Опубликовано 6 марта, 2017 · Жалоба . . . . sendByte(0xD7); data = sendByte(DUMMY); GPIO_SetBits(GPIOA, GPIO_Pin_4); --------------- (!) GPIO_ResetBits(GPIOA, GPIO_Pin_4); sendByte(0xE8); sendByte(0x00); sendByte(0x00); (!) - если это CS - то возможно обрубается обмен по SPI (CS снимается раньше, чем выдвигается-вдвигается shift-регистр SPI) Не знаю, как организован моудль SPI у STM (буферизация итд) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 6 марта, 2017 Опубликовано 6 марта, 2017 · Жалоба Не знаю, как организован моудль SPI у STM (буферизация итд) да также, как у всех :) нужно флаг контроллить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ivan24190 0 7 марта, 2017 Опубликовано 7 марта, 2017 (изменено) · Жалоба KamilSafin, вот тестовый проект в keil 4.7 (проверял на плате TE stm32f107, там стоит flash at45db321d), попробуйте, только перенастройте периферию под свой проект. SPI3.zip Изменено 7 марта, 2017 пользователем ivan24190 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 7 марта, 2017 Опубликовано 7 марта, 2017 · Жалоба KamilSafin, вот тестовый проект ну о чем и говорилось: //---------------------------------------------------------------------------------------------------- /* Обмен с Flash-памятью байтом */ uint8_t FlashByteExchg(uint8_t Byte) { while(!(SPI3->SR & SPI_SR_TXE)); SPI3->DR = Byte; while(!(SPI3->SR & SPI_SR_RXNE)); return SPI3->DR; } ; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться