Skocz do zawartości

Komunikacja Rpi i STM32(HAL) via I2C


Pomocna odpowiedź

Napisano

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.

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.

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.

@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.

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...