ارتباط با تراشه MCP3201 با حداکثر سرعت در RPi

برای ارتباط با تراشه MCP3201 (که یک مبدل آنالوگ به دیجیتال ۱۲ بیتی است) با حداکثر سرعت در رزبری پای، بهترین روش استفاده از رابط استاندارد لینوکس یعنی spidev است. این روش بسیار سریع‌تر و پایدارتر از شبیه‌سازی نرم‌افزاری (Bit-banging) است.

برای رسیدن به “حداکثر سرعت”:

  1. از کلاک سخت‌افزاری SPI استفاده می‌کنیم.
  2. از دستورات printf داخل حلقه خواندن پرهیز می‌کنیم (چون سرعت را به شدت پایین می‌آورد).

پیش‌نیاز: فعال‌سازی SPI

قبل از اجرا، باید SPI را در رزبری‌پای فعال کنید:

  1. دستور sudo raspi-config را بزنید.
  2. به بخش Interface Options بروید.
  3. گزینه SPI را انتخاب و Enable کنید.
  4. دستگاه را ریستارت کنید.

۱. اتصال سخت‌افزاری (Wiring)

تراشه MCP3201 را به صورت زیر به رزبری پای (پین‌های فیزیکی) متصل کنید.

دقت کنید که MCP3201 را با 3.3V تغذیه کنید، زیرا پین‌های رزبری پای تحمل 5V را ندارند.

پایه MCP3201نام پایهاتصال به RPi (نام)پین فیزیکی RPi
1VREF3.3VPin 1
2IN+ورودی آنالوگ
3IN-GNDPin 6
4VSSGNDPin 9
5CS/SHDNSPI0 CE0Pin 24
6DOUTSPI0 MISOPin 21
7CLKSPI0 SCLKPin 23
8VDD3.3VPin 17

۲. کد برنامه C (با استفاده از spidev)

این برنامه مستقیماً با درایور کرنل لینوکس صحبت می‌کند.

یک فایل به نام adc_spi.c بسازید:

C

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

// مسیر دستگاه SPI (معمولاً CE0)
static const char *device = "/dev/spidev0.0";

// تنظیمات SPI
static uint8_t mode = 0; // SPI_MODE_0
static uint8_t bits = 8;
// سرعت کلاک (1MHz). طبق دیتاشیت MCP3201 در 3.3V، حداکثر حدود 1MHz ایمن است.
// اگر تغذیه 5V بود (با مبدل سطح منطقی) تا 1.6MHz هم می‌شد.
static uint32_t speed = 1000000; 
static uint16_t delay = 0;

// تابع خواندن از SPI
int read_adc(int fd) {
    int ret;
    uint8_t tx[] = {0, 0}; // ما چیزی نمی‌فرستیم، فقط کلاک می‌زنیم
    uint8_t rx[2] = {0, 0}; // بافر دریافت (2 بایت برای 12 بیت)

    struct spi_ioc_transfer tr = {
        .tx_buf = (unsigned long)tx,
        .rx_buf = (unsigned long)rx,
        .len = 2,
        .delay_usecs = delay,
        .speed_hz = speed,
        .bits_per_word = bits,
    };

    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1) {
        perror("can't send spi message");
        return -1;
    }

    // تحلیل داده‌های دریافتی MCP3201
    // فرمت خروجی: 
    // Byte 0: X X X 0 B11 B10 B9 B8
    // Byte 1: B7 B6 B5 B4 B3 B2 B1 B0
    // بنابراین باید بیت‌ها را شیفت دهیم تا عدد 12 بیتی ساخته شود.
    
    uint16_t result = ((rx[0] & 0x1F) << 7) | (rx[1] >> 1);
    return result;
}

int main(int argc, char *argv[]) {
    int fd;
    
    // باز کردن دستگاه SPI
    fd = open(device, O_RDWR);
    if (fd < 0) {
        perror("can't open device");
        return 1;
    }

    // تنظیم مد (Mode 0)
    if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) {
        perror("can't set spi mode");
        return 1;
    }

    // تنظیم طول کلمه (8 بیت)
    if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {
        perror("can't set bits per word");
        return 1;
    }

    // تنظیم حداکثر سرعت
    if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
        perror("can't set max speed hz");
        return 1;
    }

    printf("SPI MCP3201 Interface Started at %d Hz\n", speed);
    
    // حلقه اصلی خواندن
    while (1) {
        int adcValue = read_adc(fd);
        
        // محاسبه ولتاژ (فرض VREF = 3.3V)
        float voltage = (adcValue * 3.3) / 4095.0;

        printf("ADC Value: %d  |  Voltage: %.4f V\n", adcValue, voltage);
        
        // تاخیر کوتاه برای خوانایی (در کاربرد واقعی "حداکثر سرعت" این خط را حذف کنید)
        usleep(100000); // 100ms
    }

    close(fd);
    return 0;
}

۳. کامپایل و اجرا

برای کامپایل این کد نیاز به کتابخانه خاصی ندارید چون از هدرهای استاندارد لینوکس استفاده شده است:

Bash

gcc -o adc_spi adc_spi.c

اجرا (ممکن است نیاز به دسترسی روت باشد):

Bash

sudo ./adc_spi

نکات فنی برای “حداکثر سرعت” (High Frequency Sampling)

اگر هدف شما نمونه‌برداری سیگنال (مثل اسیلوسکوپ یا پردازش صدا) است:

  1. حذف printf: عملیات چاپ در ترمینال بسیار کند است. در کاربرد واقعی، داده‌ها را در یک آرایه بزرگ در RAM ذخیره کنید و پس از پر شدن آرایه، آن‌ها را در فایل بنویسید یا پردازش کنید.
  2. فرکانس کلاک: در کد بالا speed روی 1000000 (1MHz) تنظیم شده است. اگر ولتاژ دقیق ۳.۳ ولت و سیم‌کشی کوتاه باشد، ممکن است تا ۱.۲ یا ۱.۵ مگاهرتز هم جواب دهد، اما بالاتر از آن دیتای MCP3201 خراب می‌شود.
  3. کتابخانه جایگزین: برای سرعت‌های فوق‌العاده بالا (نزدیک به Real-time)، حرفه‌ای‌ها از کتابخانه bcm2835 استفاده می‌کنند که مستقیماً به رجیسترهای حافظه دسترسی دارد (بدون واسطه سیستم عامل)، اما کد بالا برای ۹۹٪ پروژه‌ها کافی و ایمن‌تر است.

همچنین بررسی کنید

ساخت پروب اسیلوسکوپ برای اندازه گیری توان (قسمت دوم)

در قسمت یک، ما محدودیت های پهنای باند پروب های غیرفعال را پوشش دادیم و …

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *