Skocz do zawartości

Kurs STM32 - #9 - SPI w praktyce, ekspander I/O


Pomocna odpowiedź

html_mig_img
Poznaliśmy już jeden interfejs szeregowy UART, który był asynchroniczny. Teraz poznamy kolejny, tym razem synchroniczny SPI.Jest to prosty i szybki interfejs, pozwalający na podłączanie różnych układów peryferyjnych. W tej części kursu wykorzystamy go do podłączenia ekspandera portów.

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Link to post
Share on other sites

poczciwy, to nie błąd. Przeczytaj zadanie raz jeszcze. Komendy sterujące mają być wysyłane do płytki z komputera przez UART. To, że do sterowania ekspanderem potrzebne jest SPI, to chyba po tej części oczywistość 🙂

Link to post
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

TTakitani, witam na forum 🙂 Adres urządzenia w tym przypadku ustawia się na pindach A0-A1 układu MCP23S08. Więcej na ten temat znajdziesz w dokumentacji ekspandera. Sprawdź np. 8 stronę noty katalogowej linkowanej w artykule.

Link to post
Share on other sites
TTakitani, witam na forum 🙂 Adres urządzenia w tym przypadku ustawia się na pindach A0-A1 układu MCP23S08. Więcej na ten temat znajdziesz w dokumentacji ekspandera. Sprawdź np. 8 stronę noty katalogowej linkowanej w artykule.

Dzięki!

Link to post
Share on other sites

Hej.

Mam problem z drugą częścią lekcji. Chodzi o sterowanie diody poprzez przycisk. Nawet po wklejeniu kodu jak na prezentacji dioda nie reaguje na zwarcia pinu GP1 do masy. Poprzedni przypadek z synchronicznie migającą diodą działał bez problemu. W czym może być problem? Bawiłem się trochę kodem, ale nic nie pomogło.

Edit: Dodatkowo zauważyłem, że po załadowaniu programu do MCU włączyła się zielona dioda na płytce (pin PA5).

Dzięki!

Edytowano przez MaciejZyskowski
Link to post
Share on other sites
#include "stm32f10x.h"

#define MCP_IODIR		0x00
#define MCP_IPOL		0x01
#define MCP_GPINTEN		0x02
#define MCP_DEFVAL		0x03
#define MCP_INTCON		0x04
#define MCP_IOCON		0x05
#define MCP_GPPU		0x06
#define MCP_INTF		0x07
#define MCP_INTCAP		0x08
#define MCP_GPIO		0x09
#define MCP_OLAT		0x0a

uint8_t spi_sendrecv(uint8_t byte)
{
 // poczekaj az bufor nadawczy bedzie wolny
 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
 SPI_I2S_SendData(SPI1, byte);

 // poczekaj na dane w buforze odbiorczym
 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
 return SPI_I2S_ReceiveData(SPI1);
}

void mcp_write_reg(uint8_t addr, uint8_t value)
{
 GPIO_ResetBits(GPIOC, GPIO_Pin_0);
 spi_sendrecv(0x40);
 spi_sendrecv(addr);
 spi_sendrecv(value);
 GPIO_SetBits(GPIOC, GPIO_Pin_0);
}

uint8_t mcp_read_reg(uint8_t addr)
{
 GPIO_ResetBits(GPIOC, GPIO_Pin_0);
 spi_sendrecv(0x41);
 spi_sendrecv(addr);
 uint8_t value = spi_sendrecv(0xff);
 GPIO_SetBits(GPIOC, GPIO_Pin_0);
 return value;
}

int main(void)
{
 GPIO_InitTypeDef gpio;
 SPI_InitTypeDef spi;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

 GPIO_StructInit(&gpio);
 gpio.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; // SCK, MOSI
 gpio.GPIO_Mode = GPIO_Mode_AF_PP;
 gpio.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA, &gpio);

 gpio.GPIO_Pin = GPIO_Pin_6; // MISO
 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(GPIOA, &gpio);

 gpio.GPIO_Pin = GPIO_Pin_0; // CS
 gpio.GPIO_Mode = GPIO_Mode_Out_PP;
 GPIO_Init(GPIOC, &gpio);
 GPIO_SetBits(GPIOC, GPIO_Pin_0);

 SPI_StructInit(&spi);
 spi.SPI_Mode = SPI_Mode_Master;
 spi.SPI_NSS = SPI_NSS_Soft;
 spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
 SPI_Init(SPI1, &spi);
 SPI_Cmd(SPI1, ENABLE);

 mcp_write_reg(MCP_IODIR, ~0x01);
 mcp_write_reg(MCP_GPPU, 0x02);

 while (1) {
 if ((mcp_read_reg(MCP_GPIO) & 0x02) == 0) {
 mcp_write_reg(MCP_OLAT, 0x01);
 } else {
 mcp_write_reg(MCP_OLAT, 0x00);
 }
 }

}

 

3 godziny temu, Treker napisał:

@MaciejZyskowski, możesz dla pewności wkleić dokładnie swój program oraz pokazać podłączenie elektroniki? Różne cuda na forum już bywały - lepiej zacząć od sprawdzenia podstaw 😉

Oto kod, po prostu skopiowany. Poprzedni, z migającym ledem działał poprawnie. Jako przełącznika używam przewodu, który zwieram do masy, albo jest niepodłączony. Podsyłam zdjęcie podłączenia. Profesjonalnie, wiem. Podkreśliłem podłączenie LED-a, pozostałe są do innego ćwiczenia. Do pinu 2 expandera podłączony jest omówiony wcześniej przewód.

48358580_276886949675637_4490849462901538816_n.jpg

Link to post
Share on other sites

Dziwna sprawa, jeśli kod jest taki sam jak w kursie - a wygląda na to, że jest - to chyba winy trzeba się jednak doszukiwać w podłączeniu. Możesz pokazać jakieś dokładniejsze zdjęcia, na których widać dobrze wszystkie połączenia? Testowałeś może czy inne piny ekspandera działają poprawnie w roli wejść lub wyjść?

Link to post
Share on other sites
Dnia 14.12.2018 o 13:05, Treker napisał:

Dziwna sprawa, jeśli kod jest taki sam jak w kursie - a wygląda na to, że jest - to chyba winy trzeba się jednak doszukiwać w podłączeniu. Możesz pokazać jakieś dokładniejsze zdjęcia, na których widać dobrze wszystkie połączenia? Testowałeś może czy inne piny ekspandera działają poprawnie w roli wejść lub wyjść?

Tak, zrobiłem zadanie 9.1 i 9.2. Zmieniłem wejście na inny port, przykładowo dla GP7 zrobiłem to poprzez modyfikacje rejestru w funkcji read:

mcp_read_reg(MCP_GPIO) & 0x40

Zauważyłem, że jeżeli zmienię Ifa tak, aby dioda włączona była bez zwierania przewodu do masy ta dioda nie włącza się. Nie dotykając układu, po załadowaniu kodu np. z zadania 9.2 wszystkie diody świecą normalnie. Podłączenie samego SPI uważam, że jest okej, ponieważ jak inaczej miałyby mi działać poprzednie zadania?

 while (1) {
 if ((mcp_read_reg(MCP_GPIO) & 0x40) == 0) {
 mcp_write_reg(MCP_OLAT, 0x00);
 } else {
 mcp_write_reg(MCP_OLAT, 0x01);
 }
 }

I tak dzięki za pomoc, może sam później jeszcze na coś wpadnę. Tymczasem idę dalej z kursem. 🙂

  • Lubię! 1
Link to post
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.