stm32f4+FRAM по spi (FM25CL64)

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Родился
Сообщения: 10
Зарегистрирован: Пн янв 26, 2009 22:49:48

Сообщение aske12345 »

Здравствуйте! Прошу помощи :cry: ! Столкнулся со следующей проблемой пытаюсь подключить к контроллеру по spi память FRAM FM25CL64 ,компилятор keil , пытаюсь записать одно число и его же считать, а осциллографом вижу, что считывается не то, что записывал. Пытался в разные ячейки памяти разные числа - считываются разные числа, но не те. Пишу 0x2F считывается 0x1С, пишу 0xFF считывается 0xFE, пишу 0x99 считывается 0x20 - ерунда какая то.



Куски кода привел ниже:

Код: Выделить всё

int main(void)
{
	
	SystemCoreClockUpdate();
	SysTick_Config(SystemCoreClock/1000);//1ms
	LEDs_ini();
	Button_ini();
	SPI3_FRAM_ini();
        delay_ms(50);

	//проверим FRAM начало запись 1 байта
       CS_FRAM_ON();//
       while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};
       SPI_I2S_SendData(SPI3, 0x06);//Set Write Enable Latch 6
       while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
       while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется
       CS_FRAM_OFF();
       delay_us(3);	//на самом деле задержка выходит около 500нс
      
        CS_FRAM_ON();	
	while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};
	SPI_I2S_SendData(SPI3, 0x02);// Write 	

        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется

	SPI_I2S_SendData(SPI3, 0x10);// 13 битный адрес
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется	
	SPI_I2S_SendData(SPI3, 0x00);// 13 битный адрес
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется
	SPI_I2S_SendData(SPI3, 0x2F);// данные 
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется
	
        CS_FRAM_OFF();
        delay_us(3);//на самом деле задержка выходит около 500нс
        //проверим FRAM конец запись  1 байта

        //проверим FRAM начало чтение 1 байта
        CS_FRAM_ON();//
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};

	SPI_I2S_SendData(SPI3, 0x03);// Read 	

        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется

	SPI_I2S_SendData(SPI3, 0x10);// 13 битный адрес
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется	
	SPI_I2S_SendData(SPI3, 0x00);// 13 битный адрес
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется
	SPI_I2S_SendData(SPI3, 0x00);// пишем 0 для считывания
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется
        CS_FRAM_OFF();

//проверим FRAM конец чтение 1 байта	
	
	//LED1_OFF;
	
	while(1)
	{


настройки spi:

Код: Выделить всё

SPI_Init_user3.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_Init_user3.SPI_Mode = SPI_Mode_Master;
	SPI_Init_user3.SPI_DataSize = SPI_DataSize_8b;
	SPI_Init_user3.SPI_CPOL = SPI_CPOL_High;//SPI_CPOL_Low
	SPI_Init_user3.SPI_CPHA = SPI_CPHA_2Edge;
	SPI_Init_user3.SPI_NSS = SPI_NSS_Soft;
	SPI_Init_user3.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//4
	SPI_Init_user3.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_Init_user3.SPI_CRCPolynomial = 7;
	
	SPI_Init(SPI3, &SPI_Init_user3);
контакты вроде все пересмотрел, думал провода может длинноваты, клок spi настраивал на разную частоту уменьшал до 1МГц - не влияет, пробовал делать паузу между командой WREN и командой записи 15мс, а записью и считыванием 20мс, всё то же самое не помогло..

Осциллограмма всех посылок WREN, WITE, READ (тактовый сигнал ch1 и miso FRAM ch2) (синий луч отношения к делу не имеет)
Изображение

Осциллограмма команды WREN (тактовый сигнал ch1 и miso FRAM ch2)(синий луч отношения к делу не имеет)
Изображение

Осциллограмма команды WITE (тактовый сигнал ch1 и miso FRAM ch2)
Изображение

Осциллограмма считанного значения записывал 0x2F, считал 0x1C (тактовый сигнал ch1 и mosi FRAM ch2)
Изображение
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

Для начало избавиться от портянок и писать прямо через CMSIS + научиться строить логику программы и оформлять код.
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Реклама
Прорезались зубы
Аватара пользователя
Сообщения: 225
Зарегистрирован: Сб янв 14, 2012 22:53:50

Сообщение philosoraptor »

Как раз на днях писал либу для SST25LF040A под STM32F103 с HAL. Тоже поначалу не хотело работать как надо. Пришлось вкуривать даташит, где попалось, в частности, и такое
СпойлерThe Enable-Write-Status-Register (EWSR) instruction
arms the Write-Status-Register (WRSR) instruction and
opens the status register for alteration. The Enable-Write-
Status-Register instruction does not have any effect and
will be wasted, if it is not followed immediately by the Write-
Status-Register (WRSR) instruction. CE# must be driven
low before the EWSR instruction is entered and must be
driven high before the EWSR instruction is executed.
Причем делать это надо перед каждым новым байтом, если пишем побайтово.

После добавления этой процедуры в код все заработало. Ах да, и еще, таких вот

Код: Выделить всё

while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
конструкций лучше избегать. Задержки не люблю, но в данной ситуации они меньшее зло. Функцию delay_us под армовский таймер написал первым делом, кстати.
Потрогал лапой паяльник
Сообщения: 314
Зарегистрирован: Чт ноя 29, 2012 08:27:22

Сообщение pixar »

Ах да, и еще, таких вот конструкций лучше избегать.
while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
Почему ?
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

[uquote="philosoraptor",url="/forum/viewtopic.php?p=3453851#p3453851"]Ах да, и еще, таких вот

Код: Выделить всё

while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
конструкций лучше избегать. Задержки не люблю, но в данной ситуации они меньшее зло. Функцию delay_us под армовский таймер написал первым делом, кстати.[/uquote]


Чтобы избегать их надо делать на DMA, а в данном случае задержки - совершенно неприемлемы...
Реклама
Прорезались зубы
Аватара пользователя
Сообщения: 225
Зарегистрирован: Сб янв 14, 2012 22:53:50

Сообщение philosoraptor »

[uquote="pixar",url="/forum/viewtopic.php?p=3458530#p3458530"]
Ах да, и еще, таких вот конструкций лучше избегать.
while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};
Почему ?[/uquote]

Потому что бесконечные циклы и так зло, а бесконечные циклы в ожидании внешнего события это уже просто за гранью.
в данном случае задержки - совершенно неприемлемы
В данном случае вполне приемлемы, более того, при прототайпинге и отладке вообще оптимальны.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

philosoraptor, вы утверждаете что задержки вместо ожидания флага не чушь собачья?
Вы окончательно в это уверовали?
Прорезались зубы
Аватара пользователя
Сообщения: 225
Зарегистрирован: Сб янв 14, 2012 22:53:50

Сообщение philosoraptor »

Именно так. Sue me.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Угу , подобрали задержки, получили кое-какой результат теперь измените скорость SPI...
Прорезались зубы
Аватара пользователя
Сообщения: 225
Зарегистрирован: Сб янв 14, 2012 22:53:50

Сообщение philosoraptor »

Задержки не для тактирования SPI, а для того чтобы внешняя флешка успевала распихивать данные по ячейкам. Ничто не мешает заменить задержки автоматом состояний в конечной версии.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

philosoraptor, вы свой первый пост в этой ветке перечитайте вдумчиво.
Заодно проштудируйте RM, а кокретно работу модуля SPI, возможно до вас дойдет что задержки там и на не вперлись.
А для отслеживания "распихивания данных" в спи флэш есть BUSy...
Прорезались зубы
Аватара пользователя
Сообщения: 225
Зарегистрирован: Сб янв 14, 2012 22:53:50

Сообщение philosoraptor »

Забавно, но написанная мной за пару вечеров программка читает и записывает данные на флеш с usb-cdc безупречно. Ну а так вообще ваше мнение мне очень интересно, конечно.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Ну да, забавно.
USB-CDC и SPI флэш, чего только не наг.кодиться на калокубе.


Изучайте...
http://cxem.net/mc/mc430.php
http://cxem.net/mc/mc432.php
http://cxem.net/mc/mc433.php
Прорезались зубы
Аватара пользователя
Сообщения: 225
Зарегистрирован: Сб янв 14, 2012 22:53:50

Сообщение philosoraptor »

Еще как забавно. Некоторые даже родный язык, -тся/ться в частности освоить не в состоянии, even less likely they'd study K&R the way it should be studied.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Вы читайте, читайте...
Ответить

Вернуться в «ARM»