Skocz do zawartości

[C] stm32f4discovery problem z fatfs


dawidos145

Pomocna odpowiedź

Witajcie, próbóję podłączyć do stm32 kartę microsd, przez slot zamontowany na wykonanej płytce drukowanej, PIN CS mam na PE15, SCK -PB13 , MISO - PB14, MOSI - PB15

korzystam z gotowego programu na fatfs przez spi, lecz niestety fresult ciągle ukazuje wartość "FR_NOT_READY" a na końcu FR_INVALID_OBJECT, nie wiem gdzie szukać problemu.

void SPI_SD_Init( void )
{
   	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //taktowanie dla SPI2
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //taktowanie dla B

// GPIOB - PE15( CS ) 
	GPIOE->MODER |= GPIO_MODER_MODER15_0;
	GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR15;

//sck
	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

//MISO
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
//MOSI
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

//SPI
	SPI_InitTypeDef SPI_InitStruct;

	SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
	SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
	SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
	SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
	SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStruct.SPI_CRCPolynomial = 7;
	SPI_Init(SPI2, &SPI_InitStruct);

	SPI_CalculateCRC(SPI2, DISABLE);
	SPI_Cmd(SPI2, ENABLE);

	RCC->APB1RSTR |= RCC_APB1RSTR_SPI2RST;
    delay_ms( 10 );
    RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST;


DESELECT();
}

static
void xmit_spi (BYTE Data)  // Wyslanie bajtu do SD
{
 u8 D = 0;

while( !( SPI2->SR & SPI_SR_TXE ));
SPI2->DR = Data;
while( !( SPI2->SR & SPI_SR_RXNE ));
D = SPI2->DR;
}

static
BYTE rcvr_spi (void) 		// Odebranie bajtu z SD
{
 u8 Data = 0;
u8 i;
while( !( SPI2->SR & SPI_SR_TXE ));
SPI2->DR = 0xFF;
while( !( SPI2->SR & SPI_SR_RXNE ));
for(i=0;i<10;i++);
Data = SPI2->DR;

 return Data;
}

main

/*
* main.c
*      Author: Grzegorz H.
*/
#include "stm32f4xx.h"
#include "system_stm32f4xx.h"
#include "delay.h"
#include "fpu.h"
#include "spi_sd.h"
#include "ff.h"

#define SysTick_Frequency 21000000

FATFS fatfs;
FIL plik;
FRESULT fresult;
UINT zapisanych_bajtow = 0;
UINT zapianie_bajtow = 0;
char * buffor = "123456789abcdef\r\n";
uint16_t i;

int main( void )
{
   SystemInit();



   fpu_enable();
   delay_init( 168 );
   SPI_SD_Init();

   SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    SysTick_Config(SysTick_Frequency / 100);

   fresult = f_mount( 0, &fatfs );
   fresult = f_open( &plik, "demo.wav", FA_OPEN_ALWAYS | FA_WRITE );
   if( fresult == FR_OK )
   {
   	for( i = 0; i < 1000; i++ )
           fresult = f_write( &plik, ( const void * ) buffor, 17, &zapisanych_bajtow );
   }

   fresult = f_close( &plik );

   for(;;)
   {

   }

return 0;
}

void SysTick_Handler()
{
disk_timerproc();
}
Link do komentarza
Share on other sites

wiesz co, jakis no name , 2 gb micro sd , sd-c26g taiwan 😃 może faktycznie wina karty, ogólnie program zaczerpnięty i działający dlatego szukam już igły w stogu siana.. jutro znajdę inną i dalej walcze ! 👹

[ Dodano: 25-09-2016, 22:36 ]

mam pytanie wszystkie linie podłączone są bezpośrednio do portów, jedynie SD CS podniesione jest przez rezystor 10kΩ do +3V.

czy linię MISO,MOSI,SCK też trzeba podnieść ? i czy można to zrobić programowo ?

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dalej wisi, przechodzi przez konfiguracje SPI2, niestety przy funkcji wait_ready() - > rcvr_spi() tutaj powinien nastąpić odczyt, niestety zwracana wartość data to 0.

troche zmieniłem konfigurację na bardziej przyjazną, proszę o porady.

MAIN

int main( void )
{

   SystemInit();
    SPI_SD_Init();



       fresult = f_mount( 0, &fatfs);
       fresult = f_open( &plik, "demo.wav", FA_OPEN_EXISTING | FA_READ );
       if( fresult == FR_OK )
       {
       		//fresult = f_read(&plik, void * buffor, 17, &zapisanych_bajtow);
       		fresult = f_read( &plik, ( void * ) buffor2, 112940, &odczytanych_bajtow );
       }
       fresult = f_close( &plik );
}

SPI_SD

void SPI_SD_Init( void )  //inicjalizuje SPI dla SD
{
GPIO_InitTypeDef  GPIO_InitStructure;
SPI_InitTypeDef   SPI_InitStructure;
 volatile BYTE dummyread;

  // Konfiguracja wyprowadzen i kontrolera SPI:
/* Enable GPIO clock for CS */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    /* Enable SPI clock, SPI2 */


  // Wlaczenie sygnalow zegarowych dla peryferiow
  RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE );


  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2 );
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2 );


  // PE15 CS
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode =	GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOE, &GPIO_InitStructure);

  DESELECT_SD();

  //SCK, MISO and MOSI SD

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  // Konfiguracja SPI
  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_High; // low ?
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI2, &SPI_InitStructure);

  // Wlacz SPI
  SPI_Cmd(SPI2, ENABLE);

   while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) { ; }
    dummyread = SPI_ReceiveData(SPI2);

}

ODEBRANIE BAJTU I WYSLANIE

static
void xmit_spi (uint8_t outB)  // Wyslanie bajtu do SPI
{
u8 Data = 0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, Data);
}

static
BYTE rcvr_spi (void) 		// Odebranie bajtu z SPI
{
u8 Data = 0;
// Wysłanie 0xFF
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, 0xFF);
// odebranie bajtu
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
Data = SPI_I2S_ReceiveData(SPI2);
return Data;
}

static
BYTE wait_ready (void)
{
   BYTE res;
   Timer2 = 50;    /* Wait for ready in timeout of 500ms */
   rcvr_spi();
   do
       res = rcvr_spi();
   while ((res != 0xFF) && Timer2);

   return res;
}
static
void power_on (void)
{
u8 i, cmd_arg[6];
u32 Count = 0xFFF;

// Inicjalizacja karty i przelaczenie w tryb SPI:
    DESELECT_SD();        // CS = 1
     for (i = 0; i < 10; i++)
            xmit_spi(0xFF);    // Wyslij 0xFF 10 razy = 80 cykli zegarowych
                // (wymaganych co najmniej 74 cykli)
     SELECT_SD();        // CS = 0

      // Przygotowanie ramki inicjujacej do wyslania
      cmd_arg[0] = (CMD0 | 0x40);
      cmd_arg[1] = 0;    // Argument komendy
      cmd_arg[2] = 0;    // nawet, gdy komenda go nie ma
      cmd_arg[3] = 0;    // musi zostac wyslany w postaci zer
      cmd_arg[4] = 0;
      cmd_arg[5] = 0x95;    // CRC = 0x95

      for (i = 0; i < 6; i++)        // Wyslanie ramki
            xmit_spi(cmd_arg[i]);

      while ((rcvr_spi() != 0x01) && Count) // Czeka na 0x01
            Count--;
      DESELECT_SD();        // CS = 1
      xmit_spi( 0XFF );    // Wyslij 0xFF

      PowerFlag = 1;


}
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.