|
STM32F100 + флешка EN25T80 + soft SPI, не удаётся прочитать данные |
|
|
|
Aug 10 2014, 20:53
|
Частый гость
 
Группа: Участник
Сообщений: 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); библиотека такая , сильно не пинайте , писал на скорую руку , да и опыта конечно не много в этом деле  : 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] - для короткого!!!
|
|
|
|
|
Aug 11 2014, 05:58
|
Гуру
     
Группа: Свой
Сообщений: 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, вы ее просто не выбираете...
|
|
|
|
|
Aug 11 2014, 06:52
|
Частый гость
 
Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613

|
Цитата(Golikov A. @ Aug 11 2014, 08:58)  то есть если на плате нет никакого инвертора сигнала CS, вы ее просто не выбираете... Да вроде порядок с сигналами.... осциллографом смотрел - ничего подозрительного. Я даже набросал пример в протеус и МК взял AVR Прилепил эти библиотеки. В результате флешка точно так себя ведет........... я уже запутался  А кто скажет , почему функция не возвращает прочитанное значение из ножки? (это вопрос по прикрепленному архиву).
|
|
|
|
|
Aug 11 2014, 06:57
|

Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
Aug 11 2014, 07:01
|
Частый гость
 
Группа: Участник
Сообщений: 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
|
|
|
|
|
Aug 11 2014, 07:08
|

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

|
Цитата Я уже так делал, это проблему не решает.... figure 9 в даташите для Вас. А сделайте и КОД с исправлениями сюда. Цитата Только память не читается.... мало того, еще и выход у нее в HI-Z........... Это именно от того, что Вы снимаете CS.
Сообщение отредактировал Genadi Zawidowski - Aug 11 2014, 07:18
|
|
|
|
|
Aug 11 2014, 07:29
|
Частый гость
 
Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613

|
Цитата(Genadi Zawidowski @ Aug 11 2014, 10:08)  figure 9 в даташите для Вас. А сделайте и КОД с исправлениями сюда.
Это именно от того, что Вы снимаете CS. Геннадий, я вам премного благодарен что помогаете! Я появлюсь за ПК , попробую еще раз. И выложу пример. Может действительно чего упустил...
|
|
|
|
|
Aug 11 2014, 09:26
|
Частый гость
 
Группа: Участник
Сообщений: 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] Точно!  вот это я лопух.... Получается запутался в трёх соснах : )))) Переделал уже так: Код 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; } Результат все тот же...  Обнаружил что PORTC.2 после сброса болтается в единице .... а это ножка чип селекта
Сообщение отредактировал IgorKossak - Aug 11 2014, 10:17
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Aug 11 2014, 09:47
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
мда... soft_spi_write_instruct смотрим тело функции цикл, в нем SPI_CS_SET - есть, а в начале SPI_CS_CLR - нету.... вы снова не выбрали флешку  ... возьмите осцилограф, и смотрите картинки что он рисует, поставьте их на клок и чип селект. Правьте код пока не получите такие же картинки как в мануале... Огромное количество очевидных ошибок из-за невнимательности. 1 - 2 можно понять, иногда зарубает не видишь очевидного, но такое количество легко диагностируемых.... Проинитите порт, задайте частоту если есть, повыставляйте на порт 0 и 1, сделайте для них дефайны, реализуйте алгоритм общения с флэшкой, у вас еще и осцилограф есть...
|
|
|
|
|
Aug 11 2014, 09:49
|
Частый гость
 
Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613

|
Цитата(Genadi Zawidowski @ Aug 11 2014, 12:43)  Чипселект ДОЛЖЕН быть опущен в "0" на всё время работы. Сделайте пожалуйста так. Сейчас у Вас после передачи адреса чипселект снимается (переводится в "1"). Перенес чипселект на ПОРТА2 , проработало ровно пару минут, и данные выводились из флешки.... спустя 2 минуты ПОРТА2 Стал себя аналогично вести........ после сброса поднимается в единицу. Это просто какая то магия из этими пинами.....
|
|
|
|
|
Aug 11 2014, 10:17
|
Частый гость
 
Группа: Участник
Сообщений: 124
Регистрация: 21-07-13
Из: Украина, Ахтырка
Пользователь №: 77 613

|
Цитата(Golikov A. @ Aug 11 2014, 12:47)  мда... soft_spi_write_instruct смотрим тело функции цикл, в нем SPI_CS_SET - есть, а в начале SPI_CS_CLR - нету.... вы снова не выбрали флешку  ... возьмите осцилограф, и смотрите картинки что он рисует, поставьте их на клок и чип селект. Правьте код пока не получите такие же картинки как в мануале... Огромное количество очевидных ошибок из-за невнимательности. 1 - 2 можно понять, иногда зарубает не видишь очевидного, но такое количество легко диагностируемых.... Проинитите порт, задайте частоту если есть, повыставляйте на порт 0 и 1, сделайте для них дефайны, реализуйте алгоритм общения с флэшкой, у вас еще и осцилограф есть... Да выбрал я уже флешку  в том то и дело. Проработало пару минут , и теперь опять чипселект не опускается.... Фух......... заработало  убрал чипселект в функции. Теперь другой прикол. Почему вместо FF выводится 1FE ? Ну и естественно остальные данные какие попало. Ребятки, всем огромное спасибо!!!! Все заработало : )))) моей радости нет предела!
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|