Skocz do zawartości

[C] STM32F051 SPI nie odbiera danych z kości pamięci.


zuba1

Pomocna odpowiedź

Cześć. Borykam się z SPI w układzie stm32f051. Komunikuję się z układem zewnętrznej pamięci flash w celu zapisu rekordów pomiaru dalmierza. Natrafiłem na dziwną przypadłość. Układ startuje i wysyła dane do układu prawidłowo (sprawdzone analizatorem). Układ też chętnie odpowiada zgodnie z oczekiwaniami. Ale gdy chcę sprawdzić co odebrał, w debuggerze wyświetla mi się 0x00 lub 0xFF tak jak by noga była zwarta do masy lub do plusa (połączenie pewne, pomiar analizatora dokonany niedaleko wyprowadzenia). Oczywiście dzieje się tak tylko w momencie gdy zakomentuję while-a czekającego na reset flagi odebrania danych. W innym wypadku program zawiesi się na tym etapie. Dodaję kod:

/**
 ******************************************************************************
 * @file    main.c
 * @author  Ac6
 * @version V1.0
 * @date    01-December-2013
 * @brief   Default main function.
 ******************************************************************************
*/


#include "stm32f0xx.h"
#include "stm32f0_discovery.h"

volatile uint32_t timer_ms = 0;
#define PCS		1
#define NCS		0



void SysTick_Handler()		//handler przerwania
{
if (timer_ms) {
timer_ms--;
}
}

void delay_ms(int time)
{
timer_ms = time;
while (timer_ms) {};
}

uint8_t spi(uint8_t byte,uint8_t mode){

uint8_t data_rev;

GPIO_ResetBits(GPIOA, GPIO_Pin_4); //cs to low


 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
 SPI_SendData8(SPI1, byte);

 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
 data_rev=SPI_ReceiveData8(SPI1);

 if(mode==PCS) GPIO_SetBits(GPIOA, GPIO_Pin_4); //cs to high

return data_rev;
}


void flash_init(){

spi(0x06,PCS);
delay_ms(50); //small delay
spi(0x66,PCS);
delay_ms(50);
spi(0x99,PCS);
delay_ms(50);
}

uint8_t flash_read(uint8_t addr){
uint8_t data;

spi(0x03,NCS);
spi(0x00,NCS);
spi(0x00,NCS);
spi(addr,NCS);
data = spi(0xFF,PCS);

return data;
}



void flash_write(uint8_t addr, uint8_t data){

spi(0x02,NCS);
spi(0x00,NCS);
spi(0x00,NCS);
spi(addr,NCS);
spi(data,PCS);
}


int main(void)
{
//sys clock config
SysTick_Config(SystemCoreClock / 1000); //przerwanie co 1ms

//spi config

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

SPI_InitTypeDef SPI_InitTypeDefStruct;


SPI_InitTypeDefStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitTypeDefStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitTypeDefStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitTypeDefStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitTypeDefStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitTypeDefStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8 ;
SPI_InitTypeDefStruct.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_Init(SPI1, &SPI_InitTypeDefStruct);


RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

GPIO_InitTypeDef GPIO_InitTypeDefStruct;

GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitTypeDefStruct);

GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitTypeDefStruct);

GPIO_SetBits(GPIOA, GPIO_Pin_4); //cs to high


SPI_Cmd(SPI1, ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOC, &GPIO_InitTypeDefStruct);
GPIO_ResetBits(GPIOC, GPIO_Pin_4);


//flash init
delay_ms(2000);

flash_init();
uint8_t data=0;

while (1) {
 flash_write(0x01,0x33);
 delay_ms(100);
 data=flash_read(0x01);

 if (data==0x33)
 {
	 GPIO_SetBits(GPIOC, GPIO_Pin_9);
 }else{
	 GPIO_ResetBits(GPIOC, GPIO_Pin_9);
 }

 delay_ms(1000);
}

}
Link do komentarza
Share on other sites

A testowałeś swój SPI na innych operacjach z ta pamięcią? Jakieś odczyty rejestru stanu? Zawartość wygląda sensownie? Chodzi mi o odróżnienie, czy problem leży w samych funkcjach SPI czy może w interfejsie do pamięci, kodach operacji (choć 0x03 i 0x02 wydają się typowe) czy niezrozumieniu protokołu.

Czy odczyt jakiegoś dziewiczego bloku pokazuje ciąg 0xFF?

Napisz jaka to kostka, bo szeregowe FLASHe potrafią być całkiem skomplikowane i są różne. Odblokowałeś zapis? Kasujesz sektory/bloki przed zapisem? Ta operacja zajmuje trochę czasu i wymaga odczytu rejestru stanu. Jeśli komunikacja działa, po starcie kasowania dostaniesz niegotowość pamięci (bit w rejestrze stanu) a po jakimś czasie gotowość. Przynajmniej będzie widać, że pamięć żyje a Twoje funkcje działają.

Nie testuj pamięci FLASH wciąż na tej samej komórce i tym samym sektorze. Do komórki FLASHa możesz "doprogramowywać" tylko bity zerowe. Nie możesz odwrócić na jeden inaczej jak tylko przez skasowanie dużego obszaru.

Link do komentarza
Share on other sites

Jest to kość pochodząca z płytki esp8266. Na analizatorze po wywołaniu komendy zapisu wartości np. 0x33 po wysłaniu komendy odczytu, z przebiegów wynika że układ odpowiada wartością 0x33 więc układ jest inicjalizowany i odpowiada prawidłowo. Tylko nie wiem dlaczego to co było na kablu, nie trafia do bufforu.

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

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.