Easyelectronics.ru

Электроника для всех
Текущее время: 29 окт 2020, 22:37

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
 Заголовок сообщения: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 15 апр 2012, 14:14 
Только пришел

Зарегистрирован: 18 мар 2012, 01:12
Сообщения: 19
Подключаю микроSD (1 gb- не НС) к StM32f4Discovery по протоколу SPI. Соединил так :

карта контроллер
1 (SS) PA4(SPI1_NSS)
2 (MOSI) PA6(SPI1_MISO)
3 GND 0v
4 VCC +3.3v
5 SCK PA5 (SPI1_SCK)
6 GND 0v
7 MISO PA7 (SPI1_MOSI)

Код
Код:
#include "sd.h"

//глобальная переменная для определения типа карты
uint8_t  SDHC;




//*********************************************************************************************
//function  инициализация  SPI1                                                              //
//argument  none                                                                             //
//return    none                                                                             //
//*********************************************************************************************
void spi_init(void)
{
   SPI_InitTypeDef   SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);   //Включить питание  блока
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  //альт.функций  и  порт А

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;     // INIT NSS
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
         GPIO_Init(GPIOA, &GPIO_InitStructure);





       GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);  // INIT MISO/MOSI/SCK
       GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
       GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
       GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
       GPIO_Init(GPIOA, &GPIO_InitStructure);

    // Set SPI interface
    SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode=SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256; // lowest  speed  for init
    SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
   // SPI_InitStructure.SPI_CRCPolynomial=7;  ///?

    SPI_Init(SPI1,&SPI_InitStructure);
    SPI_Cmd(SPI1,ENABLE);     //Enable  SPI1
}

//*********************************************************************************************
//function  обмен данными по SPI1                                                            //
//argument  передаваемый байт                                                                //
//return    принятый байт                                                                    //
//*********************************************************************************************
uint8_t spi_send (uint8_t data)
{
   while(!(SPI1->SR & SPI_I2S_FLAG_TXE));

       SPI1->DR =  data;
       while(!(SPI1->SR & SPI_I2S_FLAG_RXNE));

       return (SPI1->DR);
}


//*********************************************************************************************
//function  прием байт по SPI1                                                               //
//argument  none                                                                             //
//return    принятый байт                                                                    //
//*********************************************************************************************
uint8_t spi_read (void)
{
  return spi_send(0xff);        //читаем принятые данные
}

//********************************************************************************************
//function    посылка команды в SD                                                  //
//Arguments    команда и ее аргумент                                                      //
//return    0xff - нет ответа                                                //
//********************************************************************************************
uint8_t SD_sendCommand(uint8_t cmd, uint32_t arg)
{
  uint8_t response, wait=0, tmp;

  //для карт памяти SD выполнить корекцию адреса, т.к. для них адресация побайтная
  if(SDHC == 0)
  if(cmd == READ_SINGLE_BLOCK || cmd == WRITE_SINGLE_BLOCK )  {arg = arg << 9;}
  //для SDHC корекцию адреса блока выполнять не нужно(постраничная адресация)

  CS_ENABLE;

  //передать код команды и ее аргумент
  spi_send(cmd | 0x40);
  spi_send(arg>>24);
  spi_send(arg>>16);
  spi_send(arg>>8);
  spi_send(arg);

  //передать CRC (учитываем только для двух команд)
  if(cmd == SEND_IF_COND) spi_send(0x87);
  else                    spi_send(0x95);

  //ожидаем ответ
  while((response = spi_read()) == 0xff)
   if(wait++ > 0xfe) break;                //таймаут, не получили ответ на команду

  //проверка ответа если посылалась команда READ_OCR
  if(response == 0x00 && cmd == 58)
  {
    tmp = spi_read();                      //прочитат один байт регистра OCR
    if(tmp & 0x40) SDHC = 1;               //обнаружена карта SDHC
    else           SDHC = 0;               //обнаружена карта SD
    //прочитать три оставшихся байта регистра OCR
    spi_read();
    spi_read();
    spi_read();
  }

  spi_read();

  CS_DISABLE;

  return response;
}

//********************************************************************************************
//function    инициализация карты памяти                                      //
//return    0 - карта инициализирована                             //
//********************************************************************************************
uint8_t SD_init(void)
{
  uint8_t   i;
  uint8_t   response;
  uint8_t   SD_version = 2;             //по умолчанию версия SD = 2
  uint16_t  retry = 0 ;

  spi_init();                            //инициализировать модуль SPI
  for(i=0;i<10;i++) spi_send(0xff);      //послать свыше 74 единиц

  //выполним программный сброс карты
  CS_ENABLE;
  while(SD_sendCommand(GO_IDLE_STATE, 0)!=0x01)
    if(retry++>0x20)  return 1;
  CS_DISABLE;
  lcd_putchar(100,150,2,BLACK,WHITE,0,4);//  Сюда  не  доходит  !!!
  spi_send (0xff);
  spi_send (0xff);

  retry = 0;
  while(SD_sendCommand(SEND_IF_COND,0x000001AA)!=0x01)
  {
    if(retry++>0xfe)
    {
      SD_version = 1;
      break;
    }
  }

retry = 0;
do
{
   response = SD_sendCommand(APP_CMD,0);
   response = SD_sendCommand(SD_SEND_OP_COND,0x40000000);
   retry++;
   if(retry>0xffe) return 1;
}while(response != 0x00);


//читаем регистр OCR, чтобы определить тип карты
retry = 0;
SDHC = 0;
if (SD_version == 2)
{
   while(SD_sendCommand(READ_OCR,0)!=0x00)
    if(retry++>0xfe)  break;
}

return 0;
}

//********************************************************************************************
//function    чтение выбранного сектора SD                                      //
//аrguments    номер сектора,указатель на буфер размером 512 байт                         //
//return    0 - сектор прочитан успешно                              //
//********************************************************************************************
uint8_t SD_ReadSector(uint32_t BlockNumb,uint8_t *buff)
{
  uint16_t i=0;

  //послать команду "чтение одного блока" с указанием его номера
  if(SD_sendCommand(READ_SINGLE_BLOCK, BlockNumb)) return 1;
  CS_ENABLE;
  //ожидание  маркера данных
  while(spi_read() != 0xfe)
  if(i++ > 0xfffe) {CS_DISABLE; return 1;}

  //чтение 512 байт   выбранного сектора
  for(i=0; i<512; i++) *buff++ = spi_read();

  spi_read();
  spi_read();
  spi_read();

  CS_DISABLE;

  return 0;
}

//********************************************************************************************
//function    запись выбранного сектора SD                                      //
//аrguments    номер сектора, указатель на данные для записи                              //
//return    0 - сектор записан успешно                              //
//********************************************************************************************
uint8_t SD_WriteSector(uint32_t BlockNumb,uint8_t *buff)
{
  uint8_t     response;
  uint16_t    i,wait=0;

  //послать команду "запись одного блока" с указанием его номера
  if( SD_sendCommand(WRITE_SINGLE_BLOCK, BlockNumb)) return 1;

  CS_ENABLE;
  spi_send(0xfe);

  //записать буфер сектора в карту
  for(i=0; i<512; i++) spi_send(*buff++);

  spi_send(0xff);                //читаем 2 байта CRC без его проверки
  spi_send(0xff);

  response = spi_read();

  if( (response & 0x1f) != 0x05) //если ошибка при приеме данных картой
  { CS_DISABLE; return 1; }

  //ожидаем окончание записи блока данных
  while(!spi_read())             //пока карта занята,она выдает ноль
  if(wait++ > 0xfffe){CS_DISABLE; return 1;}

  CS_DISABLE;
  spi_send(0xff);
  CS_ENABLE;

  while(!spi_read())               //пока карта занята,она выдает ноль
  if(wait++ > 0xfffe){CS_DISABLE; return 1;}
  CS_DISABLE;

  return 0;
}



При замыкании 2-7 контактов тест SPI работает ,

НО карта не инициализируется ,


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 15 апр 2012, 20:38 
Заглядывает иногда

Зарегистрирован: 02 янв 2012, 15:04
Сообщения: 35
Автор сайта, с которого Вы брали решение, на втором рисунке соответствующей статьи допустил ошибку:
2 (MOSI) PA6(SPI1_MISO)
7 MISO PA7 (SPI1_MOSI)

Должно быть так:
2 (MOSI) PA7 (SPI1_MOSI)
7 MISO PA6(SPI1_MISO

Посмотрите внимательно на таблицу 1 здесь: http://www.gaw.ru/html.cgi/txt/interface/spi/index.htm


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 15 апр 2012, 21:02 
Только пришел

Зарегистрирован: 18 мар 2012, 01:12
Сообщения: 19
Спасибо, я об ошибке в курсе, но как баран упертый почему-то решил, что MISO надо соединять с MOSI !


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 28 апр 2012, 12:06 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 10 фев 2012, 16:40
Сообщения: 197
Откуда: Украина г.Кировоград
Привет
Кто работал с STM32f103 SDIO ? У меня карточка fly MicroSD t-flash 128 Mb.
При инициализации возвращается статус SD_START_BIT_ERR, говорит о неопределенном (не назначеном) стартовом бите всех данных в режиме wide bus mode.

Здесь происходит эта штука..

else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_STBITERR);
errorstatus = SD_START_BIT_ERR;
return(errorstatus);
}

Далее срывается инициализация....(((


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 07 май 2012, 13:36 
Заглядывает иногда

Зарегистрирован: 07 май 2012, 13:32
Сообщения: 33
sherr
можешь поделиться проэктом для работы SD card по SPI?
заранее благодарен


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 07 май 2012, 17:31 
Только пришел

Зарегистрирован: 18 мар 2012, 01:12
Сообщения: 19
Вот страшно непричесанный, корявый, недоделанный код частью надерганный откуда ни попадя
Вложение:
sd_spi_F4D.zip [35.05 Кб]
Скачиваний: 208

Работает на STM32F4Discovery (без акселерометра) + китайский дисплей на SSD1289 + пищалка + кнопки,
Что делает - инициализирует SD , разбирает часть FAT16 - корневую, показывает имена первых нескольких файлов
в корневой, и кое-какие параметры FAT, потом выдает на экран содержимое одного из файлов (недо-Ё-бук - блинн),
Скорость работы с карточкой - по минимуму ... но кое-как работает. Проект для Эклипс + ARM GCC , папки СMSIS +
StdPeriferialDriver пришлось удалить - не влезли в 256 кб.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 07 май 2012, 18:08 
Заглядывает иногда

Зарегистрирован: 07 май 2012, 13:32
Сообщения: 33
ну и на том сенк, попробую разобрать

кстати, а что за юмор:
uint8_t spi_send (uint8_t data)
{
while(!(SPI1->SR & SPI_I2S_FLAG_TXE));

SPI1->DR = data;
while(!(SPI1->SR & SPI_I2S_FLAG_RXNE));

return (SPI1->DR);
}


//*********************************************************************************************
//function прием байт по SPI1 //
//argument none //
//return принятый байт //
//*********************************************************************************************
uint8_t spi_read (void)
{
return spi_send(0xff); //читаем принятые данные
}

читаем путем отправления оО?:))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 07 май 2012, 20:26 
Только пришел

Зарегистрирован: 18 мар 2012, 01:12
Сообщения: 19
А вот уж так SPI работает - у него нет отдельно чтения и отдельно записи - только обмен ... надо прочитать - отправляем что-нибудь
и в обмен получаем искомое .


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подключаю микроSD к StM32f4Discovery - не работает
СообщениеДобавлено: 08 май 2012, 17:18 
Заглядывает иногда

Зарегистрирован: 07 май 2012, 13:32
Сообщения: 33
fа вот такой вариант:

//*********************************************************************************************
//function обмен данными по SPI1 //
//argument передаваемый байт //
//return принятый байт //
//*********************************************************************************************
uint8_t spi_send (uint8_t data)
{
while (SPI1->SR & SPI_SR_BSY);
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = data; // Передача данных
return 0;
}


//*********************************************************************************************
//function прием байт по SPI1 //
//argument none //
//return принятый байт //
//*********************************************************************************************
uint8_t spi_read (void)
{
uint8_t temp;
while (SPI1->SR & SPI_SR_BSY);
while (!(SPI1->SR & SPI_SR_RXNE));
temp = SPI1->DR; // Чтение принятых данных
return temp;
}

и еще, навесил на порты (кроме питания и земли) резисторы на 47к. они там же должны быть?
карточку питаю от 3В выхода прямо на плате...


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB