برای ارتباط با تراشه MCP3201 (که یک مبدل آنالوگ به دیجیتال ۱۲ بیتی است) با حداکثر سرعت در رزبری پای، بهترین روش استفاده از رابط استاندارد لینوکس یعنی spidev است. این روش بسیار سریعتر و پایدارتر از شبیهسازی نرمافزاری (Bit-banging) است.
برای رسیدن به “حداکثر سرعت”:
- از کلاک سختافزاری SPI استفاده میکنیم.
- از دستورات
printfداخل حلقه خواندن پرهیز میکنیم (چون سرعت را به شدت پایین میآورد).
پیشنیاز: فعالسازی SPI
قبل از اجرا، باید SPI را در رزبریپای فعال کنید:
- دستور
sudo raspi-configرا بزنید. - به بخش Interface Options بروید.
- گزینه SPI را انتخاب و Enable کنید.
- دستگاه را ریستارت کنید.
۱. اتصال سختافزاری (Wiring)
تراشه MCP3201 را به صورت زیر به رزبری پای (پینهای فیزیکی) متصل کنید.
دقت کنید که MCP3201 را با 3.3V تغذیه کنید، زیرا پینهای رزبری پای تحمل 5V را ندارند.
| پایه MCP3201 | نام پایه | اتصال به RPi (نام) | پین فیزیکی RPi |
| 1 | VREF | 3.3V | Pin 1 |
| 2 | IN+ | ورودی آنالوگ | – |
| 3 | IN- | GND | Pin 6 |
| 4 | VSS | GND | Pin 9 |
| 5 | CS/SHDN | SPI0 CE0 | Pin 24 |
| 6 | DOUT | SPI0 MISO | Pin 21 |
| 7 | CLK | SPI0 SCLK | Pin 23 |
| 8 | VDD | 3.3V | Pin 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)
اگر هدف شما نمونهبرداری سیگنال (مثل اسیلوسکوپ یا پردازش صدا) است:
- حذف
printf: عملیات چاپ در ترمینال بسیار کند است. در کاربرد واقعی، دادهها را در یک آرایه بزرگ در RAM ذخیره کنید و پس از پر شدن آرایه، آنها را در فایل بنویسید یا پردازش کنید. - فرکانس کلاک: در کد بالا
speedروی1000000(1MHz) تنظیم شده است. اگر ولتاژ دقیق ۳.۳ ولت و سیمکشی کوتاه باشد، ممکن است تا ۱.۲ یا ۱.۵ مگاهرتز هم جواب دهد، اما بالاتر از آن دیتای MCP3201 خراب میشود. - کتابخانه جایگزین: برای سرعتهای فوقالعاده بالا (نزدیک به Real-time)، حرفهایها از کتابخانه bcm2835 استفاده میکنند که مستقیماً به رجیسترهای حافظه دسترسی دارد (بدون واسطه سیستم عامل)، اما کد بالا برای ۹۹٪ پروژهها کافی و ایمنتر است.
سایت آموزشی الکترونیک و کامپیوتر اوپن مقاله های آموزشی الکترونیک و کامپیوتر و فن آوری