قبلا در سیسوگ ماژول RC522 را در مقاله ای تحت عنوان “راهاندازی پروژه RFID RC522 با آردوینو” راهاندازی کردیم. اکنون در این مقاله قصد داریم به راهاندازی ماژول RC522 با STM32 بپردازیم. ابتدا در رابطه با خود RFID توضیحاتی خواهیم داد و در ادامه به راهاندازی آن با STM32 میپردازیم.
RFID (Radio Frequency Identification)
همانطور که از اسم RFID پیداست، میتواند با استفاده از فرکانسهای رادیویی عمل شناسایی را انجام دهد.
به طور ساده میتوان گفت که RFID با استفاده از امواج مغناطیس و بدون تماس مستقیم عمل شناسایی را انجام میدهد.
نحوهی عملکرد RFID
نحوهی عملکرد به این گونه است که وقتی کارت دارای UID در مجاورت ماژول RC522 قرار میگیرد، میدان مغناطیسی تولید شده توسط ماژول باعث فعال شدن تگ RFID میگردد. در ادامه تگ پیوسته اقدام به ارسال داده میکند و این دادهها توسط کارتخوانی که در قسمت ماژول است خوانده میشود.
شاید برای شما مفید باشد: هک تگ آسانسور و همه چیز راجع به هک کارت های Mifare
بررسی انواع تگهای RFID
تگهای RFID دارای انواع متفاوتی هستند و امکانات آنها تا حدودی متفاوت است، اما همگی آنها حداقل دارای یک تراشه و یک آنتن هستند.
بعضی از این تگها دارای حافظههایی نیز هستند که این حافظه میتواند فقط خواندنی و یا خواندنی/نوشتنی باشد.
در بعضی از این تگها باتری هم وجود دارد که کاربرد این باتری تامین توان لازم برای ارسال داده به کارتخوان میباشد که به این تگها، تگهای فعال گفته میشود و وجودهمین باتری باعث میشود که تگ بتواند با کارتخوانهای که قدرت کمتری دارند نیز ارتباط برقرار کند.
توجه شود که تگهای غیر فعال توان خود برای فعال شدن و ارسال داده را از کارتخوان دریافت میکنند.
ماژول RC522
ماژول کارتخوان با قابلیت خواندن و نوشتن RC522 به منظور خواندن کارتهای RFID مورد استفاده قرار میگیرد. همچنین این ماژول با فرکانس کاری 13.56 مگاهرتز قابلیت خواندن و نوشتن بر روی تگها را دارد.
این ماژول قابلیتهایی دارد که مختصرا به شرح زیر میباشند:
- پشتیبانی از پروتوکلهای I2C ,SPI و UART
- دارای یک بافر 64 بیتی
- ولتاژ کاری 2.5 تا 3.5 ولت DC
- جریان مصرفی 13 تا26 میلی آمپر
- دارای اسیلاتور خارجی 27.12 مگاهرتز
- قابلیت خواندن و نوشتن بدون تماس در فاصله 8 تا 10 سانتی متر
همانطور که در قابیلتهای این ماژول ذکر شد، از سه پروتکل برای انتقال دیتا پشتیبانی میکند. اما پروتکلی که ما قصد داریم از آن برای راهاندازی این ماژول استفاده کنیم، پروتکل SPI است. در ادامه به شرح این پروتکل میپردازیم.
پروتکل SPI
این پروتکل، یک پروتکل سریال میباشد که توسط شرکت موتورولا طراحی شده است و به صورت Master و Slave کار میکند، بدین صورت که فقط میتواند یک Master و چندین Slave داشته باشد.
در حالت تئوری تعداد Slaveها هیچ محدودیتی ندارد اما در عمل به دلیل یک سری نکات فنی تعداد Slaveها محدود است.
به تصویر زیر دقت کنید:
در حالت کلی پروتکل SPI شامل چهار سیم زیر میباشد:
- SCLK: Serial Clock (output from master)
- MOSI: Master Output Slave Input, or Master Out Slave In (data output from master)
- MISO: Master Input Slave Output, or Master In Slave Out (data output from slave)
- SS: Slave Select (often active low, output from master)
توضیحات بالا به خوبی عملکرد هر پایه را نشان میدهد و نیازی به توضیحات اضافی نیست. پس همانطور که گفتیم در این پروتکل چهار سیم وجود دارد اما این تا زمانی است که تنها یک Master و یک Slave داشته باشیم. به ازای اضافه شدن هر Slave یک سیم SS دیگر به Master اضافه میشود.
در واقع هر سیم SS برای انتخاب یکی از Slaveها به کار میرود.
در پروژه موردنظر ما چون یک Slave داریم پس Master هم همان چهار سیم را دارد.
در پروتکل SPI چهار مد عملیاتی مختلف وجود دارد که این چهار مد عملیاتی به وسیلهی دو پارامتر CPOL و CPHA تعیین میشوند. ابتدا به تصاویر زیر دقت کنید تا پس از آن این مدهای عملیاتی را توضیح بدهیم.
با توجه به تصاویر بالا پارامتر CPOL مشخص میکند که حالت اولیه کلاک صفر منطقی است یا یک منطقی. اگر صفر منطقی باشد پس اولین لبهی کلاک، لبهی بالارونده خواهد بود و اگر حالت اولیه کلاک یک منطقی باشد پس اولین لبهی کلاک، لبهی پایین رونده خواهد بود.
همچنین پارامتر CPHA مشخص میکند که دیتا در اولین یا دومین لبهی کلاک نمونهبرداری شود. اینکه پارامتر CPOL چه باشد اولین لبه میتواند لبهی بالارونده یا پایینرونده باشد، دومین لبه نیز به همین صورت میتواند بالا رونده باشد یا پایین رونده.
با توضیحات بالا چهار مد عملیاتی متفاوت میتواند وجود داشته باشد که ما در این پروژه از مد صفر استفاده میکنیم. یعنی کلاک در حالت بیکاری یا همان حالت اولیه صفر منطقی است و نمونهبرداری در لبهی اول که همان لبهی بالارونده صورت میگیرد.
راهاندازی ماژول RC522 با STM32
اکنون میخواهیم که این ماژول را با استفاده از برد Bluepill که میکروکنترلر آن STM32F1 میباشد راهاندازی کنیم.
نحوهی کار به این صورت است که ما ID تگ RFID را با استفاده از پروتکل SPI میخوانیم و پس از اینکه دیتای تگ ثبت شد آن را با استفاده از پروتکل UART بر روی پورت سریال ارسال خواهیم کرد و ID کارت را در کامپیوتر مشاهده خواهیم کرد.
ماژول را طبق اتصالات زیر به SPI1 برد Bluepill وصل خواهیم کرد.
RC522 | Bluepill |
SDA | PA4 |
SCK | PA5 |
MOSI | PA7 |
MISO | PA6 |
IRQ | unconnected |
GND | GND |
RST | 3.3V |
3.3V | 3.3V |
همچنین یک مبدل USB به سریال به UART1 برد Bluepill وصل خواهیم کرد تا دادهها را مانند شکل زیر در کامپیوتر مشاهده کنیم. پایه RX ماژول به A9 (TX USART1) متصل می شود. همچنین بهتر است پایه ریست RC522 را هم به پایه ریست بلوپیل متصل کنید تا وقتی که به وسیله دکمه بلوپیل را ریست می کنیم، ماژول هم ریست شود.
توضیحاتی در رابطه با کتابخانه و main برنامه
ابتدا دیتاشیت ماژول را میخوانیم و با توجه به رجیسترها، مد کاری، نحوهی انتقال دیتا، پروتکلی که دیتا با آن انتقال پیدا میکند و … یک کتابخانه برای ماژول درست میکنیم.
در پروژه، ما تنها یک کتابخانه نوشته شده توسط کاربر به اسم rc522 داریم. در فایل rc522.h یک سری ثوابت، رجیسترها و همچنین اسم توابع را تعریف کردیم. در فایل rc522.c هم نحوهی انتقال دیتا و کار با ماژول با استفاده از توابع توصیف شده است.
در فایل rc522.c حدود بیست تابع برای کارهای مختلف با ماژول موجود میباشد که ما به توضیح تک تک این توابع نخواهیم پرداخت و در ادامه فقط مختصرا توابعی که در main برنامه استفاده کردیم را بررسی میکنیم.
البته با توجه به اسم هر تابع و بررسی کد آن شما به سادگی میتوانید متوجه عملکرد و کارایی تابع شوید.
مثلا ما هنگام توسعه برنامه از تابع MFRC522_ReadRegister استفاده کردیم و همانطور که از اسمش مشخص است مقدار یک رجیستر را به ما برمیگرداند. ما با استفاده از این تابع مقدار رجیستر مربوط به ورژن RFID را خواندیم و با مقداری که در دیتا شیت داریم چک کردیم تا ببینیم ارتباط به درستی صورت گرفته است یا خیر.
البته چون ابتدا ولتاژ 3.3 ولت روی برد قطع بود، به نظر میرسید که کتابخانه نوشته شده به درستی کار نمیکند و عملیات انتقال دیتا با استفاده از پروتکل SPI به درستی صورت نمیگیرد. که پس از چک کردن ولتاژ 3.3 ولت و برقرار کردن آن کشف شد که کتابخانه به درستی با ماژول ارتباط برقرار میکند و مشکل از تغذیه است.
همچنین توجه شود که ما در کتابخانه rc522 برای پروتکل SPI و UART از توابع HAL استفاده کردیم.
ابتدا به main برنامه توجه کنید تا در ادامه توضیحاتی را بیان کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | int main(void) { const char intorstr[] = "STM32F103 Mifare RC522 RFID Card reader 13.56 MHz\r\n"; /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); MX_SPI1_Init(); /* USER CODE BEGIN 2 */ MFRC522_Init(); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); HAL_Delay(100); HAL_UART_Transmit(&huart1, (uint8_t*)intorstr,strlen(intorstr), 500); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if (!MFRC522_Request(PICC_REQIDL, CardID)) { if (!MFRC522_Anticoll(CardID)) { if(memcmp(CardID,LastCardID,4)) { memcpy(LastCardID,CardID,4); char ID_Str[20] = {0}; sprintf(ID_Str,"Card ID: %X\r\n",*((uint32_t*)CardID)); HAL_UART_Transmit(&huart1, ID_Str, strlen(ID_Str), 500); } } } else { t++; if (t > 4 ) { memset(LastCardID,0,4); t = 0; } } HAL_Delay(200); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } |
ابتدا کلاک سیستم، ورودی-خروجی، پروتکل UART و پروتکل SPI را انشیالایز میکنیم.
همانطور که میدانید زمانی که قرار است با پروتکل SPI ارتباط برقرار کنیم باید ابتدا پایه CS را صفر کنیم و زمانی که دیتا منتقل شد و کاری نداشتیم دوباره این پایه را به مقدار یک منطقی برگردانیم.
چون CS به پایه PA4 متصل است ما PA4 را صفر و یک میکنیم.
ابتدا PA4 را در main برنامه در حالت یک قرار میدهیم تا زمانی که بخواهیم در while دیتا را از SPI انتقال بدهیم آن را صفر میکنیم.
پس از ایجاد کمی تاخیر یک پیام بر روی پورت سریال برای راهنمای کاربر میفرستیم و ادامه برنامه در while قرار دارد.
کل برنامهی نوشته شده در while به شرح زیر است:
در ابتدای while توسط دستورات شرطی بررسی میشود که کارتی تشخیص داده شده است یا خیر، اگر تشخیص داده شد، ID آن را بر روی پورت سریال بفرستد. تواما بررسی میشود تا مادامی که همان کارت در مجاورت ماژول قرار دارد مقدار ID همان باشد و چیز دیگری روی پورت سریال فرستاده نشود مگر اینکه کارت را کلا برداریم و دوباره بزنیم تا همان ID برای بار دوم روی پورت سریال فرستاده شود.
همچنین در این برنامه اشکال اینکه اگر کارت در فاصلهای از ماژول قرار بگیرد که در لحظهای بسیار کوتاه خوانده شود و سپس خوانده نشود و به همین ترتیب ادامه پیدا کند، برطرف شده است.
سورس برنامه را میتوانید از طریق لینک زیر دانلود کنید:
دوست عزیز کد کار نمیکنه
سلام
کد الان مجددا بررسی شد و تست شد و بدون مشکل کار کرد.
سلام
میشه راه اندازی این ماژول با پروتکل i2c هم توضیح بدید؟
سلام وقتتون بخیر،
کد برای بنده کار نکرد، مقدار MFRC522_Request برابر با 2 یا همان MI_ERR است. از اتصالات و صحت ماژول نیز به طور کامل اطمینان دارم
کد برنامه مشکل داشت – اصلاح شد و تست شد
آیا بعد آن اصلاح هم تست کردید ؟
درود بر شما، خیر،
از کتابخانه دیگری استفاده کردم مشکل برطرف شد
خوشحالم که مشکلتون حل شده
به هر حال این مثال رو من خودم تست کردم به مشکل بود توی کد مین که حل کردم
سبلام از چه کتابخانه ای استفاده کردید
آقا من با یه ماژول دیگه هم امتحان کردم اکی نشد نمیدونین مشکلش چیه؟
فقط همون عبارت سریال که اول میفرستیم ارسال میشه. ودیگه کارت رو نمیخونه و ماژول هیچ عملکردی نداره…؟؟؟!!!!
آقا کد رو بررسی کردم یه مشکلی که داشت این بود که تابع اینیت ماژول رو کال نکرده بود که مقداری عجیب هم بود
کد رو اصلاح کردم و برای دانلود قرار دادم –
دوباره دانلود کنید و تست کنید احتمالا اوکی شده باشه
فقط بعد ریست این عبارت STM32F103 Mifare RC522 RFID Card reader 13.56 MHz که دارین ارسال میکنید میاد اما زمانی که کارتو میگیریم هیچی نمیاد؟؟
ریست ماژول رو به ریست میکرو وصل کنید که هم زمان با هم ریست بشن و کد جدید رو دانلود کنید و تست کنید
سلام براچی کار نمیکنه؟؟؟؟؟؟؟
جالبه اجازه بدید من خودم فردا مدارش رو بیندم ببینم کد مشکل داره کتابخانه یا مدار
بهتون اطلاع میدم
ممنون میشم چون کارم یکم گیره
درست کردم کد رو دوست عزیز
تست کنید و نتیجه رو بگید 🙂
سلام خسته نباشید. من با یه ماژول دیگه هم امتحان کردم اکی نشد؟؟؟. نمیدونین مشکلش چیه؟؟…
کد مشکل داشت متاسفانه بررسی کردم و مشکل رو حل کردم
دوباره دانلود کنید و تست کنید – من تست کردم اوکی شد و کار میکرد
سلام توی تابع MFRC522_WriteRegister چرا ادرس رو شیفت دادین؟ منظورم addr = (addr << 1) & 0x7E; هست
علت اینکه با 0x7e اند شده متوجه شدم(ولی مو دیتاشیت پیدا نکردم) ولی علت شیفت ادرسو نفهمیدم
سلام ، ممنون از زحماتتون ، من این برنامه رو اپلود کردم ولی جواب نداد که؟ من اومدم پایه های سریال رو به ماژول بلوتوث دادم و با گوشیم چکش میکردم ، برنامه که استارت میشه اون نوشته ی stm32f103 …. رو میفرسته رو گوشیم ، ولی کارت رو که نزدیک میکنم هیچی نمیاد ، اصلا انگار نه انگار ، ماژول ۵۲۲ هم چراغش روشنه و نو هم هست ، کانکتور ها و سیم ها رو هم چک کردم ، درست وصلن ، پایه ریست رو هم به زمین وصل کردم ، هم وی سی سی هم ازاد گزاشتم اما تو هیچ کدوم از اونا ماژول هیچی نفرستاد ، میشه یه راهنمایی برای دیباگ کردن برنامه یا ماژول بهم بدین؟ خب از کجا بفهمم ماژول سالمه یا نه ، حتما باید یه ماژول دیگه هم بخرم؟
عجیبه یه مقدار چون برنامه رو چک کردیم قبلا
پایه ریست ماژول و به ریست میکرو وصل کنید و برد رو ریست کنید ببینید آیا مشکل حل میشه ؟
ممنون ، نتونستم راه اندازیش کنم متاسفانه ، دیگه با اردینو راهش انداختم ، ولی بازم ممنون
ببخشید که دیر جواب دادم و البته خوشحالم که مشکل رو به نحوی حل کردید 🙂
سلام ببخشید طبق عکس بالا شما rst رو به پایه میکرو متصل کردید ولی نوشتید 3.3v ببخشید نحوه اتصال درسته اخه کد ج نمیده ممنون میشم راهنمایی کنید
درود بر محمد عزیز. شما طبق جدول ریست رو به 3.3V متصل کنید، سپس امتحان کنید.
سلام جناب مهندس بله درسته مشکل از برد بود با تشکر از اموزش بسیار خوبتون
دوست عزیز خوشحالم که این مقاله برایتان مفید بوده است. موفق باشید.
سلام چطوری مشکلتون حل شد؟
سلام خسته نباشید
این پروژه برای ماژول های 125khz هم جواب میده ؟؟؟؟
سلام حسین عزیز. خیر، این پروژه برای کار شما مناسب نیست.
مقالهی زیر احتمالا به کمکتان بیایید:
https://sisoog.com/2020/05/%D9%BE%D8%B1%D9%88%DA%98%D9%87-%D8%B1%D8%A7%DB%8C%DA%AF%D8%A7%D9%86-%DA%A9%D9%86%D8%AA%D8%B1%D9%84-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D9%87%D9%88%D8%B4%D9%85%D9%86%D8%AF-%D9%85%D8%AC%D9%87%D8%B2/
کد شما جواب نداد ولی کتابخانه اش جواب داد یه کده دیگه نوشتم
آره تا جایی که یادمه تو کتابخونش توابع زیادی وجود داشت. بسیار عالی.
سلام مشکلش کجا بود ؟ این جواب نمیده که
سلام با چه نرم افزاری باید باز کرد این پروژه رو ؟
فکر میکنم keil
با نرمافزار Keil و STM32CubeMX
سلام
با تشکر از مطالب خوب شما.
پیشنهاد من این بود که خوب بود در مورد خوندن سکتور ها میزاشتین، اینا که اسونه تقریبا.
درود. فعلا فقط همین آسونش برآورده شده ???
سلام برای دانلود سورس یوزر و پسورد لازمه !
سلام دوست عزیز. مشکل برطرف شد، هماکنون میتوانید دانلود کنید.
سلام خسته نباشید . سورس برنامه قابل دانلود نیست . در صورت امکان بررسی بشه.ممنونم.
سلام دوست عزیز. مشکل برطرف شد، هماکنون میتوانید دانلود کنید.
خیلی ممنون ، محبت کردین.
خواهش میکنم.