реклама на сайте
подробности

 
 
> stm32f1xx - внешняя флеш память по SPI, подключение at45db по SPI
KamilSafin
сообщение Mar 2 2017, 09:24
Сообщение #1





Группа: Новичок
Сообщений: 2
Регистрация: 2-03-17
Пользователь №: 95 666



Пытаюсь общаться по SPI с внешней флеш памятью at45db081
Инициализация SPI:
CODE
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);
}


отсылка и прием байта данных:
CODE
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 незначащих) - но принимаются одни и те же данные, независимого от того, что писал, т.е. это даже не прием данных:
CODE
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
гугление и поиск по форуму не помогли, не могу найти видимо какую то глупую ошибку
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
k155la3
сообщение Mar 3 2017, 08:59
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Давно работаю с этой флешкой - весч удобная и надежная.
Обратите внимание на следующее:
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


Сообщение отредактировал k155la3 - Mar 3 2017, 09:10
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th June 2025 - 14:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01396 секунд с 7
ELECTRONIX ©2004-2016