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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> STM32F100 + флешка EN25T80 + soft SPI, не удаётся прочитать данные
Artos5
сообщение Aug 10 2014, 20:53
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613



Добрый вечер дорогие форумчане! Помогите пожалуйста решить проблему....

значит проблема такая:
Ни в какую не удаётся прочитать данные из флешки. Почему то , ее выход "болтается в воздухе" HI-Z состояние . Потому как в момент чтения , если приблизить руку к ней - данные хаотично принимаются.

код при обращении такой:

Код
soft_spi_write_instruct(SPI_FLASH_INS_READ); // comand
     soft_spi_write_addr(0x000000); // adress


Код
// в вечном цикле читаю данные и вывожу прямо на экран дисплея + показываю считанный байт

sprintf(buffer, "A=%x  P=%d         ", soft_spi_read(), y++); // колл. этапов
lcd_xy(3,1);
lcd_out(buffer);



библиотека такая , сильно не пинайте , писал на скорую руку , да и опыта конечно не много в этом деле sm.gif :

CODE
файл .С


#include "EN25T80.h"

#define DLY 10000

void delay(long x)
{
while(x)
{
x--;
}
}

void soft_spi_init()
{


//GPIOC->CRH |=0x24200000; //
//GPIOD->CRL |=0x00000002; //
}

void soft_spi_write_instruct(unsigned char instruct)
{
char x;
SPI_CS_CLR;
delay(DLY);
for(x=0;x<8;x++) // instruction
{
if (0x80 & instruct)
{
SPI_DATA1;
}
else
{
SPI_DATA0;
}

SCK_SPI_CLR;
delay(DLY);
SCK_SPI_SET;


instruct = instruct<<1;

delay(DLY);
}
SPI_CS_SET;
}

void soft_spi_write_addr(long addr_dev)
{
char x;

SPI_CS_CLR;
delay(DLY);
for(x=0;x<24;x++) // instruction
{
if (0x800000 & addr_dev)
{
SPI_DATA1;
}
else
{
SPI_DATA0;
}

SCK_SPI_CLR;
delay(DLY);
SCK_SPI_SET;
addr_dev = addr_dev<<1;

delay(DLY);
}
SPI_CS_SET;
}

int soft_spi_read()
{
int data_buff=0;
char x;

SPI_CS_CLR;
delay(DLY);

for(x=0;x<8;x++)
{
SCK_SPI_CLR;
delay(DLY);

if (SPI_IN)
{
data_buff |=1;
}
data_buff = data_buff<<1;

SCK_SPI_SET;
SPI_DATA1;



delay(DLY);
}

SPI_CS_SET;

return data_buff;
}

файл .Н

#include "stm32f10x_gpio.h"



#define BIT_IN (1<<1) // номер бита входа SPI
#define SCK_SPI_SET GPIO_SetBits(GPIOC, GPIO_Pin_1)
#define SCK_SPI_CLR GPIO_ResetBits(GPIOC, GPIO_Pin_1)

#define SPI_DATA1 GPIO_SetBits(GPIOC, GPIO_Pin_0)
#define SPI_DATA0 GPIO_ResetBits(GPIOC, GPIO_Pin_0)

#define SPI_CS_SET GPIO_ResetBits(GPIOC, GPIO_Pin_2)
#define SPI_CS_CLR GPIO_SetBits(GPIOC, GPIO_Pin_2)


//****************** SPI Definitions **************//
//#define CHIP_SELECT_AT25 PORTE.3=0;delay_ms(100);
//#define CHIP_UNSELECT_AT25 PORTE.3=1;delay_ms(100);
//******************* SPI Definitions *************//

//******************* Instruction Set ************//
// Read Commands
#define SPI_FLASH_INS_READ 0x03 // Read array
#define SPI_FLASH_INS_FAST_READ 0x0B // Read array(low frequency)

// Program and Erase Commands
#define SPI_FLASH_INS_BLOCK_ERASE_4K 0x20 // Sector erase
#define SPI_FLASH_INS_BLOCK_ERASE_32K 0x52 // Sector erase
#define SPI_FLASH_INS_BLOCK_ERASE_64K 0xD8 // Sector erase
#define SPI_FLASH_INS_CHIP_ERASE_1 0x60 // Sector erase
#define SPI_FLASH_INS_CHIP_ERASE_2 0xC7 // Sector erase
#define SPI_FLASH_INS_PAGE_PROGRAM 0x02 // Byte/Page program

// Protection commands
#define SPI_FLASH_INS_WRITE_ENABLE 0x06 // Write enable
#define SPI_FLASH_INS_WRITE_DISABLE 0x04 // Write disable
#define SPI_FLASH_INS_PROTECT_SECTOR 0x36 // Write disable
#define SPI_FLASH_INS_UNPROTECT_SECTOR 0x39 // Write disable

// Status register commands

#define SPI_FLASH_INS_READ_STATUS_REGISTER 0x05 // Read status register
#define SPI_FLASH_INS_WRITE_STATUS_REGISTER 0x01 // Write status register

// Miscellanous Commands
#define SPI_FLASH_INS_READ_DEVICE_ID 0x9F // Read identification
#define SPI_FLASH_INS_DEEP_POWER_DOWN 0xB9 // Deep power-down
#define SPI_FLASH_INS_RESUME_FROM_DEEP_POWER_DOWN 0xAB // Release from deep power- down

#define SPI_IN ((GPIOA->IDR & BIT_IN)==BIT_IN)

void soft_spi_init();
void soft_spi_write_instruct(unsigned char instruct);
void soft_spi_write_addr(long addr_dev);
int soft_spi_read();



Подскажите пожалуйста что я делаю не так.......
ПС: клок от МК присутствует , и чип селект тоже.

Даташит взял отсюда : http://www.suwa-koubou.jp/micom/TempLogger/EN25T80.pdf

Буду крайне благодарен за любую помощь в решении данной проблемы....
С уважением Артем Угримов.

Сообщение отредактировал IgorKossak - Aug 11 2014, 07:56
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 11 2014, 05:58
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



#define SPI_CS_SET GPIO_ResetBits(GPIOC, GPIO_Pin_2)
#define SPI_CS_CLR GPIO_SetBits(GPIOC, GPIO_Pin_2)

чип селект точно в эту сторону?

правильнее понятнее и читабильнее делать
FLASH_CS_0 и FLASH_CS_1
обычно все выбирается 0, а в ваших функция в начале на флешку идет 1, а как закончили работу на нее идет 0. Может вы ее просто не выбираете?

из мануала к флешке
Цитата
Chip Select (CS#)
The SPI Chip Select (CS#) pin enables and disables device operation. When CS# is high the device
is deselected and the Serial Data Output (DO) pin is at high impedance. When deselected, the
devices power consumption will be at standby levels unless an internal erase, program or status
register cycle is in progress. When CS# is brought low the device will be selected, power
consumption will increase to active levels and instructions can be written to and data read from the
device. After power-up, CS# must transition from high to low before a new instruction will be
accepted.


то есть если на плате нет никакого инвертора сигнала CS, вы ее просто не выбираете...
Go to the top of the page
 
+Quote Post
Artos5
сообщение Aug 11 2014, 06:52
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613



Цитата(Golikov A. @ Aug 11 2014, 08:58) *
то есть если на плате нет никакого инвертора сигнала CS, вы ее просто не выбираете...


Да вроде порядок с сигналами....
осциллографом смотрел - ничего подозрительного.
Я даже набросал пример в протеус и МК взял AVR
Прилепил эти библиотеки. В результате флешка точно так себя ведет........... я уже запутался sad.gif


А кто скажет , почему функция не возвращает прочитанное значение из ножки? (это вопрос по прикрепленному архиву).
Прикрепленные файлы
Прикрепленный файл  ___________AT25.rar ( 140.77 килобайт ) Кол-во скачиваний: 14
 
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 11 2014, 06:57
Сообщение #4


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



А что, снимать чипселект после команды, опять ставить для передачи адреса и опять снимать - это нормально? Попробуйте на весь цикл обмена оставлять чипселект. Что даташит про это говорит?

Чтение в мегах с выводов выглядит так:
#define SPI_IN ((PINB & BIT_IN)==BIT_IN)

Да и вообще, посмотрите тут: http://188.134.5.254/browser/hfreceiver/trunk/nvram.c#L209

Сообщение отредактировал Genadi Zawidowski - Aug 11 2014, 07:01
Go to the top of the page
 
+Quote Post
Artos5
сообщение Aug 11 2014, 07:01
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613



Я уже так делал, это проблему не решает.... я сейчас так сделал потому что вчера ставал осциллографом на программатор при чтении такой флешки, и программатор точно так работал...

Цитата(Genadi Zawidowski @ Aug 11 2014, 09:57) *
Чтение в мегах с выводов выглядит так:
#define SPI_IN ((PINB & BIT_IN)==BIT_IN)


Точно! Уже вообще голова не работает...

Теперь заработала функция чтения! Только память не читается.... мало того, еще и выход у нее в HI-Z...........

Сообщение отредактировал Artos5 - Aug 11 2014, 07:02
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 11 2014, 07:08
Сообщение #6


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
Я уже так делал, это проблему не решает....

figure 9 в даташите для Вас.
А сделайте и КОД с исправлениями сюда.
Цитата
Только память не читается.... мало того, еще и выход у нее в HI-Z...........

Это именно от того, что Вы снимаете CS.

Сообщение отредактировал Genadi Zawidowski - Aug 11 2014, 07:18
Go to the top of the page
 
+Quote Post
Artos5
сообщение Aug 11 2014, 07:29
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613



Цитата(Genadi Zawidowski @ Aug 11 2014, 10:08) *
figure 9 в даташите для Вас.
А сделайте и КОД с исправлениями сюда.

Это именно от того, что Вы снимаете CS.


Геннадий, я вам премного благодарен что помогаете!
Я появлюсь за ПК , попробую еще раз. И выложу пример. Может действительно чего упустил...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 11 2014, 08:35
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я чет не понимаю...

soft_spi_write_instruct

начинается с

SPI_CS_CLR

который в свою очередь объявлен как

#define SPI_CS_CLR GPIO_SetBits(GPIOC, GPIO_Pin_2)

то есть с установки чип селекта в 1. при этом в описании на флешку написано что это СНИМАЕТ выбор флэшки... как вы хотите чтобы она после этого хоть что-то вернула? если вы все общение производите со снятым выбором? Есть инверсия сигнала на плате чтобы он до флешки 0 доходил при 1?

и еще написано что флешка ловит фронты чипселекта, так что после включения питания чип селектом надо дернуть, нельзя просто в 0 держать.
Библиотеки бл...
Go to the top of the page
 
+Quote Post
Artos5
сообщение Aug 11 2014, 09:26
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613



Цитата(Golikov A. @ Aug 11 2014, 11:31) *
я чет не понимаю...

soft_spi_write_instruct

начинается с

SPI_CS_CLR

который в свою очередь объявлен как

#define SPI_CS_CLR GPIO_SetBits(GPIOC, GPIO_Pin_2)

то есть с установки чип селекта в 1. при этом в описании на флешку написано что это СНИМАЕТ выбор флэшки... как вы хотите чтобы она после этого хоть что-то вернула? если вы все общение производите со снятым выбором? Есть инверсия сигнала на плате чтобы он до флешки 0 доходил при 1?



Нет.... как раз сброс происходит.... [CENSORED] Точно! sm.gif вот это я лопух....

Получается запутался в трёх соснах : ))))

Переделал уже так:

Код
     soft_spi_init();
     SPI_CS_CLR;
     //soft_spi_write_instruct(SPI_FLASH_INS_READ_DEVICE_ID);
     soft_spi_write_instruct(SPI_FLASH_INS_READ);
     soft_spi_write_addr(0x000000);


Код
                                    sprintf(buffer, "A=%x  P=%d         ", soft_spi_read(), y++); // колл. этапов
                                    lcd_xy(3,1);
                                    lcd_out(buffer);


сама библиотека:

CODE
// .Н =================

#include "stm32f10x_gpio.h"



#define BIT_IN (1<<1) // номер бита входа SPI
#define SCK_SPI_SET GPIO_SetBits(GPIOC, GPIO_Pin_1)
#define SCK_SPI_CLR GPIO_ResetBits(GPIOC, GPIO_Pin_1)

#define SPI_DATA1 GPIO_SetBits(GPIOC, GPIO_Pin_0)
#define SPI_DATA0 GPIO_ResetBits(GPIOC, GPIO_Pin_0)

#define SPI_CS_CLR GPIO_ResetBits(GPIOC, GPIO_Pin_2)
#define SPI_CS_SET GPIO_SetBits(GPIOC, GPIO_Pin_2)


//****************** SPI Definitions **************//
//#define CHIP_SELECT_AT25 PORTE.3=0;delay_ms(100);
//#define CHIP_UNSELECT_AT25 PORTE.3=1;delay_ms(100);
//******************* SPI Definitions *************//

//******************* Instruction Set ************//
// Read Commands
#define SPI_FLASH_INS_READ 0x03 // Read array
#define SPI_FLASH_INS_FAST_READ 0x0B // Read array(low frequency)

// Program and Erase Commands
#define SPI_FLASH_INS_BLOCK_ERASE_4K 0x20 // Sector erase
#define SPI_FLASH_INS_BLOCK_ERASE_32K 0x52 // Sector erase
#define SPI_FLASH_INS_BLOCK_ERASE_64K 0xD8 // Sector erase
#define SPI_FLASH_INS_CHIP_ERASE_1 0x60 // Sector erase
#define SPI_FLASH_INS_CHIP_ERASE_2 0xC7 // Sector erase
#define SPI_FLASH_INS_PAGE_PROGRAM 0x02 // Byte/Page program

// Protection commands
#define SPI_FLASH_INS_WRITE_ENABLE 0x06 // Write enable
#define SPI_FLASH_INS_WRITE_DISABLE 0x04 // Write disable
#define SPI_FLASH_INS_PROTECT_SECTOR 0x36 // Write disable
#define SPI_FLASH_INS_UNPROTECT_SECTOR 0x39 // Write disable

// Status register commands

#define SPI_FLASH_INS_READ_STATUS_REGISTER 0x05 // Read status register
#define SPI_FLASH_INS_WRITE_STATUS_REGISTER 0x01 // Write status register

// Miscellanous Commands
#define SPI_FLASH_INS_READ_DEVICE_ID 0x9F // Read identification
#define SPI_FLASH_INS_DEEP_POWER_DOWN 0xB9 // Deep power-down
#define SPI_FLASH_INS_RESUME_FROM_DEEP_POWER_DOWN 0xAB // Release from deep power- down

/*
#define BIT_IN (1<<3) // номер бита входа SPI
#define SCK_SPI_SET {GPIOA->BSRR |=(1<<1); GPIOA->BSRR &=~(1<<17);}
#define SCK_SPI_CLR {GPIOA->BSRR |=(1<<17); GPIOA->BSRR &=~(1<<1);}

#define SPI_DATA1 {GPIOA->BSRR |=(1<<2); GPIOA->BSRR &=~(1<<18);}
#define SPI_DATA0 {GPIOA->BSRR |=(1<<18); GPIOA->BSRR &=~(1<<2);}

#define SPI_CS_SET {GPIOA->BSRR |=(1<<4); GPIOA->BSRR &=~(1<<20);}
#define SPI_CS_CLR {GPIOA->BSRR |=(1<<20); GPIOA->BSRR &=~(1<<4);}
*/
#define SPI_IN ((GPIOA->IDR & BIT_IN)==BIT_IN)

void soft_spi_init();
void soft_spi_write_instruct(unsigned char instruct);
void soft_spi_write_addr(long addr_dev);
int soft_spi_read();

// .С =================


#include "EN25T80.h"

#define DLY 10000

void delay(long x)
{
while(x)
{
x--;
}
}

void soft_spi_init()
{

SPI_CS_CLR;
delay(DLY);
SPI_CS_SET;
delay(DLY);
SPI_CS_CLR;
delay(DLY);
SPI_CS_SET;
delay(DLY);
//GPIOC->CRH |=0x24200000; //
//GPIOD->CRL |=0x00000002; //
}

void soft_spi_write_instruct(unsigned char instruct)
{
char x;

delay(DLY);
for(x=0;x<8;x++) // instruction
{
if (0x80 & instruct)
{
SPI_DATA1;
}
else
{
SPI_DATA0;
}
SCK_SPI_CLR;
delay(DLY);
SCK_SPI_SET;
delay(DLY);

instruct = instruct<<1;
}

}

void soft_spi_write_addr(long addr_dev)
{
char x;


delay(DLY);
for(x=0;x<24;x++) // instruction
{
if (0x800000 & addr_dev)
{
SPI_DATA1;
}
else
{
SPI_DATA0;
}
SCK_SPI_CLR;
delay(DLY);
SCK_SPI_SET;
delay(DLY);
addr_dev = addr_dev<<1;
}
SPI_CS_SET;
}

int soft_spi_read()
{
int data_buff=0;
char x;


delay(DLY);

for(x=0;x<8;x++)
{
SCK_SPI_CLR;
delay(DLY);

if (SPI_IN)
{
data_buff |=1;
}
data_buff = data_buff<<1;

SCK_SPI_SET;
SPI_DATA1;



delay(DLY);
}



return data_buff;
}


Результат все тот же... sad.gif

Обнаружил что PORTC.2 после сброса болтается в единице .... а это ножка чип селекта

Сообщение отредактировал IgorKossak - Aug 11 2014, 10:17
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 11 2014, 09:43
Сообщение #10


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Чипселект ДОЛЖЕН быть опущен в "0" на всё время работы. Сделайте пожалуйста так. Сейчас у Вас после передачи адреса чипселект снимается (переводится в "1").

Сообщение отредактировал Genadi Zawidowski - Aug 11 2014, 09:46
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 11 2014, 09:47
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



мда...

soft_spi_write_instruct

смотрим тело функции

цикл, в нем SPI_CS_SET - есть, а в начале
SPI_CS_CLR - нету.... вы снова не выбрали флешкуsm.gif...

возьмите осцилограф, и смотрите картинки что он рисует, поставьте их на клок и чип селект. Правьте код пока не получите такие же картинки как в мануале... Огромное количество очевидных ошибок из-за невнимательности. 1 - 2 можно понять, иногда зарубает не видишь очевидного, но такое количество легко диагностируемых....

Проинитите порт, задайте частоту если есть, повыставляйте на порт 0 и 1, сделайте для них дефайны, реализуйте алгоритм общения с флэшкой, у вас еще и осцилограф есть...

Go to the top of the page
 
+Quote Post
Artos5
сообщение Aug 11 2014, 09:49
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613



Цитата(Genadi Zawidowski @ Aug 11 2014, 12:43) *
Чипселект ДОЛЖЕН быть опущен в "0" на всё время работы. Сделайте пожалуйста так. Сейчас у Вас после передачи адреса чипселект снимается (переводится в "1").


Перенес чипселект на ПОРТА2 , проработало ровно пару минут, и данные выводились из флешки.... спустя 2 минуты ПОРТА2 Стал себя аналогично вести........ после сброса поднимается в единицу. Это просто какая то магия из этими пинами.....
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 11 2014, 09:50
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я бы сделал функцию

WriteSPIData(int8_t data_out);
ReadSPIData(int8_t *data_in);

макросы
FLASH_CS_0
FLASH_CS_1


и использовал

FLASH_CS_0;
WriteSPIData(...);
...
ReadSPIData(...);
...
FLASH_CS_1;

Go to the top of the page
 
+Quote Post
Artos5
сообщение Aug 11 2014, 10:17
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613



Цитата(Golikov A. @ Aug 11 2014, 12:47) *
мда...

soft_spi_write_instruct

смотрим тело функции

цикл, в нем SPI_CS_SET - есть, а в начале
SPI_CS_CLR - нету.... вы снова не выбрали флешкуsm.gif...

возьмите осцилограф, и смотрите картинки что он рисует, поставьте их на клок и чип селект. Правьте код пока не получите такие же картинки как в мануале... Огромное количество очевидных ошибок из-за невнимательности. 1 - 2 можно понять, иногда зарубает не видишь очевидного, но такое количество легко диагностируемых....

Проинитите порт, задайте частоту если есть, повыставляйте на порт 0 и 1, сделайте для них дефайны, реализуйте алгоритм общения с флэшкой, у вас еще и осцилограф есть...


Да выбрал я уже флешку sm.gif
в том то и дело. Проработало пару минут , и теперь опять чипселект не опускается....


Фух......... заработало wink.gif
убрал чипселект в функции.

Теперь другой прикол. Почему вместо FF выводится 1FE ? Ну и естественно остальные данные какие попало.

Ребятки, всем огромное спасибо!!!! Все заработало : )))) моей радости нет предела!
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 11 2014, 14:11
Сообщение #15


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Сделать так:
Код
     SCK_SPI_CLR;
     delay(DLY);
     SCK_SPI_SET;
     delay(DLY);

      data_buff = (data_buff<<1) | (SPI_IN != 0);

И разберитесь с задержками и оптимизацией в компиляторе - а то следующий вопрос будет "почему всё в release перестало работать".
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 17:10
Рейтинг@Mail.ru


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