1-1پیشآگاهی
نرمافزار STM32CubeMX
این نرمافزار بهعنوان تولید کد در ایجاد پروژه استفاده میشود. بدینصورت
که تمام کانفیگ های سختافزاری و رجیستری میکروکنترلر موردنظر در یک محیط کاملاً
گرافیکی صورت میگیرد و در انتها با توجه به کانفیگ های صورت گرفته این نرمافزار
پروژهی موردنظر که در محیط توسعهی یکپارچه
برنامهنویسی اجرا میشود را تولید میکند.
نرمافزار IAR-EWARM
این نرمافزار محیط توسعه یکپارچه برای برنامهنویسی این میکروکنترلر میباشد.
کد تولید شده توسط نرمافزار STM32CubeMX در این نرمافزار اجرا میشود و برنامه نویسی پروژه و کامپایل و
تولید کد ماشین توسط این نرمافزار صورت میگیرد. از قابلیت ها دیگر این نرمافزار
بارگذاری برنامه روی حافظهی فلش میکروکنترلر، دیباگ برنامه بصورت خط به خط و
همچنین مشاهده متغیرهای حافظه میکروکنترلر به صورت زنده
میباشد.
نرمافزار STMSudio
این نرمافزار برای مشاهده متغیرهای موجود در حافظه رم میکروکنترلر مورد
استفاده قرار میگیرد. این نرمافزار با محیطی بسیار ساده و کاربردی کمک بسیاری
برای رفع اشکال کد و توسعهی کد میکند.
نرمافزار St-Link
Utility
این نرمافزار برای بارگذاری کد ماشین تولید شده به فرمتهای معروف Hex یا Bin توسط نرمافزار
IAR EWARM بر
روی حافظه دستورالعمل مورد
استفاده قرار میگیرد.
میکروکنترلرهای مختلفی توسط شرکتهای مختلفی در دنیا تولید میشود. از
سری های پر کاربرد در ایران می توان به AVR,PIC,ARM اشاره کرد که از این میان
پردازندههای ARM 32 بیتی و AVR,PIC 8 بیتی هستند. در این آزمایشگاه از پردازندههای ARM به دلیل
جایگاه مهمی که در طراحی سیستمهای توکار دارد استفاده میشود. شرکتهای مختلفی از
هستهی ARM برای
تولید میکروکنترلر استفاده میکنند. در ایران دومیکروکنترلر ساخت شرکتهای Philips و Stmicroelectronics
بیشتر مورد استفاده قرار میگیرد. از این دو سری در این آزمایشگاه از
میکروکنترلرهای ساخت شرکت Stmicroelectronics برای آموزش استفاده میشود.
سری 32 بیتی میکروکنترلرهای ساخت شرکت Stmicroelectronics با
نام stm32 به
خانوادههای مختلفی تقسیم میشوند که در زیر تصویر آن آمده است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image002.jpg)
در میان خانوادههای مختلف میکروکنترلرهای ARM ساخت شرکت stm با هستههای
پردازشی مختلف که با اسم Cortex-Mx مشخص میشود برای این آزمایشگاه، جدید ترین هسته Cortex-M یعنی
Cortex-M7 که
در ردهی High performance دسته بندی میشود تدریس میشود. سختافزاری که بر روی آن آزمایشها
صورت میگیرد، برد Stm32F7 Nucleo میباشد که هستهی اصلی آن میکرکنترلر STM32F746ZG میباشد. این
برد به دو قسمته اصلی و پروگرامر تقسیم میشود. همانطور که در شکل زیر مشاهده میکنید
قسمت پروگرامر با شیارهایی که در سمت راست برد قرار دارد از قسمت اصلی برد جدا شدهاست.
با اتصال کابل میکروUSB به قسمت پروگرامر میتوان میکروکنترلر قرار گرفته بر روی قسمت
اصلی برد را پروگرام کرد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image003.jpg)
1- نرمافزار STM32CubeMX را
اجرا کرده و با انتخاب New Project یک پروژهی جدید ایجاد کنید. در صفحهی باز شده و با استفاده از
اطلاعاتی که روی چیپ اصلی برد نوشتهشدهاست میکروکنترلر مورد نظر را انتخاب
کنید.(راهنمایی: برای انتخاب راحتتر و سریع میکروی مورد نظر بهتر است از فیلترها(series, line, package)
استفاده کنید. Package میکروکنترلر روی برد LQFP144 میباشد.)
2- با قسمتهای مختلف نرمافزار
STM32CubeMX کار
کنید و هر قسمت را مختصرا توضیح دهید.
3- از منوی پروژه Generate Code را انتخاب کنید. در پنجرهی باز شده نامی برای پروژه انتخاب کنید و محلی
برای ذخیره کردن پروژه برای آن مشخص کنید. از قسمت Toolchain/IDE باید
نرمافزار که برای توسعه و کامپایل کد مورد استفاده قرار میگیرد را به آن بدهید.
(نرمافزاری که در این آزمایشگاه مورد استفاده قرار می گیرد نرمافزار IAR EWARM میباشد)
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image004.jpg)
شکل 1 قسمت تنظیمات پروژه برای تولید کد
4- بعد از انجام مراحل قبل بر
روی OK کلیک
کنید تا نرمافزار STM32CubeMX پروژهی مورد نظر را ایجاد کند. بعد از ایجاد پروژه بر روی Open Project کلیک
کنید تا نرمافزار توسعهی کد شما یعنی IAR EWARM اجرا گردد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image005.jpg)
اگر هنگام
ایجاد کد با پیغام بالا روبرو شدید به این معنی است که پکیج مورد نظر برای سری
خانواده میکروکنترلر شما نصب نمیباشد.( مثلا در پیغام بالا پیکیج سری STM32F2 نصب
نمیباشد). برای نصب پکیج مورد نظر بر روی help>Install New Libraries کلیک کنید.
دو روش برای نصب پکیج وجود دارد:
Ø بصورت
افلاین: با مراجعه به سایت http://st.com/stm32cubef7 (برای سری STM32F7)در انتهای صفحه از بر روی get software کلیک کند و فایل zip را دانلود
کنید. فایل را بر روی سیستمی که قابلیت دسترسی به اینترنت ندارد منتقل کنید. از
قسمت نصب کتابخانه بر روی from
local کلیک کنید و فایل zip دانلود شده
را به آن بدهید. بعد از نصب بسته تیک سبز رنگ کنار بستهی نصب شده مشاهده میشود.
Ø بصورت
آنلاین: از قسمت نصب کتابخانه که از منوی help ایجاد شد. بروی بستهی مورد نظر کلیک
کنید. سپس روی Install now کلیک کنید. دقت کنید در این روش حتما باید نرمافزار به اینترنت
دسترسی داشته باشد تا بستههای مورد نظر را از سرور شرکت St دانلود کند.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image006.jpg)
5- بعد از ایجاد پروژه و ذخیرهی
آن بر روی Open Project کلیک کنید تا پروژهی ایجاد شده باز شود. پروژه در نرمافزار IAR اجرا میشود.
همانطور که در شکل زیر مشاهده میشود، پروژهی ایجاد شده شامل سه فولدر میباشد:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image007.jpg)
دو پوشهی
اول، شامل application و Drivers دو پوشهی
اصلی پروژه هستند. در پوشهی Drivers کتابخانههای راه انداز بخشهای مختلف میکروکنترلر قرار
دارند.پروژهی اصلی برای کامپایل شدن از دو کتابخانهی اصلی CMSIS و HAL که در این
پوشه قرار دارد استفاده میکند. پوشهی اصلی دیگر پوشهی Application قرار دارد که
تمام کدها و کتابخانههایی که کاربر به پروژه اضافه میکند در آن قرار میگیرد.
فایل اصلی برنامه که main.c قرار دارد در پوشهی user قرار دارد. کدها و الگوریتمهای اصلی کاربر در این فایل در تابع main()
نوشته میشود.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image008.jpg)
6- فایل main.c را از قسمت Application>User باز
کنید. به ساختار کد و کامنتهای تولید شده دقت کنید.
فرض کنید می
خواهید دو کتابخانهی stdlib.h و math.h را به پروژهی خود اضافه کنید.در ابتدای کد با استفاده از دستور #include یکی را قبل از کامنت /* USER CODE BEGIN Includes */ و دیگری
را بعد از کامنت بنویسید. فایل را ذخیره کنید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image009.jpg)
به نرمافزار STM32CubeMX برگشته یک
بار دیگر Generate Code را انتخاب کنید. به نرمافزار IAR برگشته و
تغییرات را مشاهدهکنید. چه نتیجهای میگیرید؟ دلیل این تغییرات چه میباشد؟
در این جلسه با یکی از مهمترین واحدهای جانبی میکروکنترلرstm32f746 که
واحد GPIO میباشد
و نحوهی تنظیم کردن آن در نرمافزار STM32CubeMX و کار کردن با کتابخانههای HAL آشنا میشوید.
کتابخانهی HAL رابط برنامه نویس با واحد سخت افزار میباشد. بدین صورت که این
کتابخانه با فراهم کردن توابعی وظیفهی ارتباط با رجیسترهای سخت افزار را بر عهده
میگیرد. تمام مباحثی که در این آزمایشگاه گفته میشود توسط این کتابخانه پیاده
سازی و اجرا میشود. نرمافزار stm32cubemx با دسترسی به این کتابخانه پروژه را ایجاد میکند. سندی که این
کتابخانه ها را به طور کامل توضیح داده با شماره “dm00189702” با نام Description of
STM32F7xx HAL drivers در اینترنت قرار دارد.
با جستجوی نام این سند در اینترنت سند مورد نظر را دانلود
کنید و در انجام آزمایشات از آن استفاده کنید.
برای کار کردن با سخت افزار آزمایشگاه اطلاع داشتن از مدار برد و اتصالات
پایهها ضروری میباشد. شماتیک برد آزمایشگاه با شماره سند “dm00244518” با نام STM32
Nucleo-144 Board در اینترنت موجود است. با
جستجوی شماره سند شماتیک مدار را دانلود کرده و در آزمایشهای برای اطلاع از
اتصالات مدار از آن استفاده کنید.
برای انتخاب پایه به عنوان خروجی بر روی پایهی مورد نظر کلیک چپ کرده و GPIO_Output را
انتخاب کنید. با این کار پایهی مورد نظر به عنوان خروجی پیکربندی میشود. برای
تنظیمات بیشتر پایهی خروجی از قسمت Configuration قسمت system گزینهی GPIO را انتخاب کنید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image010.jpg)
پایههای مربوط به دیباگ و پروگرام کردن میکرو توسط واحد SWD مشخص میگردد.
اگر از این پایهها در پروژه استفاده گردد امکان دیباگ کردن برنامه غیر فعال میگردد
و امکان خطا هنگام پروگرام کردن نیز وجود دارد. نکته دیگری که اگر واحد SWD را در نرمافزار
فعال نکنید با مشکل در دیباگ کد برخورد میکنید این است که اگر از قسمت MENU>Project>Settings>TAB>Code
Generator تمام پایههای بدون استفاده را به
عنوان آنالوگ انتخاب کنید(به منظور کاهش توان مصرفی میکروکنترلر) دیگر قادر به
دیباگ کد نخواهید بود.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image011.jpg)
برای اطمینان از اینکه از پایههای SWD در پروژه
استفاده نمیشود، بهتر است از قسمت sys>debug>serial
wire آن را فعال کنید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image012.jpg)
همانطور که در شکل بالا مشاهده میکنید بعد از فعال سازی قسمت SWD پایههای
دیتا و کلاک میکروکنترلر با نام های SWCLK,
SWDIO روی میکروکنترلر نشان داده میشود.
1- با مراجعه به سند مربوط به
شماتیک برد، LED های متصل به پایههای میکروکنترلر را شناسایی کنید و شماره پورت و
پایههای آن را یادداشت کنید.
2- با توجه مباحثی که در قسمت
پیشآگاهی مطالعه کردید پایه های متصل به LED را در محیط STM32CubeMX بصورت خروجی
تعریف کنید. در قسمت Configuration چه تنظیماتی برای GPIO وجود دارد؟(هر یک را مختصرا شرح دهید) پروژه را ایجاد کنید و وارد
محیط برنامه نویسی IAR شوید.
3- با مراجعه به سند مربوط به
توضیحات کتابخانه HAL و مراجعه به فصل HAL
GPIO Generic Driver توابع مربوط برای نوشتن روی
خروجی میکروکنترلر را پیدا کنید و در گزارش توضیحات آن را بدهید.
4- با استفاده از توابعی که از
قسمت قبل بدست آوردید، برنامهای بنویسید که یکی از LED های موجود
روی برد هنگام اجرای برنامه با تاخیر 100 میلیثانیه شروع به چشمک زدن
کند.(راهنمایی: برای ایجاد تاخیر 100ms از
تابع HAL_Delay(100); استفاده کنید.)
5- برای کامپایل برنامه F7 را فشار
دهید. اگر برنامه خطایی نداشته باشد تعداد خطا در انتهای پنجرهی Build
مقدار صفر خواهد بود. اگر با خطایی مواجه شدید کدهای نوشتهشده را یکبار دیگر
بررسی کنید.(به حروف بزرگ و کوچک دقت کنید.)
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image013.jpg)
6- بعد از کامپایل برنامه باید
میکروکنترلر را پروگرام کنید. برای این کار بعد از اتصال کابل USB متصل به برد
به کامپیوتر از قسمت Download and
debug نوار ابزار اقدام به پروگرام میکروکنترلر
کنید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image014.jpg)
7- بعد از پروگرام کردن
میکروکنترلر، نرمافزار IAR وارد محیط دیباگ میشود. همانطور که میبینید اولین خطی که برنامه
از آن اجرا میشود تابع main() میباشد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image015.jpg)
با ابزارهای موجود در قسمت دیباگ که در شکل زیر نشان داده شده است
کارکنید و نتیجهی کار هر کدام را توضیح دهید. با گذاشتن break point در کد نوشته
شده، نتیجهی آن را گزارش دهید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image016.jpg)
8- برنامهای بنویسید که هر سه
LED روی
برد همزمان در یک خط کد تغییر وضعیت دهد.
نکته: آزمایشهای
انجام شده در هر جلسه را در جلسات بعدی همراه داشته باشید. برای انتقال پروژه بر
روی فلش مموری از منوی Project>clean بزنید تا فایلهای اضافهی تولید شده پاک شود وحجم پروژه کاهش
پیدا کند.
در این آزمایش با نحوهی خواندن پایههای ورودی میکروکنترلر و همچنین
مشاهده متغیرهای داخلی میکروکنترلر به صورت زنده آشنا خواهید شد.
برای خواندن وضعیت ورودی یک پایه باید نوع پایه به عنوان GPIO_Input
انتخاب شود. برای اینکار روی پایه ای از میکروکنترلر که به عنوان ورودی می خواهید
استفاده کنید٬ کلیک چپ کرده و GPIO_Input را
برای آن انتخاب کنید.
یکی از مدار های ساده برای خواندن ورودی میکروکنترلر استفاده از کلید
فشاری است. کلید فشاری با توجه به طراح سخت افزار به صورت فعال با یک و یا فعال با
صفر در مدار قرار میگیرد. دلیل استفاده از مقاومت این است که در هنگام رها کردن
کلید فشاری٬ وضعیت پایهی میکروکنترلر به صورت
شناور قرار نگیرد. در صورت عدم استفاده از مقاومت های PU/PD ورودی
میکروکنترلر عملکرد درستی نخواهد داشت. در شکل زیر نحوهی اتصال این دو حالت امده
است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image017.jpg)
نکته: بهجای استفاده از مقاومت خارجی جهت pull-up و pull-down می
توان از مقاومت داخلی که جهت این کار قرار گرفته است استفاده کرد. برای فعال سازی
مقاومتهای داخلی از قسمت Configuration ٬ قسمت GPIO پایهی مورد
نظر را انتخاب کرده و از قسمت GPIO Pull-up/pull-doown یکی را انتخاب کنید.
برای مشاهده متغیر هایی که بصورت global در برنامه تعریف شده اند٬ پس از بارگزاری برنامه بر روی میکروکنترلر و وارد شدن به
مرحله debug از
منوی view روی live watch کلیک
کنید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image018.jpg)
قسمت live watch به محیط دیباگ برنامه اضافه می شود. Live watch از دو قسمت Expression و value
تشکیل شده است که در قسمت Expression نام متغیری که می خواهید ان را ببینید وارد میکنید و در قسمت value
مقداری که آن متغیر در طول برنامه دارد نشان داده میشود.
این نرمافزار مخصوص مشاهده متغیر های برنامه است٬ برای کار با این نرمافزار
مراحل زیر را انجام دهید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image019.jpg)
از دایرکتوری زیر فایل *.out را
وارد کنید:
PRJ_NAME\EWARM\ PRJ_NAME \Exe
و بعد از محلهی بالا مانند تصویر زیر متغیر را به قسمت مشاهده متغیر
اضافه کنید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image021.jpg)
1- با مراجعه به سند توضیحات
کتابخانه HAL فصل HAL GPIO Generic Drivers
بررسی کنید برای خواندن پایه به عنوان ورودی از چه تابعی باید استفاده کرد.
2- با مراجعه به سند شماتیک
برد، پایههایی که کلیدهای فشاری برد به آن متصل شده است را بدست آورید.
3- با تعریف پایهی متصل به
کلید User به
عنوان ورودی، برنامهای بنویسید که وقتی کلید فشاری فشرده شد، یکی از LED های روی برد
روشن شود و وقتی رها شد خاموش شود.
4- برنامهای بنویسید که با هر
بار فشردن کلید، شمارنده یک واحد یک واحد افزایش پیدا کند. با استفاده از Live watch این
شمارنده را در نرمافزار IAR مشاهده کنید.
5- برنامهی قبل را در نرمافزار
STMStudio اجرا
کنید و شمارنده را در این نرمافزار مشاهده کنید.
در آزمایش قبل با نحوه ی خواندن ورودی بدون استفاده از وقفه و به صورت
سرکشی
آشنا شدید.در
این آزمایش با مفهوم وقفه و اولویتهای وقفه آشنا میشوید و وقفهی خارجی
میکروکنترلر را راه اندازی خواهید کرد.
همانطور که در شکل زیر مشخص است٬ وقفه ای که از محیط پیرامون STM32(نظیر
ADC,EXTI (TIMER,می آید به قسمت کنترلر وقفه
می آید و با توجه به الویت وقفهها،
هسته پردازشی را در اختیار تابع سرویس وقفه(Interrupt Service Routin-ISR)
قرار میدهد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image022.jpg)
وقفهها با توجه به اولویت آن ها به آنها پاسخ داده می شود. مثلا در شکل
زیر دو وقفهی IRQ1,IRQ2 با اولویت های متفاوت تعریف شده است. دقت کنید که هر چه سطح
اولویت عدد بیشتری داشته باشد از اولویت کمتری برخوردار است در نتیجه در شکل زیر IRQ1 اولویت
بالاتری نسبت به IRQ2 دارد. همانطور که در شکل زیر مشخص است رویداد دوم اتفاق افتاده و
هسته پردازشی توسط رویداد دوم گرفته میشود. در زمان اجرای سرویس وقفه دوم٬ رویداد اول که اولویت بالاتری دارد اتفاق می افتد در نتیجه
هسته پردازشی از رویداد دوم گرفته می شود و به رویداد اول که اولویت بالاتری دارد
داده میشود. بعد از اتمام سرویس وقفه اول٬
پردازش در اختیار وقفهی دوم قرار میگیرد و بعد از اتمام سرویس وقفهی دوم به
پردازش اصلی بر میگردد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image023.jpg)
علاوه بر اولویت٬ یک ویژگی دیگری به نام زیر اولویت در کنترلر وقفه
وجود دارد. اگر دو وقفه دارای اولویت یکسانی باشند ولی زیر اولویت آنها با یکدیگر
متفاوت باشد٬کنترلر وقفه مانند شکل
زیر آن ها را مدیریت میکند:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image024.jpg)
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image025.jpg)
همانطور که در شکل زیر آمده است پایههای ورودی میکروکنترلر به ورودی یک
مالتی پلکسر متصل هستند که اصطلاحا به آن line های ورودی گفته میشود. 16 پین بصورت
اینتراپت خاجی می توان فعال کرد٬ که روی پایه ها متناظر با
هر کدام مشخص می باشد.
v
نکته: دقت شود اگر از پین شماره 13 پورتC بهعنوان EXTI استفاده شود، دیگر نمی توان از پین 13 پورت B به عنوان EXTI استفاده کرد
و همینطور در پایههای دیگر از پورت های A,B ,…. در واقع مانند شکل زیر از هر شماره
پایه PA13, PB13, PC13, ... فقط یکی میتواند توسط مالتی پلکسر انتخاب گردد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image026.jpg)
برای انتخاب پایهی مورد نظر به عنوان وقفهی خارجی مانند شکل زیر، GPIO_EXTI
انتخاب کنید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image027.jpg)
وقفه با حالت های مختلفی(لبهی
بالارونده، لبه پایینرونده و ...) میتواند رخ دهد. این حالت ها به دو دسته
رویداد و وقفه تقسیم میشود. در شکل زیر این حالات نشان داده شده است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image028.jpg)
برای فعال سازی وقفه
باید از منوی Configuration بر روی NVIC کلیک کنید و در پنجرهی باز شده با انتخاب آن، وقفه را فعال کنید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image029.jpg)
در پنجرهای که باز میشود
تمام وقفه هایی که فعال هستند با علامت کنار آن مشخص شدهاند. تنظیمات این قسمت را
مانند شکل زیر انجام دهید. همانطور که گفته شده وقفه خارجی شامل 16 پایهی
خارجی(که به آنها lineگفته میشود) میباشد. با توجه به پایهای که انتخاب میشود
فعالسازی وقفه مورد نظر در این قسمت میآید. مثلا برای فعال سازی وقفه با شماره Line 13 باید EXTI line[15:10] Interrupt را فعال کرد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image030.jpg)
تمام وقفه های خارجی فقط در یک روتین پاسخ داده می شود. روتین وقفه بصورت
__weak در فایل stm32f7xx_hal_gpio.c
تعریف شده است. این فایل در نرمافزار IAR در پوشه Driver\STM32F7xx_hal_gpio.c وجود
دارد. به توابع پاسخ به وقفه(چه داخلی چه خارجی) Callback گفته میشود.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image031.jpg)
با جستجوی عبارت __weak در این فایل تابع ISR مورد نظر پیدا میشود. مانند کد زیر آن را در فایل main.c قبل
از تابع main() کپی کنید.
همانطور که گفته شد تمام وقفههای
خارجی در یک روتین وقفه پاسخ داده میشود. برای تشخیص شماره Line وقفه و پاسخ
به آن می توان مانند شکل زیر از دستور switch استفاده کرد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image032.jpg)
1- پایهی متصل به کلید فشاری user را که در
جلسه قبل به عنوان ورودی(GPIO_Input)
انتخاب کردید، در این آزمایش به عنوان وقفه خارجی(EXTI) تعریف کنید. با مراجعه به شماتیک و بررسی مدار کلید فشاری، از
قسمت Configuration کدام مد باید انتخاب شود؟
2- با توجه به مباحثی که در
پیشآگاهی توضیح داده شد، با فعال سازی وقفه برنامهای بنویسید که هنگام فشرده شدن
کلید فشاری user وضعیت یکی از LEDهای روی برد Toggle شود.
3- تابع HAL_Delay
را بررسی کنید و توضیح دهید که چطور این تابع باعث ایجاد تاخیر میشود.(راهنمایی:
با کلیک راست کردن بر روی تابع HAL_Delay() به قسمت Go to definition of ‘HAL_Delay’بروید).
4- برنامهای بنویسید که با هر
بار فشردن کلید فشاری user، یکی از LED های روی برد به مدت 1 ثانیه روشن بماند، سپس خاموش شود.
5- به پرسش های زیر پاسخ دهید:
v با بررسی مدار کلید فشاری user دلیل گذاشتن
مقاومت ها و خازن را پیدا کنید.
v بررسی کنید کنید تفاوت
مدهای Event و Interrupt در چیست؟
v در زبان برنامه نویسی C توابعی که با
__weak شروع میشوند
چه توابعی هستند و چه کاربردی دارند؟
ارتباط سریال یکی از پرکاربرد ترین روش ارتباطی در میان انواع ارتباط ها
می باشد. این ارتباط به دلیل سادگی و سیم کشی کم٬ بستر بسیار ساده برای ارتباط را فراهم می کند. ارتباط UART یک از معروف
ترین پروتکل ارتباطی برای ارتباط با دستگاه های جانبی(مانند لپتاپ یا هر ماژول
دیگری) میباشد.در این آزمایش با نحوهی راه اندازی واحد سریال
UARTدر
میکروکنترلر STM32F746 و ارتباط آن با کامپیوترهای موجود در آزمایشگاه آشنا خواهیدشد.
5-1-1 نحوهی ارسال سریال
داده
ارسال داده در ارتباط UART به صورت سریال است. در ارتباط سریال آسنکرون برای پیدا کردن شروع
بیت و دریافت داده در سمت گیرنده نیاز به بیتهای اضافی(overhead) است. همانطور
که در تصویر زیر آمدهاست برای ارسال 8بیت داده نیاز به 2بیت سربار یکی برای مشخص
کردن شروع بیت و دیگری برای پایان بیت است. برای ارسال داده در ارتباط سریال
معمولا از کد های اسکی
استفاده می
شود. برای مثال برای ارسال حرف “ui”
همانطور که در جدول کدهای اسکی آمده باید دو عدد u=117 و i=105
ارسال شود. باینری این دو عدد به صورت قطاری از صفر و یک مانند شکل زیر ارسال میشود:
![http://old.myhdl.org/lib/exe/fetch.php/projects:rs232image.png?w=500](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image033.gif)
![https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/ASCII-Table.svg/738px-ASCII-Table.svg.png](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image034.gif)
5-1-2 مشخصات سیگنالینگ ارتباط UART
و تفاوت آن با RS232
سطح ولتاژ منطقی 0 و 1 در میکروکنترلرها پایین میباشد مثلا در STM32f746 یک
منطقی با ولتاژ 3.3 ولت و صفر منطقی با صفر ولت مشخص می شود این درحالی است که در
پروتکل RS232 یک
منطقی با ولتاژ -12 ولت و صفر منطقی با ولتاژ +12 ولت مشخص می شود.
![Image result for uart signals](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image035.jpg)
1-
استفاده از پورت سریال موجود بر روی برد اصلیCase کامپیوتر:
پورت سریال موجود بر روی کامپیوتر از پروتکل RS232 استفاده میکند.
برای ارتباط از این طریق به دلیل تفاومت سطح ولتاژهای منطقی 0 و 1 نیاز به یک چیپ
واسط میباشد. یکی از چیپهای معروف برای ارتباط RS232 با
میکروکنترلر چیپ MAX232 میباشد.
2-
استفاده از مبدل USB to Serial: یکی از روشهای
معروف برای ارتباط با کامپیوتر استفاده از مبدل های USM به سریال میباشد.
این مبدلها به دلیل فراهم کردن ارتباط USB بسیار مورد استفاده قرار میگیرد. از
چیپهای معروفی که این ارتباط را انجام میدهند میتوان به FT232, PL2303, CP2102
اشاره کرد.
3-
استفاده از ارتباط سریال مجازی(VCP) : این ارتباط که بستری کاملا نرمافزاری است،قابل پیاده سازی
مستقیم بر روی درگاه USB میکروکنترلرهای STM32 میباشد. بدین صورت که با اتصال کابل USB برد شما به
عنوان یک پورت سریال شناخته میشود. در این آزمایشگاه از سریال مجازی که میکروکنترلر
موجود(STM32F103) بر روی قسمت
پروگرامر برد فراهم میکند استفاده میشود. اگر به شماتیک برد مراجعه کنید این
قسمت بهUSART3 یعنی پایههای PD8 و PD9 میکروکنترلر متصل است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image036.jpg)
در این آزمایش برای تست
ارتباط سریال بین میکروکنترلر و کامپیوترها از virtual com port که در قسمت پروگرمر ST-Link قراردارد استفاده میشود. برای دیدن شماره پورت سریال که در
ویندوز ایجاد شده٬ از قسمت Control Panel>Device Manager قسمت Ports مشاهده کنید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image038.jpg)
نرمافزارهای زیادی مانندTerminal,
RealTerm,Hercues,… برای ارسال و دریافت از پورت
سریال در محیط ویندوز وجود دارد. در
تمامی این نرمافزار ها٬ برای اتصال به برد تنها
کافیست شماره پورت که در قسمت قبل توضیح داده شد به همراه Baud Rate در
قسمت تنظیمات وارد شود و سپس برای اتصال روی دکمه Connectیا Open کلیک شود. در شکل زیر این تنظیمات در نرمافزار Hercules نشان
داده شده است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image039.jpg)
نکته: برای ارسال عدد در مبنای هگز از علامت $ وبه
صورت یک عدد 2 رقمی در مبنای 16 و برای ارسال عدد دسیمال از علامت # به صورت یک عدد سه رقمی استفاده میشود. در حالت عادی(بدون علامت $, #) کد اسکی نوشته شده در قسمت send ارسال میشود.
برنامه نویسی پورت سریال در زبانهای برنامه نویسی معروف مانند Java, C++, C#, python
بسیار آسان است. در اکثر زبان های برنامه نویسی به صورت پیشفرض توابعش موجود است
که به شما در نوشتن یک ارتباط بین سخت افزار و نرمافزار کمک میکند. در زیر اسم
کتابخانههای موجود برای ارتباط با پورت سریال در زبانهای برنامه نویسی مختلف
آمدهاست:
در محیط QT C++
استفاده از کتابخانه ی QSerial
در زبان برنامه نویسی C# استفاد از
ابزار SerialPort در قسمت جعبه ابزار
در زبان Java استفاده از
کتابخانهی Java Simple Serial
Connector و jSerialComm
در زبان Python
استفاده از کتابخانهی Pyserial
همانطور که گفته شد ارتباط UART یک ارتباط اسنکرون(برای هماهنگسازی نیاز به کلاک ندارد) سریال میباشد
و شامل یک پایه برای ارسال داده(TX) و یک
پایهبرای دریافت داده(RX) میباشد.
اتصالات و سیم کشی واحد UART بر روی برد فراهم شده است و به پایههای ارسال و دریافت داده
میکروکنترلر به پایههایVCP روی برد پروگرامر متصل شده است. در صورتی که بخواهید دو
میکروکنترلر یا هر دستگاه دیگری را از طریق واحد UART به هم متصل
کنید مانند شکل زیر باید اتصالات انجام شود. یعنی پایهی Rx یکی به Tx
دیگری متصل می شود و برعکس.
![https://www.allaboutcircuits.com/uploads/articles/BBUART_diagram1_2.JPG](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image040.jpg)
با توجه به اینکه در سخت افزار برد UART شماره3 به پورت
مجازی موجود بر روی برد متصل است٬ در تنظیمات cubeMX
مانند شکل زیر USART3 را بصورت Asynchronous تنظیم کنید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image041.jpg)
همانطور که مشاهده کردید پایههای PB11 و PB10 به عنوان UART پیکربندی
شدند اما پایه های PD8,PD9 برای ارتباط متصل هستند.(به شماتیک برد رجوع کنید) برای انتقال
این پایه ها به پایه ها PD8 , PD9 که پایههای جایگزین USART3 هستند مانند شکل زیر عمل کنید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image042.jpg)
همانطور که مشاهده کردید پایههای PD8 و PD9 برای ارتباط
سریال UART
پیکربندی شدند. برای تنظیمات واحد UART از قسمت Configuration قسمت Connectivity روی USART3 کلیک کنید.
Baud Rate را روی 9600 Bits/s قرار
دهید و Word Length را برابر 8 قرار دهید(مانند شکل زیر).
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image043.jpg)
پروژه را ایجاد کرده و وارد محیط برنامه نویسی IAR شوید.
در زیر تابع ارسال داده بدون استفاده از وقفه بر روی
ارتباط UART از
سمت میکروکنترلر آمده است:
HAL_UART_Transmit
Function name
|
HAL_StatusTypeDef
HAL_UART_Transmit (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t
Size, uint32_t Timeout)
|
Function description
|
Send an amount of data
in blocking mode.
|
Parameters
|
huart: UART
handle.
pData: Pointer
to data buffer.
Size: Amount
of data to be sent.
Timeout:
Timeout duration.
|
Return values
|
HAL: status
|
در زیر تابع ارسال داده با استفاده از وقفه بر روی ارتباط UART از سمت
میکروکنترلر آمده است:
HAL_UART_Transmit_IT
Function name
|
HAL_StatusTypeDef
HAL_UART_Transmit_IT (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t
Size)
|
Function description
|
Send an amount of data
in interrupt mode.
|
Parameters
|
huart: UART
handle.
pData: pointer
to data buffer.
Size: amount
of data to be sent.
|
Return values
|
HAL: status
|
نکته: دقت شود با هر بار اجرا شدن سرویس وقفه نیاز هست تا تابع HAL_UART_Receive_IT
دوباره فراخوانی شود.
HAL_UART_Receive_IT
Function name
|
HAL_StatusTypeDef
HAL_UART_Receive_IT (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t
Size)
|
Function description
|
Receive an amount of
data in interrupt mode.
|
Parameters
|
huart: UART
handle.
pData: pointer
to data buffer.
Size: amount
of data to be received.
|
Return values
|
HAL: status
|
نکته: بهتر است تا مقدار دادههای دریافتی برابر با یک باشد تا با هر بار
دریافت داده، سرویس وقفه اجرا شود.
نکته: بهترین قسمت فعال سازی واحد وقفه گیرنده گذاشتن تابع بالا یک بار
قبل از حلقهی بینهایت while(1) و در انتهار تابع سرویس وقفه میباشد.
1-
با استفاده از تابع HAL_UART_Transmit نام خود را به
کامپیوتر ارسال کنید به طوری که قبل از ارسال یکی از LED های برد روشن
و بعد از ارسال خاموش و به مدت یک ثانیه صبر کند و دوباره این روند تکرار شود.
برای دیدن نام خود از نرمافزار Hercules که در پوشهی serial
tools در Desktop قرار دارد،
استفاده کنید. زمان روشن ماندن LED چند میلیثانیه است؟
1)
روشن شدن LED
2)
ارسال داده
3)
خاموش شدن LED
4)
تاخیر به مدت یک ثانیه(HAL_Delay(1000))
5)
تکرار مراحل بالا
مثلا برای ارسال عبارت “university
of Isfahan” به این صورت نوشته میشود:
char *str=”university of isfahan”;
HAL_UART_Transmit(&huart3,str,strlen(str),100);
پارامتر آخر Timeout بر حسب میلیثانیه میباشد. با توجه به اینکه این تابع باعث بلاک
شدن برنامه هنگام ارسال داده میشود پارامتر آخر حداکثر زمان این ارسال را مشخص میکند
و اگر دادهها در این زمان ارسال نشوند، از این تابع خارج میشود.
نکته: این تابع باعث بلاک شدن برنامه هنگام ارسال دادهها میشود(زمان
روشن ماندن LED). برای جلوگیری از بلاک شدن می توان با استفاده از HAL_UART_Transmit_IT() داده ها را ارسال کرد.
2-
مانند شکل زیر از قسمت NVIC Setting وقفهی واحد UART را فعال
کنید، سپس آزمایش اول را با استفاده از تابع HAL_UART_Transmit_IT()
بنویسید.(یادآوری: در نرمافزار STM32Cubemx بر
روی generate code کلیک کنید تا تغییرات بر روی پروژه اعمال شود.)
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image044.jpg)
همانطور که در آزمایش قبل روتین سرویس وقفه را که به صورت Weak تعریف شده
بود را در main.c ایجاد کردید برای استفاده از اینتراپت UART هنگام دریافت
داده٬ از فایلstm32f7xx_hal_uart.c تابع
void HAL_UART_TxCpltCallback(UART_HandleTypeDef
*huart){
__NOP();
}
را به فایل main.c اضافه کنید. هنگام اتمام ارسال اطلاعات به واحد سریال با استفاده
از دستور HAL_UART_Transmit_IT() این سرویس روتین وقفه اجرا میشود. با گذاشتن Break
Point بر روی خط __NOP() عملکرد برنامه را بررسی کنید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image045.jpg)
3-
برنامهای بنویسید که درصورت دریافت حرف ‘a’ یکی از LEDها روشن و با دریافت حرف ‘b’ خاموش شود.
راهنمایی: برای دریافت داده از
دستور HAL_UART_Receive_IT استفاده میشود. هر زمان این تابع فراخوانی شود وقفه دریافت فعال
میشود و با هر بار دریافت داده با توجه به تعدادی که در پارامتر size این داده
مشخص شده سرویس روتین وقفه اجرا میشود. مثلا اگر بخواهیم با دریافت هر داده وقفه
خورده شود کد زیر را باید بنویسیم:
HAL_UART_Receive_IT(&huart3,rx_data,1);
پارامتر اول شماره سخت افزار uart را نشان میدهد.
پارامتر دوم ارایهای است که دادههای دریافتی در آن ذخیره میشوند. پارامتر سوم
تعداد دادههایی است که می خواهیم در صورت دریافت سرویس روتین وقفه اجرا شود.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image046.jpg)
نکته: تابع
HAL_UART_Receive_IT حتما باید فراخوانی شود تا وقفه اجرا شود و با هر بار اجرای وقفه
دوباره باید فراخوانی شود. این تابع اولین بار قبل از حلقهی while(1) یک بار فراخوانی میشود تا سرویس روتین وقفه اجرا شود. برای فراخوانی
دوباره این تابع همانطور که در کد بالا نوشته شد در سرویس روتین وقفه این تابع
فراخوانی میشود.
4-
برنامهای بنویسید که میکروکنترلر دو عدد دلخواه از ترمینال
دریافت کرده و ضرب این دو عدد را بعد از محاسبه به ترمینال برگرداند. (راهنمایی:
برای مشخص کردن انتهای عدد میتوانید یکی از کدهای هگز Cr=0x0D, LF=0x0A
استفاده کنید.) برای دریافت داده و بافر
کردن دادههای دریافتی مانند کد زیر عمل شود:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image047.jpg)
5- به پرسشهای زیر پاسخ دهید:
v تفاوت واحدUART با USART چیست؟ آیا میتوان از واحد USART به عنوان UART استفاده کرد؟
v مدار ارتباط میکروکنترلر با
پورت سریال کامپیوتر که با استفاده از چیپ MAX232 طراحی شده باشد را رسم کنید.
v چرا از بیتهای سربار در
ارسال داده استفاده میشود؟
هدف از این آزمایش آشنایی با تایمرها و کانترها در میکروکنترلرهای ARM سری STM32 می
باشد. از مهمترین کاربردهای تایمرمیتوان به:
ü
مدیریت زمان وظایف در یک برنامه
ü
جلوگیری از بلاک شدن کد
ü
تولید پالس دیجیتال پیوسته بدون نیاز به دخالت CPU
ü
تولید پهنای پالس مدولهشده
ü
و ...
اشاره کرد. کانترها یا همان شمارنده در واقع همان تایمری میباشد که
کلاک میکروکنترلر در آن دخالت ندارد و یک رویداد خارجی باعث شمارش آن میشود.
6-1-1 تایمرها
تایمرها در میکروکنترلر STM32 به سه دستهی اصلی تقسیم میشوند:
Advanced-control timers (TIM1/TIM8)
General-purpose timers (TIM2/TIM3/TIM4/TIM5)
General-purpose timers
(TIM9/TIM10/TIM11/TIM12/TIM13/TIM14)
Basic timers (TIM6/TIM7)
در شکل زیر، بلوک دیاگرام یک تایمر پایه نشان داده شده است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image048.jpg)
همانطور که در شکل بالا مشاهده میشود، منبع اندازه گیری زمان، کلاک داخلی میکرو میباشد. این کلاک با استفاده از یک واحد Prescaler قابل
تقسیم شدن میباشد. فرض کنید کلاک داخلی میکروکنترلر ما 16 مگاهرتز باشد. برای
تولید یک وقفه زمانی به مدت 1 ثانیه، واحد prescaler را برابر 15999 قرار می دهیم و
Auto-Reload Register را 999 مقدار
دهی میکنیم.
نکته: دقت شود در قسمت prescaler چون تقسیم بر صفر نداریم، عدد
وارد شده همیشه یک واحد به آن اضافه میشود. در نتیجه برای تقسیم بر 16000 عدد
15999 را مینویسیم.
6-1-2 تنظیمات تایمرها در نرمافزار
STM32CubeMX
بسته به نوع تایمر و امکاناتی که تایمر دارد تنظیمات متفاوتی در نرمافزار
stm32cubemx
وجود دارد. ساده ترین تنظیمات، تنظیم کردن زمان تایمر می باشد، مثلا با فعال کردن
تایمر 10 در قسمت configuration نرمافزار شکل زیر نمایش داده میشود.(پیشفرض
مقادیر صفر میباشد، در اینجا برای پیاده سازی زمان 1 ثانیه این مقادیر قرار داده
شده است)
نکته: فرکانس کلاک ورودی واحد تایمر پیشفرض 16
مگاهرتز میباشد.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image049.jpg)
برای شروع تایمر به شمارش در مد وقفه از دستور زیر
استفاده می شود. دقت شود که این دستور بعد از خط مربوط به تنظیمات تایمر قرار می
گیرد(MX_TIMx_Init).
HAL_TIM_Base_Start_IT(&htim10);
و برای نگهداشتن آن از این دستور استفاده میشود:
HAL_TIM_Base_Stop_IT(&htim10);
روتین سرویس وقفهای که هنگام به پایان رسیدن شمارش تایمر اجرا میشود،
void
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
نام دارد که به صورت __weak در فایل stm32f7xx_hal_tim.c وجود دارد.
v آزمایش شماره1 و 2 را
انجام دهید.
6-1-3 شمارندهها
شمارندهها در واقع همان تایمرها هست که منبع کلاک آن، یکی از پایههای خارجی میکروکنترلر میباشد. برای فعال سازی
شمارندهها یکی از تایمرها که این قابلیت را دارند انتخاب کرده و قسمت clock source را
روی ETR2 قرار
دهید. برای مثال در شکل زیر از تایمر شماره 2 در مد شمارنده استفاده شده است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image050.jpg)
تنظیمات قسمت configuration مانند تنظیمات تایمر می باشد با این تفاوت که دیگر در اینجا منبع
کلاک ما 16 مگاهرتز نیست و پایه ای است که تعریف شده است(در مثال بالا پایه PA0). با هر بار فشار دادن کلید متصل به پایه PA0 در مثال بالا
شمارنده یک واحد شمرده و اگر با مقدار auto reload register برابر شد،
روتین سرویس وقفهی تایمر HAL_TIM_PeriodElapsedCallback اجرا می شود.
v
آزمایش شماره3 را انجام دهید.
6-1-4 Output Compare
این مد برای ایجاد یک خروجی از مقایسه کنندهی تایمر طراحی شده است. این
خروجی می تواند منبع تریگر واحدهای دیگر داخلی میکروکنترلر مانند واحد ADC برای نمونه
برداری دادهی آنالوگ و یا به طور مستقیم بر روی یکی از پایههای میکروکنترلر به
عنوان خروجی کلاک برای قطعات دیگر مدار مورد استفاده قرار گیرد. برای استفاده از
این قابلیت روی تایمرهایی که خروجی مقایسه کننده در اختیار است، میتوان استفاده
کرد. برای مثال Timer3 خروجی کانال سوم آن به پایهی PB0 متصل است.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image051.jpg)
برای تنظیم زمان تایمر مانند آنچه در قسمت تایمر گفته شود عمل میشود.
همانطور که در شکل زیر آمده است، خروجی شامل مدهای مختلفی است که برای ایجاد یک
پالس پریودیک مربعی از گزینه Toggle
on match استفاده میشود. یعنی زمانی که
شمارندهی تایمر به مقدار Counter
period رسید وضعیت خروجی را معکوس کند.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image052.jpg)
نکته: کانالهای تایمر جدا از CPU کار میکنند
و برای اجرا نیاز به فعالسازی وقفه ندارد.
برای شروع کار تایمر و تولید خروجی
بر روی کانال سوم تایمر سه از دستور زیر استفاده میشود:
HAL_TIM_OC_Start(&htim3,TIM_CHANNEL_3);
v آزمایش شماره 4 را
انجام دهید.
1-
برنامهای بنویسید که بدون استفاده از تابع HAL_Delay یکی
از LED های
روی برد را هر یک ثانیه خاموش و روشن کند.(از تایمر شماره10 استفاده شود)
2-
فقط با استفاده از یک تایمر(مثلاً تایمر
شماره10) سه LED روی برد را با زمانهای
·
LD1:
1 s
·
LD2:
500 ms
·
LD3:
200 ms
روشن و خاموش نماید.
3- با استفاده از تایمر
شماره2 در مد شمارنده(Counter) برنامهای بنویسید که هر بار 5 کلید زده شد وضعیت LED متصل به
پایه PB0
برعکس(toggle) شود.
4- با فعالسازی Timer3
یک پالس مربعی با فرکانس 10 هرتز بر روی کانال سوم(PB0) این
تایمر ایجاد کنید.
در این آزمایش با واحد مبدل
آنالوگ به دیجیتال DAC آشنا خواهید شد. این واحد به شما این امکان را میدهد تا ولتاژ
خروجی متغیر از صفر ولت تا ولتاژ مرجع مثبت(VREF+) ایجاد کنید.
7-1-1 سخت افزارDAC
مبدلهای دیجیتال به انالوگ از تعدادی ورودی دیجیتال که بیانگر دقت آن میباشد
مانند شکل زیر تشکلیل شده است. با توجه به مقدار صفر و یکی که بر روی ورودی قرار
میگیرد ولتاژ خروجی متناظر با آن تغییر میکند:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image053.jpg)
میکروکنترلر STM32f7 دارای دو
کانال 12 بیتی خروجی آنالوگ میباشد که در نرمافزار STM32CubeMX قابل فعال
سازی است.
7-1-2 DAC در نرم افزار STM32CubeMX
به منظور فعال سازی واحد DAC از قسمت چپ نرم افزار بر روی DAC کلیک کنید و
با توجه به کانالی که می خواهید آن را به عنوان خروجی انالوگ در نظر بگیرید فعال
کنید. همانطور که میبینید کانالهای خروجی انالوگ بر روی پایههای PA4, PA5 قرار
گرفتهاند.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image054.jpg)
7-1-3 توابع HAL برای کار کردن با واحد DAC
HAL_DAC_Start
Function name
|
HAL_StatusTypeDef
HAL_DAC_Start (DAC_HandleTypeDef *hdac, uint32_t Channel)
|
Function description
|
Enables DAC and starts
conversion of channel.
|
Parameters
|
hdac: pointer
to a DAC_HandleTypeDef structure that
contains the configuration information for the specified DAC.
Channel: The selected DAC channel. This parameter can be
one of the following values:
DAC_CHANNEL_1: DAC
Channel1 selected
DAC_CHANNEL_2: DAC Channel2 selected
|
Return values
|
HAL: status
|
مثال) با اجرای خط زیر کانال دوم از
واحد DAC فعال
میشود.
HAL_DAC_Start(&hdac,DAC_CHANNEL_2);
HAL_DAC_SetValue
Function name
|
HAL_StatusTypeDef
HAL_DAC_SetValue
(DAC_HandleTypeDef * hdac, uint32_t Channel, uint32_t
Alignment, uint32_t Data)
|
Function description
|
Set the specified data
holding register value for DAC channel.
|
Parameters
|
hdac: pointer
to a DAC_HandleTypeDef structure that
contains the configuration information for the specified DAC.
Channel: The selected DAC channel. This parameter can be
one of the following values:
DAC_CHANNEL_1: DAC Channel1 selected
DAC_CHANNEL_2: DAC Channel2 selected
Alignment: Specifies the data alignment. This parameter
can be one of the following values:
DAC_ALIGN_8B_R: 8bit right data alignment selected
DAC_ALIGN_12B_L: 12bit left data alignment selected
DAC_ALIGN_12B_R: 12bit right data alignment selected
|
مثال با
اجرای خط زیر مقدار value_dac برو روی کانال دوم خروجی آنالوگ set میشود:
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_2,
DAC_ALIGN_12B_R,value_dac);
7-1-3 ارتباط مقدار دیجیتال واحد DAC به ولتاژ
خروجی
ولتاژ خروجی آنالوگ هر کانال DAC از فرمول زیر محاسبه میشود:
DAC_OUTx
= VREF+ * DOR / 4095
که DOR مقدار دیجیتالی است که با استفاده از دستور HAL_DAC_SetValue
مقداردهی شدهاست و VREF+ ولتاژ مرجع ورودی است که بر روی پایهی VREF+
میکروکنترلر قرار گرفته است. بر روی برد STM32f7-Nucleo این پایه
به ولتاژ 3.3v متصل شده است.
1-
کانال دوم DAC را فعال کنید و با استفاده از توابعی که در قسمت پیش آگاهی توضیح
داده شد ولتاژ خروجی کانال دوم را هر دو ثانیه با ولتاژهای 0 ، 1، 2و3 ولت تغییر
داده و آن را با استفاده از ولت متر مشاهده کنید.
اکثر پدیدههای پیرامون ما را میتوان
به صورت یک سیگنال پیوسته در زمان و پیوسته در مقدار(مانند:دما، رطوبت، نور و ...)
دستهبندی کرد. از این جهت برای پردازش این دادههای آنالوگ نیاز داریم آن را
تبدیل به دیجیتال کنیم تا واحد پردازش مرکزی میکروکنترلر بتواند این داده ها را
پردازش کند. میکروکنترلرهای STM32 دارای ADC با دقت 12 بیت هستند.
8-1-1 سخت افزارADC
سخت افزار استفاده شده در مبدلA/D مدار تقریب متوالی
می باشد. مدار زیر دیاگرام این روش میباشد:
![https://upload.wikimedia.org/wikipedia/commons/6/61/SA_ADC_block_diagram.png](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image055.jpg)
نرخ نمونه برداری:
سیگنالهای آنالوگ بصورت یک سیگنال پیوسته در زمان هستند، از این رو لازم است تا
به صورت مقدارهای دیجیتال پشت سر هم در بیایند. به نرخی که دادهی جدید بدست میآید
نرخ نمونه برداری یا فرکانس نمونهبرداری میگویند.
زمان تبدیل: زمانی که طول می کشد تا واحد ADC مقدار
دیجیتال یک سیگنال آنالوگ را محاسبه کند زمان تبدیل میگویند. نمودار زیر نحوهی
تبدیل یک مقدار آنالوگ به دیجیتال را نشان میدهد. با توجه به مدار سخت افزاری
واحد ADC و
نمودار زیر عملکرد واحد ADC را تحلیل کنید.
در مبدل A/D برای بدست آوردن مقدار دیجیتال خوانده شده توسط واحد ADC از فرمول زیر
استفاده میشود:
![alt text](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image056.gif)
برای مثال فرض کنید ولتاژ آنالوگ ورودی به میکروکنترلر مقدار 2.17 ولت
باشد. عددی که واحد ADC آن را میخواند برابر استبا:
<= ![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image058.gif)
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image059.jpg)
مبدل A/D می تواند به سه روش زیر عمل کند:
1-Polling
2-Interruption
3-Transfer by DMA
بعد از فعال سازی کانالهای ADC از قسمت Configuration تنظیمات زیر را انجام دهید.
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image060.jpg)
فرایند تبدیل با استفاده از این روش در زیر آمدهاست:
1. Start the ADC peripheral using
HAL_ADC_Start() .
2. Wait for end of conversion using
HAL_ADC_PollForConversion().
3. To read the ADC converted values,
use the HAL_ADC_GetValue() function.
4. Stop the ADC peripheral using
HAL_ADC_Stop().
HAL_ADC_Start(&hadc1); //ADC Start here
HAL_ADC_PollForConversion(&hadc1,10); //wait here until conversion done
value_adc=HAL_ADC_GetValue(&hadc1); //Digital value read here!
|
|
مثال) خطوط
کد زیر این روند را در برنامه نشان میدهند. مقدار دیجیتال در متغیر Value_adc
ریخته میشود:
Ø
آزمایش اول را انجام دهید.
8ـ1ـ3ـ روش وقفه(Interrupt)
برای خواندن مقدار ADC با استفاده از روش وقفه دیگر برنامه بلاک نمیشود و به محض پایان
یافتن تبدیل، تابع وقفه(HAL_ADC_ConvCpltCallback()) اجرا میشود و مقدار ADC در این تابع با استفاده از دستور HAL_ADC_GetValue()
قابل خواندن است.
نکته: برای استفاده از این روش باید وقفهی مربوط به واحدهای
ADC از قسمت NVIC
Setting فعال گردد.
نکته: برای هر تبدیل، تابع HAL_ADC_Start_IT() باید
فراخوانی شود.
1. Start the ADC peripheral using HAL_ADC_Start_IT().
2. At ADC end of conversion HAL_ADC_ConvCpltCallback()
function is executed and user can add his own code by customization of
function pointer HAL_ADC_ConvCpltCallback()
3. To read the ADC converted values,
use the HAL_ADC_GetValue() function.
4. Stop the ADC peripheral using
HAL_ADC_Stop_IT()
v آزمایش دوم را انجام دهید.
8ـ1ـ4ـ روش انتقال از طریق DMA
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image061.jpg)
واحد DMA برای انتقال مستقیم مقدار دیجیتال محاسبه شده توسط واحد ADC به حافظه
است. در این روش CPU آزاد است و بدون اینکه درگیر شود، مقدار ADC بر روی حافظه
ذخیره میشود.
مد نمونه برداری پیوسته: در این مد به محض اینکه مبدل انالوگ به دیجیتال
شروع به کار کرد بعد از هر اتمام تبدیل(EOC) دوباره نمونه برداری را آغاز میکند
و نیازی به start دوبارهی آن نیست. برای فعال کردن این مد در تنظیمات STM32CubeMX باید
گزینهی continues conversion mode را فعال کنید. نمودار حالت این مد در شکل زیر آمدهاست:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image062.jpg)
تنظیمات نرم افزاری STM32CubeMX برای استفاده از DMA در مد نمونه
برداری پیوسته مانند شکل زیر است:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image063.jpg)
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image064.jpg)
1. Start the ADC peripheral using
HAL_ADC_Start_DMA(), at this stage the user specify the length of data to be
transferred at each end of conversion.
2. At The end of data transfer by
HAL_ADC_ConvCpltCallback() function is executed and user can add his own code
by customization of function pointer HAL_ADC_ConvCpltCallback.
3. Stop the ADC peripheral using
HAL_ADC_Stop_DMA().
1-
با استفاده از کانال دوم واحد DAC که در
دستورکار شماره7 با آن آشنا شدید. برنامهای بنویسید که واحد ADC با استفاده
از روش سرکشی مقدار تولید شده توسط DAC را بخواند. مقدار دیجیتال DAC هر یک میلیثانیه افزایش پیدا کند و
به بیشترین مقدار(4095) که رسید، صفر شود و دوباره این فرایند ادامه پیدا کند.
مقدار ADC را در نرم
افزار STMStudio مشاهده کنید. برای نمایش بهتر مقدار دیجیتال نوع نمایش را بر روی Curve قرار
دهید و تنظیمات زیر را انجام دهید:
![](/DorsaPax/userfiles/Sub108/1dastor/rezpar/image067.jpg)
یادآوری: برای شروع نمایش دادهها
از فلش سبزرنگ بالای workspace استفاده کنید.
2-
قسمت ADC آزمایش یک را با استفاده از روش وقفه انجام دهید.
3-
قسمت ADC آزمایش یک را با استفاده از روش انتقال از طریق DMA انجام دهید.