برای اتصال دتکتورها به پورت C میکروکنترلر ATmega8، از یک یا چند شیفت رجیستر 74HC165 (که قابلیت تبدیل چند ورودی به یک سیگنال سریال را دارد) یا از یک روش Multiplexing میتوان استفاده کرد. در اینجا نحوه اتصال پورت C به دتکتورها با شیفت رجیستر 74HC165 را شرح میدهم:
شیفت رجیستر 74HC165 دارای ۸ ورودی است.
هر دتکتور را میتوان به یکی از ورودیهای شیفت رجیستر متصل کرد.
در این صورت، هر شیفت رجیستر قادر خواهد بود ۸ ورودی (برای ۸ دتکتور) را دریافت کند.
برای ۱۲ دتکتور، به دو عدد شیفت رجیستر نیاز داریم.
هر شیفت رجیستر نیاز به ۳ سیگنال از میکروکنترلر دارد:
در اینجا، شیفت رجیسترها به پورتهای Data (PD0)، Clock (PD1) و Latch (PD2) از میکروکنترلر متصل میشوند.
در برنامه کد زیر برای خواندن وضعیت دتکتورها از شیفت رجیسترها میتواند استفاده شود:
#define DATA_PIN PD0 // سیگنال داده
#define CLOCK_PIN PD1 // سیگنال ساعت
#define LATCH_PIN PD2 // سیگنال لچ
// خواندن دادهها از شیفت رجیستر
uint8_t readShiftRegister() {
uint8_t value = 0;
for (uint8_t i = 0; i < 8; i++) {
// راهاندازی سیگنال ساعت
PORTD &= ~(1 << CLOCK_PIN); // صفر کردن ساعت
if (PIND & (1 << DATA_PIN)) { // خواندن داده از ورودی
value |= (1 << i); // قرار دادن داده در بیت مناسب
}
PORTD |= (1 << CLOCK_PIN); // بالابردن ساعت
}
return value;
}
void main() {
// تنظیم پورتها به عنوان ورودی و خروجی
DDRD = 0x00; // پورت D به عنوان ورودی (برای داده از شیفت رجیستر)
DDRC = 0xFF; // پورت C به عنوان خروجی
while (1) {
uint8_t detector_status = readShiftRegister();
// پردازش وضعیت دتکتورها
// به ازای هر دتکتور وضعیت را بررسی کنید و در صورت آلودگی، پردازشهای لازم را انجام دهید
}
}
آیا این توضیحات کمکتون کرد؟
در اینجا برنامه کامل و اصلاحشده برای میکروکنترلر ATmega8 با استفاده از دو شیفت رجیستر 74HC165 برای اتصال ۱۲ دتکتور را مینویسم. برنامه به گونهای طراحی شده است که دتکتورها به پورتهای میکرو متصل میشوند و وضعیت آلودگی هر دتکتور بر اساس شمارشها نمایش داده میشود.
#include <mega8.h>
#include <delay.h>
#include <lcd.h> // فرض بر این است که کتابخانه LCD در دسترس است
// پینهای شیفت رجیستر
#define DATA_PIN PD0 // سیگنال داده
#define CLOCK_PIN PD1 // سیگنال ساعت
#define LATCH_PIN PD2 // سیگنال لچ
// پینهای متصل به موتور نوار نقاله و دکمهها
#define CONVEYOR_PIN PC0 // پین کنترل نوار نقاله
#define START_BUTTON PC1 // پین دکمه شروع
#define INFO_BUTTON PC2 // پین دکمه اطلاع از آلودگی
// متغیرهای وضعیت
uint8_t detector_status = 0; // وضعیت دتکتورها
uint8_t contaminated = 0; // وضعیت آلودگی لباس
uint8_t detector_number = 0; // شماره دتکتور آلوده
// خواندن دادهها از شیفت رجیستر
uint8_t readShiftRegister() {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; i++) {
PORTD &= ~(1 << CLOCK_PIN); // صفر کردن ساعت
if (PIND & (1 << DATA_PIN)) { // خواندن داده از ورودی
value |= (1 << i); // قرار دادن داده در بیت مناسب
}
PORTD |= (1 << CLOCK_PIN); // بالا بردن ساعت
}
return value;
}
void init() {
// تنظیم پورتها به عنوان ورودی و خروجی
DDRD = 0x00; // پورت D به عنوان ورودی (برای داده از شیفت رجیستر)
DDRC = 0xFF; // پورت C به عنوان خروجی
PORTC = 0x00; // خاموش کردن تمام پینهای پورت C
DDRB = 0xFF; // پورت B به عنوان خروجی (LCD)
// تنظیم پایههای شیفت رجیستر
PORTD &= ~(1 << LATCH_PIN); // صفر کردن سیگنال لچ
}
void showInProgress() {
lcd_clear();
lcd_gotoxy(0, 0);
lcd_puts("IN PROGRESS");
}
void showContaminate(uint8_t detector, uint8_t cps) {
lcd_clear();
lcd_gotoxy(0, 0);
lcd_puts("CONTAMINATE");
delay_ms(1000); // نمایش برای 1 ثانیه
lcd_clear();
lcd_gotoxy(0, 0);
lcd_puts("Detector: ");
lcd_putc(detector + '0'); // شماره دتکتور
lcd_gotoxy(0, 1);
lcd_puts("CPS: ");
lcd_putc(cps + '0'); // میزان شمارش
delay_ms(1000); // نمایش برای 1 ثانیه
}
void conveyorStop() {
PORTC &= ~(1 << CONVEYOR_PIN); // توقف نوار نقاله
}
void conveyorStart() {
PORTC |= (1 << CONVEYOR_PIN); // شروع حرکت نوار نقاله
}
void checkDetectors() {
uint8_t i;
detector_status = readShiftRegister(); // خواندن وضعیت دتکتورها از شیفت رجیستر
for (i = 0; i < 12; i++) {
if (detector_status & (1 << i)) {
contaminated = 1;
detector_number = i + 1;
showContaminate(detector_number, detector_status); // نمایش پیغام آلودگی
conveyorStop();
break;
}
}
if (!contaminated) {
lcd_clear();
lcd_gotoxy(0, 0);
lcd_puts("No Contaminate");
delay_ms(1000);
}
}
void main(void) {
init();
lcd_init(LCD_DISP_ON); // راهاندازی نمایشگر LCD
showInProgress(); // نمایش پیغام در حال انجام
while (1) {
if (PINC & (1 << START_BUTTON)) { // بررسی وضعیت دکمه شروع
checkDetectors(); // بررسی وضعیت دتکتورها
}
if (PINC & (1 << INFO_BUTTON)) { // بررسی وضعیت دکمه اطلاع از آلودگی
if (contaminated) {
showContaminate(detector_number, detector_status); // نمایش آلودگی
} else {
lcd_clear();
lcd_gotoxy(0, 0);
lcd_puts("No Contaminate");
delay_ms(1000);
}
contaminated = 0; // وضعیت آلودگی را صفر میکنیم
conveyorStart(); // نوار نقاله را شروع میکنیم
showInProgress(); // پیغام در حال انجام را نمایش میدهیم
}
}
}
تعریف پینها:
DATA_PIN
, CLOCK_PIN
, LATCH_PIN
: این پینها برای ارتباط با شیفت رجیستر 74HC165 استفاده میشوند.CONVEYOR_PIN
: پین کنترل نوار نقاله است.START_BUTTON
و INFO_BUTTON
: دکمههای ورودی برای شروع اندازهگیری و اطلاع از آلودگی هستند.تابع readShiftRegister
:
value
ذخیره میکند.تابع showInProgress
:
تابع showContaminate
:
cps
بهعنوان نمونه استفاده شده) نمایش داده میشود.تابع checkDetectors
:
کنترل نوار نقاله:
conveyorStop
).conveyorStart
).
اگر سوال دیگری دارید یا نیاز به توضیحات بیشتری دارید، خوشحال میشوم کمک کنم.