Ta strona używa ciasteczek (plików cookies), dzięki którym może działać lepiej. Dowiedz się więcejRozumiem i akceptuję

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

Autor Wiadomość
zuba1 




Posty: 236
Pomógł: 2 razy
Otrzymał 6 piw(a)
Skąd: horyniec-zdrój
Programuję w:
Bascom,C++
Moje roboty:
Pantaleon 1.0/2.0, Virtus ,FRodo1.0/2.0 SZERSZEŃ

Wysłany: 13-02-2018, 11:25   [C] STM32F051 SPI nie odbiera danych z kości pamięci.

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:

Kod programu: Zaznacz cały
/**
  ******************************************************************************
  * @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);
 }

}

Ostatnio popularny » Kurs elektroniki - #10 - Podsumowanie, Quiz



Tylko trzy rzeczy są nie skończone: 1.Wszechświat 2.Ludzka głupota 3.Wersja testowa Win-RAR-a
Ostatnio zmieniony przez zuba1 13-02-2018, 11:40, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4592
Pomógł: 484 razy
Otrzymał 630 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 13-02-2018, 13:12   

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.

Postaw piwo autorowi tego posta
 
 
zuba1 




Posty: 236
Pomógł: 2 razy
Otrzymał 6 piw(a)
Skąd: horyniec-zdrój
Programuję w:
Bascom,C++
Moje roboty:
Pantaleon 1.0/2.0, Virtus ,FRodo1.0/2.0 SZERSZEŃ

Wysłany: 13-02-2018, 13:53   

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.


Tylko trzy rzeczy są nie skończone: 1.Wszechświat 2.Ludzka głupota 3.Wersja testowa Win-RAR-a
Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4592
Pomógł: 484 razy
Otrzymał 630 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 13-02-2018, 14:47   

Hm, może MISO procesora powinno być wejściem?

Popularny artykuł » Tworzenie aplikacji Android - #1 - Wstęp


Postaw piwo autorowi tego posta
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Wersja do druku

Skocz do:  

Nie rozwiązałeś swojego problemu? Zobacz podobne tematy: Kombinowanie z przer... Mikrokontrolery z ob... Jaki język programow... Generowanie przebieg...
lub przeszukaj forum po wybranych tagach: danych, kosci, nie, odbiera, pamieci., spi, stm32f051


Powered by phpBB modified by Przemo © 2003 phpBB Group
Popularne kursy: Arduinopodstawy elektroniki