// Rapsberry Pi: SPI in C - Versione 0.57 - Luglio 2013 // Copyright (c) 2013, Vincenzo Villa (https://www.vincenzov.net) // Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported. // Creative Commons | Attribution-Share Alike 3.0 Unported // https://www.vincenzov.net/tutorial/RaspberryPi/spi-c.htm // Compile: gcc max146-8.c -std=c99 -o max146-8 // Run as user with R&W right on /dev/spidev0.* (NOT ROOT!) // vv@vvrpi ~ $ ./max146-8 // Using MAX146 - Read all channel in 16 clocks/conversion mode #include #include #include #include #include #include #include #include #include #define SPI_SPEED 2000000 // SPI frequency clock #define VREF 2.500 // MAX146 voltage reference #define MAX146_CONTROL_BYTE 0x8F // 1000 1111 = Unipolar, single ended, external clock (see datasheet) #define SAMPLES 8 static const char *device = "/dev/spidev0.0"; // MAX146 CS to RPi CE0 static uint8_t mode = SPI_MODE_0; // Set SPI mode static void exit_on_error (const char *s) // Exit and print error code { perror(s); abort(); } int main(int argc, char *argv[]) { int fd; double volt[SAMPLES]; uint16_t data; uint8_t rx[SAMPLES * 2 + 1]; // RX buffer uint8_t tx[SAMPLES * 2 + 1]; // TX buffer struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = SAMPLES * 2 + 1, .delay_usecs = 0, .speed_hz = SPI_SPEED, .bits_per_word = 8, .cs_change = 0, }; for (int i = 0; i < (SAMPLES * 2 + 1 ); i++) tx[i] = 0; tx[0] = (uint8_t)MAX146_CONTROL_BYTE | 0x00; tx[2] = (uint8_t)MAX146_CONTROL_BYTE | 0x40; tx[4] = (uint8_t)MAX146_CONTROL_BYTE | 0x10; tx[6] = (uint8_t)MAX146_CONTROL_BYTE | 0x50; tx[8] = (uint8_t)MAX146_CONTROL_BYTE | 0x20; tx[10] = (uint8_t)MAX146_CONTROL_BYTE | 0x60; tx[12] = (uint8_t)MAX146_CONTROL_BYTE | 0x30; tx[14] = (uint8_t)MAX146_CONTROL_BYTE | 0x70; // Open SPI device if ((fd = open(device, O_RDWR)) < 0) exit_on_error ("Can't open SPI device"); // Set SPI mode if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) exit_on_error ("Can't set SPI mode"); // Read data if (ioctl(fd, SPI_IOC_MESSAGE(1), &tr) < 1) exit_on_error ("Can't send SPI message"); for (int i = 0; i < SAMPLES; i++) { // Adjust bit order from buffer (see datasheet) data = rx[2*i + 1]; data = data << 5; data = data | (rx[2*i + 2] >> 3); // Convert to voltage volt[i] = VREF * data / 4096; } printf("Rapsberry Pi: SPI in C - Versione 0.57 - Luglio 2013\n"); printf("Copyright (c) 2013, Vincenzo Villa (https://www.vincenzov.net)\n"); printf("Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported.\n"); printf("Creative Commons | Attribution-Share Alike 3.0 Unported\n"); printf("https://www.vincenzov.net/tutorial/elettronica-di-base/RaspberryPi/spi-c.htm\n\n"); printf("Reading data from MAX146 on %s\n\n", device); printf("TX buffer: "); for (int i = 0; i < (SAMPLES * 2 +1 ); i++) printf("0x%02X ", tx[i] ); printf ("\nRX buffer: "); for (int i = 0; i < (SAMPLES * 2 +1 ); i++) printf("0x%02X ", rx[i] ); printf ("\n"); for (int i = 0; i < SAMPLES; i++) printf("\nVoltage to CH%d = %f V", i, volt[i]); printf("\n\n"); close(fd); return (0); }