از آنجا که ما در شرکت تصمیم گرفتیم در تمام پروژه های پیش رو از میکروهای سری RISC-V مربوط به شرکت WCH استفاده کنیم. میکروکنترلر CH32X035C8T6 به علت صنعتی بودن ، امکانات و پریفرال های کاملی را دارا می باشد بر این اساس یک راهنمای جامع در مورد میکروکنترلر CH32X035C8T6 تهیه شده است.
در مورد مطالب این راهنما بدیهی است , از نقطه نظرات و پیشنهادات شما عزیزان در در این راستا خوشحال میشویم و اشکالات و کمی و کاستی و سوالات خود را در مورد این راهنما, با ما درمیان بگذارید.
CH32X035C8T6 محصول شرکت WCH (نانجینگ چین هنگ) و عضوی از خانواده CH32X035 است؛ یک میکروکنترلر صنعتی ۳۲ بیتی مبتنی بر هسته RISC-V که مهم ترین امتیاز آن، یکپارچگی کامل زیرساخت USB 2.0 فول اسپید و USB Power Delivery با PHY اختصاصی در کنار مجموعه آنالوگ داخلی (اپ امپ، کامپاراتور، ADC و TouchKey) و هسته کمکی پروتکل محور (PIOC) است. این ترکیب در رده قیمتی این چیپ تقریبا بی همتاست و آن را به گزینه ای جذاب برای شارژرهای PD، دستگاه های USB و بردهای حسگر صنعتی تبدیل کرده است.
شکل پکیج و بازه دمایی از پسوند نام چیپ قابل خواندن است: حرف «C» به معنای پکیج LQFP48 با ابعاد ۷×۷ میلی متر و گام ۰٫۵ میلی متر، عدد «8» کلاس ۶۴ کیلوبایتی فلش (۶۲KB قابل استفاده برای کاربر)، حرف «T» بدنه پلاستیکی LQFP و عدد «6» بازه دمایی صنعتی ۴۰− تا ۸۵+ درجه سانتی گراد است. بدین ترتیب چیپ بدون نیاز به قطعه جانبی پیچیده، مستقیما برای محیط های صنعتی تأیید دمایی دارد.
مشخصات کلیدی میکروکنترلر CH32X035C8T6خانواده X035 در چند پکیج عرضه میشود و همه اعضا از نظر هسته، حافظه و بسته نرمافزاری مشترک اند؛ تنها تعداد پایه های رسیده به پکیج و به تبع آن کانال های آنالوگ متفاوت است. جدول زیر مقایسه رسمی دیتاشیت است:
جدول ۱-۱ — مقایسه اعضای خانواده CH32X035 (بر اساس دیتاشیت V2.3)

همه اعضا ۶۲KB فلش، ۲۰KB، SRAM هسته ۴۸MHz، دو تایمر پیشرفته و پشتیبانی PIOC دارند. CH32X035C8T6 با ۴۶ پایه و پشتیبانی کامل Source/Sink/DRP، متعادل ترین عضو خانواده برای بردهای صنعتی است.
چرا این چیپ برای بردهای صنعتی جذاب است؟
وجود PHY داخلی برای USB و PD یعنی حذف تراشه های الکترونیکی خارجی پیچیده، کاهش BOM و افزایش قابلیت اطمینان؛ به همراه بازه تغذیه گسترده ۲ تا ۵٫۵ ولت که امکان کار مستقیم با شناورهای صنعتی ۵ ولت یا رگولاتورهای ۳٫۳ ولت را میدهد، و مجموعه آنالوگ داخلی که فیلتراسیون و خواندن سنسورها را بدون قطعه جانبی ممکن میکند.
معماری X035 حول هسته QingKe RISC-V4C شکل گرفته که مجموعه دستور RV32IMAC و دستورات توسعه یافته اختصاصی WCH را اجرا میکند. ضرب تک سیکلی و تقسیم سخت افزاری، پیش بینی انشعاب و کنترل کننده وقفه سریع PFIC با پشته وقفه سخت افزاری، پاسخ دهی بلادرنگ سیستم را تضمین میکنند. دیباگ از طریق رابط سریال دو سیمه SDI (پایه های PC18/PC19) انجام میشود که با پروگرامر WCH-Link کار میکند. شکل ۱ سلسله مراتب باس ها و پریفرال ها را به صورت خلاصه نشان میدهد.

نقشه حافظه و مشخصات فلش

عمر نوشتن فلش ۳۰۰ هزار سیکل در C°۲۵ و ۱۰۰ هزار سیکل در C°۷۰ با نگهداری داده ۲۰ سال است؛ برای ذخیره سازی مکرر پارامترها (شمارنده ها، لاگ خطا) باید بازی وارد و پخش شده (Wear-Levelling) نوشت — در بخش ۷ به این موضوع برمی گردیم. هر چیپ همچنین یک شناسه یکتا Unique) (ID دارد که برای سریال سازی برد و قفل گذاری نرمافزاری قابل استفاده است.
X035 هیچ نوسان ساز خارجی (HSE) ندارد؛ تنها منبع کلاک، اسیلاتور RC داخلی ۴۸MHz (HSI) است با دقت ±۱٫۱٪ در کل بازه دمایی صنعتی. کلاک USB مستقیما از HSI تولید میشود و کلاک کم مصرف ۴۷kHz (HSI/1024) برای IWDG و بیدارباش خودکار در دسترس است. این طراحی سه پیامد مهم دارد:
حذف کریستال و خازن های بار از BOM و حذف دغدغه شروع به کار نوسان ساز در دمای پایین؛ بادریت UART به دلیل تلورانس ±۱٫۱٪ برای سرعت های متداول (تا 115200 و بالاتر) کاملا مطمئن است؛ برای پروتکل های زمان سنجی بسیار حساس (مثلا برخی پروتکل های دقیق تک سیمه) باید از PIOC یا کالیبراسیون نرمافزاری کمک گرفت.
خروجی کلاک داخلی از پایه MCO (PB9) برای ساعت دهی به ICهای دیگر قابل استفاده است و زمان راه افتادن HSI فقط ۱٫۵ تا ۳٫۵ میکروثانیه است.
بازه مجاز VDD از ۲٫۰ تا ۵٫۵ ولت است و تراز منطقی همه پایه ها با VDD تعیین میشود؛ فقط هنگام استفاده از USB یا PD باید VDD در بازه ۳٫۰ تا ۵٫۳ ولت حفظ شود. رگولاتور داخلی هسته و مدارهای POR/PDR و مانیتور ولتاژ قابل برنامه PVD نیز روی چیپ موجود است.
جدول ۲-۲ — جریان مصرف در حالت های کاری (VDD=3.3V، مقادیر تیپی دیتاشیت)

نکته مهم صنعتی: پایه های بسته شده در پکیج ولی استفاده نشده و پایه های پریفرال غیرفعال باید طبق توصیه دیتاشیت به صورت ورودی Pull- up یا Pull-down پیکربندی شوند، وگرنه جریان مصرف از مقادیر جدول بالا بیشتر میشود.
کنترل کننده USBFS با PHY داخلی، استاندارد USB 2.0 Full-Speed (۱۲Mbps) را هم در نقش میزبان و هم دستگاه پشتیبانی میکند؛ در حالت دستگاه ۸ اندپوینت قابل پیکربندی و در حالت میزبان یک جفت اندپوینت فراهم است. انتقال Control/Bulk/Isochronous/Interrupt، بافر دوگانه، Suspend/Resume و پروتکل شارژ BC1.2 پشتیبانی میشود. پایههای PC17 = D+ و PC16 = D− مستقیما به کانکتور میروند و فرستنده افتراقی با کلاک ۴۸MHz داخلی کار میکند. برای بردهای صنعتی این یعنی امکان پیاده سازی CDC (پورت سریال مجازی)، DFU (آپدیت فریم ور)، HID و لاگ گیر USB بدون هیچ تراشه اضافه.
مثال زیر با کتابخانه استاندارد WCH، چیپ را به یک پورت سریال مجازی CDC تبدیل میکند (مبنای مثال SimulateCDC در EVT): داده ای که از پنجره ترمینال PC دریافت میشود به UART2 منتقل میشود و برعکس؛ همین قالب، پایه آپدیت کننده فریم ور (DFU) و لاگ گیری USB نیز هست.
مثال MounRiver Studio II — دستگاه USB-CDC با کتابخانه استاندارد (مبنای:EVT) SimulateCDC
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* CH32X035 - USBFS Device: virtual COM port (CDC) * MounRiver Studio II - based on EVT example "SimulateCDC" */ #include "debug.h" #include "ch32x035_usbfs_device.h" #include "UART.h" int main( void ) { NVIC_PriorityGroupConfig( NVIC_PriorityGroup_1 ); SystemCoreClockUpdate(); Delay_Init(); RCC_Configuration( ); /* clocks of USBFS & GPIO */ TIM3_Init( ); /* 1ms tick for timeouts */ UART2_Init( 1, DEF_UARTx_BAUDRATE, /* backend UART2 on PA2/PA3 */ DEF_UARTx_STOPBIT, DEF_UARTx_PARITY ); USBFS_RCC_Init( ); /* 48MHz clock for PHY */ USBFS_Device_Init( ENABLE , PWR_VDD_SupplyVoltage( ) ); while( 1 ) { UART2_DataRx_Deal( ); /* USB-CDC -> UART2 TX */ UART2_DataTx_Deal( ); /* UART2 RX -> USB-CDC */ } } |
بلوک USBPD با PHY اختصاصی شامل کدک BMC سخت افزاری، CRC و کنترل لبه های سیگنال است؛ یعنی کل لایه فیزیکی PD بدون دخالت نرمافزار حساس به زمان انجام میشود. پشتیبانی کامل PD 2.0 و PD، 3.0 تشخیص خودکار میزبان/منبع Type-C، حالت های،Source Sink و DRP و PDUSB فراهم است:
در نقش Source، مقاومت های Rp داخلی با سه سطح جریان Aμ۸۰/۱۸۰/۳۳۰ (مطابق مشخصه استاندارد Type-C) قابل انتخاب اند؛ در نقش Sink معمولا دو مقاومت Rd = 5.1k خارجی روی CC1/CC2 لازم است؛ با تراشه کمکی CH211 میتوان تحمل ۲۸ ولت روی،CC/VBUS Rd داخلی ۵٫۱k و کنترل MOSFET قدرت را اضافه کرد؛ پایه ها: PC14 = CC1 و PC15 = CC2 که باید کوتاه و بدون قطعه اضافه به کانکتور وصل شوند.
نکته سخت افزاری مهم
پیام های PD روی خط CC با مدولاسیون BMC و آمپلی تود ~۱٫۱ ولت جابه جا میشوند (زمان بالا/پایین سیگنال ۳۰۰ تا ۶۰۰ نانوثانیه). هر خازن یا فیلتر اضافه روی CC شکل موج را خراب میکند؛ مسیر CC باید مستقیم، کوتاه و فقط شامل مقاومت های Rd در نقش Sink باشد. در نقش Sink، کل لایه فیزیکی PD (کدک،BMC CRC و تشخیص قطع/وصل) توسط بلوک سخت افزاری USBPD انجام میشود و کتابخانه، موتور پیام PD را در قالب PD_Det_Proc و PD_Main_Proc ارائه میدهد؛ مثال رسمی USBPD_SNK در EVT همین ساختار را دارد:
مثال Sink — MounRiver Studio II بسته USB-PD (مبنای:EVT) USBPD_SNK
| 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 | /* CH32X035 - USBPD Sink: PD contract negotiation * MounRiver Studio II - based on EVT example "USBPD_SNK" */ #include "debug.h" #include "PD_Process.h" void PD_Init( void ) /* from EVT: PD_Process.c */ { GPIO_InitTypeDef GPIO_InitStructure = {0}; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE ); RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE ); RCC_AHBPeriphClockCmd( RCC_AHBPeriph_USBPD, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; /* CC1/CC2 */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init( GPIOC, &GPIO_InitStructure ); AFIO->CTLR |= USBPD_IN_HVT | USBPD_PHY_V33; /* PHY I/O level 3.3V */ USBPD->CONFIG = PD_DMA_EN; /* BMC codec engine */ USBPD->STATUS = BUF_ERR | IF_RX_BIT | IF_RX_BYTE | IF_RX_ACT | IF_RX_RESET | IF_TX_END; memset( &PD_Ctl.PD_State, 0x00, sizeof( PD_CONTROL ) ); PD_PHY_Reset( ); /* reset PD PHY */ PD_Rx_Mode( ); /* start RX */ } int main( void ) { NVIC_PriorityGroupConfig( NVIC_PriorityGroup_1 ); SystemCoreClockUpdate(); Delay_Init(); USART_Printf_Init( 921600 ); printf( "PD SNK TEST\r\n" ); PD_Init( ); TIM1_Init( 999, 48-1 ); /* 1ms time base */ while( 1 ) { PD_Ctl.Det_Timer += Tmr_Ms_Dlt; /* ms from TIM1 ISR */ if( PD_Ctl.Det_Timer > 4 ) { PD_Ctl.Det_Timer = 0; PD_Det_Proc( ); /* CC attach/detach */ } PD_Main_Proc( ); /* PD state machine */ } } |
PIOC یک هسته RISC ساده تک سیکلی جدا از CPU اصلی است که با ۲K کلمه ROM برنامه (قرض گرفته از ۴KB سربار ۴۹ SRAM)، ثبات SFR، شمارنده های PWM و پشته ۶ سطحی، دو پایه اختصاصی PIOC_IO0 (PC18) و PIOC_IO1 (PC19) را کنترل میکند. با بارگذاری پویاِ برنامه های پروتکل، انواع رابط های تک سیمه و دورسیمه (مانند پروتکل های اختصاصی سنسورها و ماژول های صنعتی) بدون تحمیل تراکم زمان بندی به CPU اصلی پیاده سازی میشوند. دو برنامه نمونه PIOC در بسته رسمی EVT موجود است.
از دید CPU اصلی، کار با PIOC سه گام دارد: تهیه بایت کد برنامه با ابزار PIOC شرکت WCH، بارگذاری آن در حافظه برنامه PIOC و فعال سازی هسته کمکی؛ سپس رخدادهای پروتکل از طریق وقفه اختصاصی PIOC دریافت میشود:
مثال MounRiver Studio II — بارگذاری برنامه PIOC و فعال سازی (مبنای:EVT) PIOC_NEC
| 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 | /* CH32X035 - PIOC: load program binary into the co-processor * MounRiver Studio II - based on EVT example "PIOC_NEC" */ #include "debug.h" #include "string.h" /* PIOC program (assembled by the WCH PIOC toolchain) */ __attribute__( ( aligned( 16 ) ) ) const unsigned char PIOC_CODE[] = { /* ... opcodes generated by the PIOC assembler ... */ }; void PIOC_INIT( void ) { GPIO_InitTypeDef GPIO_InitStructure = {0}; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE ); RCC_AHBPeriphClockCmd( RCC_AHBPeriph_IO2W, ENABLE ); /* PIOC_IO0 = PC18 , PIOC_IO1 = PC19 (SWJ must be disabled first) */ GPIO_PinRemapConfig( GPIO_Remap_SWJ_Disable, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_18 | GPIO_Pin_19; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init( GPIOC, &GPIO_InitStructure ); NVIC_EnableIRQ( PIOC_IRQn ); NVIC_SetPriority( PIOC_IRQn, 0xf0 ); memcpy( ( uint8_t * )( PIOC_SRAM_BASE ), PIOC_CODE, sizeof( PIOC_CODE ) ); R8_SYS_CFG |= RB_MST_RESET; /* reset PIOC */ R8_SYS_CFG = RB_MST_IO_EN0 | RB_MST_IO_EN1; /* enable IO0/1 */ R8_SYS_CFG |= RB_MST_CLK_GATE; /* start PIOC */ } void PIOC_IRQHandler( void ) __attribute__( ( interrupt( "WCH-Interrupt-fast" ) ) ); void PIOC_IRQHandler( void ) /* protocol events from PIOC */ { /* read PIOC status / data registers here ... */ } |
این مقاله تنها بخش اول از سلسله مباحث بررسی و راهاندازی ماژول میکروکنترلر WCH است. در قسمتهای بعدی این مجموعه، به سراغ مباحث پیشرفتهتری از جمله نحوه پیکربندی سایر پریفرالها، پیادهسازی پروژههای عملی با MounRiver Studio و نکات تکمیلی برنامهنویسی این تراشهها خواهیم رفت؛ پس با ما همراه باشید!
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.