آشنایی و راه‌اندازی پروتکل CAN با استفاده از STM32

0
215
پروتکل CAN با استفاده از STM32
پروتکل CAN با استفاده از STM32

برای برقراری ارتباط پروتکل‌های زیادی وجود دارند؛ پروتکل‌هایی که برای ارتباط نزدیک طراحی و پایه‌ریزی شده‌اند، پروتکل‌هایی که برای ارتباط راه‌دور (پروتکل CAN) مورد‌استفاده قرار می‌گیرند و حتی پروتکل‌هایی که مخصوص روی برد هستند. یکی‌از مهم‌ترین نیاز‌های هر ارتباطی، اطمینان‌از صحت داده‌های دریافتی است. قبلاً درخصوص خطایابی و ترمیم‌داده بااستفاده‌از همینگ کد توضیح داده‌ایم. چالش بعدی سرعت انتقال داده است. باتوجه‌به نرم‌افزاری بودن سیستم خطایابی در بیشتر پروتکل‌های ارتباطی، سرعت، رابطه‌ای مستقیم با فرکانس پردازنده خواهدداشت. حال فرض‌کنید پروتکلی موجود باشد که خطایابی را به‌صورت سخت‌افزاری انجام دهد و نیازی به درگیری پردازنده نباشد. با این تکنیک می‌توان به سرعت‌های بالاتری دست پیدا کرد. پروتکل‌هایی مثل شبکه و یا CAN دارای چنین قابلیت‌هایی هستند. چیزی که استفاده‌از این پروتکل‌ها را محدود کرده‌است، در وهله‌ی اول، پیچیدگی‌های سخت‌افزاری و نیاز به قطعات جانبی مورد‌نیاز و بعد‌از‌آن پیچیدگی ظاهری پروتکل است.

در این مقاله قصد داریم به بررسی پروتکل ارتباطی CAN بپردازیم و مختصری از نحوه‌ی کانفیگ اولیه آن را به زبان ساده بیان کنیم. با ما همراه باشید.

پروتکل CAN چیست و از کجا آمده است؟

شاید باور این‌که، این پروتکل ابتدا برای خودرو پایه‌ریزی شد، مقداری سخت باشد. خب البته باید دید که چه خودروهایی از این پروتکل استفاده می‌کرده‌اند؛ قطعاً ماشین‌هایی با استاندارد‌های الکترونیکی بالا! نه خودروهایی مثل تولیدات داخلی! در سال ۱۹۸۰ شرکت Bosch باهدف کاهش سیم‌کشی‌های انبوه موجود در خودروها، دست‌به ابداع پروتکل محبوب CAN زد. محبوبیت و مقبولیت پروتکل ابداعی تا جایی پیش‌رفت که علاوه‌بر استفاده موفق از آن در صنعت خودرو، در دیگر صنایع نیز مورد‌استفاده قرار گرفت. پروتکل CAN علاوه‌بر تأمین ایمنی در سطح شبکه، نیاز به سخت‌افزار پیچیده‌ای برای برقراری ارتباط ندارد و از روش آشنای دو رشته سیم به‌هم‌تابیده و خطوط دیفرانسیلی استفاده می‌کند. امنیت در پروتکل CAN تا اندازه‌ای است که علاوه‌بر استفاده در خودرو، در هواپیماها نیز مورد‌استفاده قرار می‌گیرد و سنسور‌های سیستم ناوبری هواپیما برای برقراری ارتباط با کامپیوتر مرکزی از این پروتکل استفاده می‌کنند.

چرا باید از CAN استفاده کنیم؟

پروتکل CAN
پروتکل CAN

 

دلایل زیادی وجود دارد که استفاده‌از پروتکل CAN رو توجیه می‌کند، ولی مهم‌ترین دلایلی که در پروژه‌هایی با سطح صنعتی، باید از CAN استفاده کنیم به شرح زیر هستند:

  • اگر در شبکه CAN یکی‌از Node ها کرش یا هنگ کند، به‌صورت اتوماتیک توسط لایه‌ی فیزیکی از شبکه خارج می‌شود و شبکه به کار خود ادامه می‌دهد.
  • عدم نیاز به عناصر خارجی زیاد و سادگی مدار راه‌انداز: تنها به یک واسط لایه‌ی فیزیکی نیاز دارد که معمولاً یک آی سی ۸ پایه است.
  • پروتکل CAN باتوجه‌به لایه‌ی فیزیکی مورد‌استفاده (خطوط داده دیفرانسیلی) قادر است در محیط‌هایی با نویز زیاد مثل محیط‌های صنعتی کار کنند.
  • پروتکل CAN از لایه‌بندی مدل استاندارد OSI استفاده می‌کند.
  • تأمین امنیت داده‌های ارسالی با استفاده از CRC در لایه‌ی سخت‌افزاری
  • اولویت‌بندی پیام‌های ارسالی به‌نحوی‌که داده‌هایی با اولویت بالاتر زودتر ارسال می‌شوند.
  • شبکه‌ی CAN یک شبکه Real Time است؛ یعنی ارسال و دریافت داده‌ها را در بازه‌های زمانی مشخص، گارانتی می‌کند.

و البته موارد دیگر که شمردن آن‌ها در این مقاله ممکن نیست. برای روشن‌شدن اهمیت استفاده‌از پروتکل CAN، دومورد از قابلیت‌های ذاتی این پروتکل را بیشتر توضیح می‌دهیم:

مورد مهم اول، خارج شدن Node های مشکل‌دار از شبکه به‌صورت خودکار است؛ فرض‌کنید ماشینی که از مدل شبکه CAN استفاده می‌کند، در اتوبان با سرعت بالایی درحال حرکت است. ماشین دیگری از مسیر خود خارج‌شده و با آن تصادف می‌کند. بر اثر ضربه‌ی وارده، سیستم قفل مرکزی آسیب می‌بیند. آسیب وارده باعث نمی‌شود که سیستم کیسه‌ی هوا نیز با اختلال مواجه‌شود و کار نکند؛ بافرض این‌که هر دو سیستم از باس مشترک CAN استفاده می‌کنند.

مورد دوم، اولویت‌بندی پیام و Real Time بودن شبکه است. همان تصادف را فرض کنید؛ سیستم موتور قصد دارد پیامی را به سیستم سوخت‌رسانی ارسال کند تا باعث قطع سوخت‌رسانی و جلوگیری از آتش‌سوزی شود. ازطرفی سنسور ضربه قصد دارد به سیستم کیسه هوا وقوع تصادف را گزارش دهد. Real Time بودن شبکه CAN کمک می‌کند که پیام‌های مورد‌نظر در زمان‌های تعیین‌شده به مقصد برسند و از وقوع فاجعه جلوگیری کنند. درضمن پیام وقوع تصادف، مهم‌تر از دستور خاموش‌شدن موتور است. پروتکل CAN این قابلیت را دارد که پیام وقوع تصادف را زودتر منتشر کند تا سیستم‌های مربوطه اقدامات لازم را انجام‌دهند. همین مثال و قابلیت‌ها را می‌توان به‌راحتی برای کنترل یک کارخانه یا خط تولید گسترش داد.وجود چنین قابلیت‌هایی باعث می‌شود که پروتکل CAN امروزه بخش جدایی‌ناپذیر صنعت باشد. شاید تنها مشکل این پروتکل حجم محدود اطلاعات باشد.

فریم‌های ارسالی در پروتکل CAN به چه صورت هستند‌؟

برای این‌که شبکه CAN قادر باشد که به‌صورت Real Time عمل کند و داده‌ها در زمان مناسبی ارسال‌شوند، محدودیت‌هایی جهت ارسال بسته‌های (فریم‌های) داده‌ای وجوددارد؛ به‌این‌صورت که هر بسته داده‌ای نمی‌تواند بیشتر از ۸ بایت اطلاعات را حمل کند. قبل از این‌که به تشریح فریم‌های داده‌ای بپردازیم, لازم‌به‌ذکر است که دو ورژن مختلف از استاندارد CAN امروزه رایج هستند:

  • استاندارد CAN 2.0A
  • استاندارد CAN 2.0B

تفاوت این دو استاندارد در تعداد بیت‌های آدرس‌دهی (identifier) است؛ به‌صورتی که در استاندارد CAN 2.0A تعداد بیت‌های مجاز برای آدرس ۱۱ بیت هستند و در استاندارد CAN 2.0B تعداد بیت مجاز به ۲۹ بیت گسترش یافته‌اند.خوشبختانه تغییرات این دو استاندارد به‌نحوی بوده که هردو استاندارد قادرند به تبادل دیتا برروی یک خط داده مشغول باشند، بدون این‌که اختلالی به‌وجود آید.

آدرس در داده‌ها
آدرس در داده‌ها

 

همان‌طور که در تصویرفوق مشاهده می‌کنید، هر بسته‌ی داده‌ای دارای یک آدرس منحصر‌به‌فرد است که بسته‌به نوع استاندارد CAN مورد‌استفاده، می‌تواند ۱۱ یا ۲۹ بیت طول داشته‌باشد. تعداد داده‌های موجود در هر فریم توسط DLC مشخص می‌شود که در بیشترین حالت می‌تواند ۸ بایت داده باشد. بخش بعد CRC است که توسط سخت‌افزار تولید و بررسی می‌شود. درصورت صحت آدرس و CRC، گیرنده با ارسال ACK فرستنده را از دریافت اطلاعات آگاه می‌کند.

چطور اولویت یک پیام مشخص می‌شود؟

اما چطور می‌شود که پیام‌ها را اولویت‌بندی کرد؟ چطور می‌شود که اولویت یک پیام از دیگری بالاتر باشد؟ این اتفاق در لایه‌ی فیزیکی رقم می‌خورد. به‌این‌صورت که فریم‌های داده‌ای با آدرس (identifier) کوچک‌تر، دارای اولویت بالاتری برای ارسال هستند. بالاترین اولویت برای ارسال، مربوط به identifier با ارزش صفر است و پایین‌ترین اولویت هم مربوط به identifier با ۲۰۴۷ در استاندارد Can که ۲A است.

اولویت‌بندی در لایه‌ها
اولویت‌بندی در لایه‌ها

 

برای روشن‌شدن مسئله، به عکس فوق دقت‌کنید. فرض‌کنید سه Node قصددارند به‌صورت همزمان داده ارسال‌کنند. لایه‌ی فیزیکی اگر بیت مورد‌نظر را برروی خط مشاهده‌نکند، باس را آزاد می‌کند؛ به‌این‌شکل که مثلاً وقتی Node 2 قصد ارسال بیت ۵ ام را دارد، مشاهده می‌کند که بر‌خلاف مقدار بیت ۵ ام که باید مقدار باس ۱ باشد، صفر شده‌است و این بدان معناست که فرستنده‌ای با اولویت بالاتر، در حال ارسال داده‌است. پس دسترسی را واگذار می‌کند. فرستنده Node 1 همین وضعیت را در ارسال بیت دوم مشاهده می‌کند و این‌گونه می‌شود که Node 3 باس را در اختیار می‌گیرد و به ارسال داده می‌پردازد.

سیم‌کشی شبکه‌ی CAN به چه صورت است؟

سیم‌کشی شبکه‌ی CAN
سیم‌کشی شبکه‌ی CAN

 

همان‌طور که قبلا توضیح دادیم، پروتکل CAN از باس دیفرانسیلی استفاده می‌کند؛ مثل باس RS-485. به‌همین‌دلیل نمی‌توان و نباید از مدل ستاره‌ای برای این شبکه استفاده کرد (معمولاً افراد به این مسئله‌ی مهم توجه نمی‌کنند و همین امر باعث می‌شود که عملکرد سیستم با اختلال همراه باشد)، مگر در حالت خاص و با درنظرگرفتن شرایط و محاسبه‌ی امپدانس مورد‌نیاز به‌شکلی که امپدانس خط بر روی ۶۰ اهم باشد. در حالت خطی که در تصویر فوق مشاهده می‌کنید، باید یک مقاومت به ابتدا و یکی هم به انتها اضافه شود. مقدار توصیه‌شده برای این مقاومت‌ها مقدار ۱۲۰ اهم است.

باس دیفرانسیلی در CAN
باس دیفرانسیلی در CAN

 

همان‌طورکه در تصویر بالا می‌بینید، باس دیفرانسیلی مورد‌استفاده در CAN طبق استاندارد ISO 11898-2، باید با رفرنس ۲.۵ ولت باشد. مقدار رفرنس در آی‌سی لایه‌ی فیزیکی قابل‌تعیین است که به‌صورت پیش‌فرض مقدار ۲.۵ برای آن درنظر گرفته شده‌است. تعیین سرعت مورد‌استفاده یکی‌از پارامتر‌های مهم در شبکه CAN است. با‌توجه‌به طول باس، باید از سرعت مناسب استفاده‌کرد. در بیشترین حالت، طبق استاندارد می‌توان تا ۵۰۰ متر باس CAN طول داشته‌باشد و بیشترین سرعت قابل پشتیبانی در ISO 11898-2، ۱مگابیت بر ثانیه است. اما محدودیت‌هایی وجود دارد که باید آن‌ها را رعایت‌کرد؛ مثلاً نمی‌توان انتظارداشت در خطوط دیتا با طول ۲۰۰متر بتوان داده‌ها را با سرعت ۱مگابیت‌برثانیه منتقل‌کرد. برای سهولت ما چهار مقدار از تناسب طول خطوط داده و بیت ریت را آماده کرده‌ایم که به شرح‌زیر هستند:

  • سرعت ۱ مگابیت بر ثانیه برای خطوط داده با حداکثر طول ۴۰ متر
  • سرعت ۵۰۰ کیلوبیت بر ثانیه برای خطوط داده با حداکثر طول ۱۰۰ متر
  • سرعت ۲۵۰ کیلوبیت بر ثانیه برای خطوط داده با حداکثر طول ۲۰۰ متر
  • سرعت ۱۲۵ کیلوبیت بر ثانیه برای خطوط داده با حداکثر طول ۵۰۰ متر

سخت‌افزار لایه‌ی فیزیکی

شماتیک
شماتیک

 

معمولاً به‌دلیل آسیب‌پذیری لایه‌ی فیزیکی باتوجه‌به نوع عملکرد آن، این قسمت را در چیپ میکروکنترلر قرار نمی‌دهند تا درصورت بروز حادثه در باس، که موجب سوختن این آی‌سی واسط می‌شود، به میکروکترلر یا کنترلر CAN صدمه وارد نشود. آی‌سی‌های مختلفی توسط شرکت‌های مختلف برای واسط شبکه‌ی CAN ساخته شده‌اند ولی در دسترس‌ترین و مناسب‌ترین آن‌ها، آی‌سی MCP2551 ساخت شرکت میکروچیپ است. در نگاه اول، افرادی که قصد راه‌اندازی باس CAN توسط میکرو‌کنترلر‌های ARM را دارند، به‌دلیل وجود تغذیه‌ی ۵ ولت این آی‌سی، از آن استفاده نمی‌کنند. معادل این آی‌سی با تغذیه‌ی ۳.۳ ولت، هم کمیاب است و هم قیمتی تا ۴ برابر این این آی سی دارد. در‌صورتی‌که به‌راحتی و بدون هیچ مدار اضافه‌ای می‌توان این آی سی را به میکروکنترلر ARM متصل کرد (در‌صورتی‌که میکروکنترلر از ۳.۳ استفاده کند). فقط دقت داشته باشید که پایه‌ی ۸ را حتماً به زمین متصل‌کنید. اگر بتوانید یک خازن ۱۰۰ نانوفاراد هم بر روی پایه ۵ و زمین قرار دهید که بهتر خواهدبود. پایه‌ی ۵ در واقع همان ولتاژ رفرنس ۲.۵ ولت است که برای تشخیص سطح منطقی باس به‌کار می‌رود.

نرم‌افزار و راه‌اندازی اولیه

معمولاً اکثر میکروکنترلرهای آرم به‌صورت سخت‌افزاری از CAN پشتیبانی می‌کنند. اگرهم قصد دارید از CAN استفاده‌کنید و سخت‌افزار آن در میکروکنترلر مورد‌نظر شما وجودندارد، به‌راحتی می‌توانید از آی‌سی MCP2515 استفاده‌کنید. این آی‌سی یک مبدل SPI به CAN است. ما در این مقاله از میکروکنترلر STM32F103 استفاده می‌کنیم که واسط CAN را به‌صورت سخت‌افزاری درون خود میکروکنترلر دارد.

static void CAN_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;

/* CAN GPIOs configuration **************************************************/

/* Enable GPIO clock */
RCC_AHBPeriphClockCmd(CAN_GPIO_CLK, ENABLE);

/* Connect CAN pins to AF7 */
GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);
GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT); 

/* Configure CAN RX and TX pins */
GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(CAN_GPIO_PORT, &GPIO_InitStructure);

/* NVIC configuration *******************************************************/
NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* CAN configuration ********************************************************/ 
/* Enable CAN clock */
RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

/* CAN register init */
CAN_DeInit(CANx);
CAN_StructInit(&CAN_InitStructure);

/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;


/* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 2;
CAN_Init(CANx, &CAN_InitStructure);

/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);


/* Enable FIFO 0 message pending Interrupt */
CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
}

 

همان‌طور که مثال فوق مشاهده می‌کنید، می‌توان تنظیمات اولیه مربوط به CANx (بسته به نوع نیاز می‌تواند CAN1 یا CAN2 باشد) را به‌راحتی انجام داد. بعداز انجام تنظیمات اولیه، به‌سادگی و با نوشتن خطوط زیر می‌توان داده‌های مورد‌نظر را از بستر CAN منتقل کرد.

 CanTxMsg TxMessage = {0};
/* Transmit Structure preparation */
TxMessage.StdId = 0x321;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 1;
TxMessage.Data[0] = TestData;
CAN_Transmit(CANx, &TxMessage);

 

همان‌طور که مشاهده می‌کنید، ما یک فریم داده که شامل ۱ بایت داده‌است را با مشخصه‌ی 0x321 و با فرمت استاندارد (۱۱ بیت) در شبکه CAN منتشر می‌کنیم. اگر گیرنده وجود نداشته‌‌باشد یا مستر ACK را دریافت‌نکند، به‌صورت سخت‌افزاری ارسال تا تعداد دفعات مشخصی تکرار می‌شود.

در آینده

تااینجا با کلیت پروتکل CAN آشنا شدیم و چند خط از نحوه‌ی کانفیگ نرم‌افزاری آن‌را برای میکروکنترلر‌های STM32F103 قراردادیم. برای یافتن مثال‌های بیشتر می‌توانید به مثال‌های منتشر‌شده ازسوی شرکت ST مراجعه‌کنید. اما چیزی‌که متأسفانه به‌درستی به آن پرداخته نشده، نحوه‌ی کانفیگ نرخ ارسال داده‌است.

 /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 2;

 

در این مثال و دیگر مثال‌ها و برنامه‌ها، نرخ ارسال اطلاعات به‌صورت ثابت در برنامه قرار گرفته‌است و درمورد چگونگی محاسبه‌ی آن هیچ توضیحی ارائه نشده‌است. در مقاله‌ی آینده به توضیح این مهم خواهیم‌پرداخت و خواهیم‌گفت که چطور می‌شود با‌استفاده‌از پارامتر‌های مورد‌نظر، مقادیر مناسبی برای ایجاد نرخ ارسال اطلاعات انتخاب‌کنید.

 

 

 

منبع: سیسوگ

برای این مقاله نظر بگذارید:

لطفا دیدگاه خود را بنویسید
لطفا نام خود را وارد کنید