Skocz do zawartości

Komunikacja Rpi i STM32(HAL) via I2C


r_bot

Pomocna odpowiedź

Cześć, próbowaliście kiedyś komunikacji pomiędzy RPI stm32? Próbuję użyć do tego celu I2C, na Rpi używam BCM2835 biblioteki, a na STM32, Hal. Niestety działa mi tylko nadawanie z RPi do STM32, STM32 nic nie wysyła.

na STM32 włączam nadawanie i obiernie danych przez DMA.

HAL_I2C_Slave_Receive_DMA(&hi2c2, (uint8_t*)i2c_rx, SIZE);
 HAL_I2C_Slave_Transmit_DMA(&hi2c2, (uint8_t*)i2c_tx, SIZE);

A na Rpi konfiguracja, wysyłanie i odbieranie:

#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

#define I2C_ADDRESS 10

#define LED_RED RPI_GPIO_P1_11

#define SIZE 8
char i2c_tx[SIZE];
char i2c_rx[SIZE];

void timer_handler (int signum)
{
static int state = 0;
static int n = 0;
int i = 0;

switch(state)
{
case 0:
	while(i<SIZE)
	{
		i2c_tx[i] = 255-n;
		i++;
		n++;
	}
	i = 0;
	while(i<SIZE)
	{
		printf("%d ", i2c_tx[i]);
		i++;
	}
	printf("\n");
	bcm2835_gpio_set(LED_RED);
	bcm2835_i2c_write(i2c_tx, SIZE);
	state = 1;
	break;
case 1:
	bcm2835_i2c_read(i2c_rx, SIZE);
	i = 0;
	while(i<SIZE)
	{
		printf("%d ", i2c_rx[i]);
		i++;
	}
	printf("\n\n");
	bcm2835_gpio_clr(LED_RED);
	state = 0;
	break;
}
}

int main(void)
{


if(!bcm2835_init())
{
	printf("INIT ERROR\n");
}
else
{
	printf("INIT OK\n");
}

bcm2835_gpio_fsel(LED_RED, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(I2C_EN, BCM2835_GPIO_FSEL_OUTP);

if(!bcm2835_i2c_begin())
{
	printf("I2C ERROR\n");
}
else
{
	printf("I2C OK\n");
}

bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_150);
bcm2835_i2c_setSlaveAddress(I2C_ADDRESS);
bcm2835_i2c_set_baudrate(10000);

struct sigaction sa;
struct itimerval timer;

/*Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &sa, NULL);

/*Configure the timer to expire after 1 sec... */
timer.it_value.tv_sec = 1;
timer.it_value.tv_usec = 0;
/* ... and every 1000 msec after that. */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 0;
/* Start a virtual timer. It counts down whenever this process is
 executing. */
setitimer (ITIMER_VIRTUAL, &timer, NULL);

while(1)
{

}

return EXIT_SUCCESS;
}

Konfigurację I2C zamieszczam w załącznikach.

Wiem, że HAL może nie jest najlepszy, kiedyś chciałbym to napisać samemu, ale na razie zależy mi na szybkim prototypowaniu urządzenia.

Interesują mnie też inne formy komunikacji pomiędzy RPI a STM32, jak SPI i USB.

Dziękuję za pomoc.

Link do komentarza
Share on other sites

Komunikacja między Rpi, a stm32 za pomocą i2c nie różni się niczym od komunikacji między innymi urządzeniami, np mikrokontrolerem a czujnikiem. Oba układy wykorzystują napięcie 3.3V wystarczy więc dodać rezystory podciągające i komunikacja powinna przebiegać prawidłowo.

Niestety trzeba najpierw dobrze poznać sam protokół i2c - szczególnie oprogramowanie slave-a, czyli stm32 jest nieco trudniejsze. Najczęściej masterem jest mikrokontroler, a slave-m czujnik. Wtedy to co trudne jest już zaszyte w układzie scalonym. Nie jest to czarna magia, ale musisz trochę poczytać o i2c, zanim prawidłowo go wykorzystasz.

Z porad na szybko - użyj SPI jest dużo łatwiejszy. No i raczej nie zaczynaj od USB, chyba że jesteś bardzo ambitny.

Link do komentarza
Share on other sites

Jest jedna różnica w przypadku I2C na Raspberry Pi: ze względu na błąd sprzętowy clock stretching nie działa poprawnie i prowadzi do gubienia danych. Żeby tego uniknąć trzeba albo upewnić się, że slave jest wystarczająco szybki, żeby dane wysyłać i odbierać bez rozciągania zegara, albo użyć programowej implementacji I2C po stronie Raspberry Pi.

Albo użyć innego komputera jednopłytkowego, który nie ma takich problemów.

Link do komentarza
Share on other sites

@Elvis

I2C wydaje się łatwiejsze dla mnie. Rezystory podciągające sa konieczne? Wydaje mi się, że Rpi ma już rezystory podciągające, ale jeszcze to sprawdzę.

Nie rozumiem różnicy pomiędzy DMA normal a DMA circular.

@deshipu

Musi to być raspberry, docelowo Raspberry Pi zero, ewentualnie mogę spróbować SPI.

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

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.