آموزش STM32 با توابع LL قسمت دهم: مبدل آنالوگ به دیجیتال (ADC)

آموزش ARM

در قسمت نهم از آموزش STM32 با توابع LL، ابتدا چالش بخش Receive یا همان دریافت دیتا در پروتکل UART را بررسی کردیم و در نهایت با استفاده از بهترین روشی که ذکر کردیم، یعنی روش وقفه، این بخش را به صورت عملی بر روی برد راه‌اندازی کردیم.

در این قسمت می‌خواهیم در رابطه با ADC یا همان مبدل آنالوگ به دیجیتال در میکروکنترلرهای STM32 صحبت کنیم.

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

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

این مقدمه را از این جهت گفتم که اگر با یک سیستمی که ظاهرا تمام دیجیتال به نظر می‌رسد برخورد کردید، این نکته را در نظر داشته باشید که تبدیل آنالوگ به دیجتال آن، از قبل توسط افراد دیگری انجام شده است، و شما فقط دارید از بخش دیجیتال آن استفاده می‌کنید.

اما موضوع مورد بحث ما در این مقاله، آن مواقعی است که نیاز است خودمان تبدیل آنالوگ به دیجیتال را انجام بدهیم، و در اینجا مشخصا منظورمان از این تبدیل آنالوگ به دیجیتال، (analog-to-digital converter) ADC یا مبدل آنالوگ به دیجیتال می‌باشد.

 

(ADC) analog-to-digital converter

مبدل آنالوگ به دیجیتال، یا همان ADC عنصری است که یک سیگنال آنالوگ را به عنوان ورودی دریافت می‌کند، و در خروجی معادل دیجیتال همان سیگنال آنالوگ را تولید می‌کند.

برای ساخت ADC روش‌های ساخت مختلفی وجود دارد، اما عملکرد همه‌ی این روش‌ها یکسان است. یعنی تبدیل یک سیگنال آنالوگ به یک سیگنال دیجیتال.

هر کدام از این روش‌ها و در کل خود ADC دارای جزئیات بسیار زیادی هستند و از حوصله این مقاله خارج است که بخواهیم تمامی این جزئیات را شرح بدهیم، چون هدف ما به کار گیری ADC در میکروکنترلرهای STM32 است، نه اینکه بخواهیم مشخصا ADC را مورد بررسی قرار بدهیم.

اما نگران نباشید، تمامی آن نکاتی که ضروری است و نیاز است که شما برای درک عملکرد ADC آن‌ها را بدانید، را در ادامه شرح خواهیم داد.

سیگنال دیجیتال و آنالوگ
سیگنال دیجیتال و آنالوگ

در تصویر بالا دو سیگنال به رنگ آبی و قرمز مشاهده می‌کنید که سیگنال آبی، سیگنال آنالوگ، و سیگنال قرمز، معادل دیجیتال شده‌ی همین سیگنال آبی یا سیگنال آنالوگ است.

اما این تبدیل چگونه انجام می‌شود؟

همانطور که گفتیم با استفاده از روش‌های مختلفی در بازه‌های زمانی یکسان از سیگنال آنالوگ، نمونه‌برداری می‌شود. حال سوال اینجا است که این نمونه‌ها از چه جنسی هستند و در نهایت این نمونه‌ها به چه شکلی در می‌آیند.

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

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

 

کوانتیزاسیون

برای اینکه با مفهوم کوانتیزاسیون بهتر آشنا شوید، ابتدا به تصویر زیر دقت کنید:

مقدار واقعی و مقدار اندازه‌گیری شده توسط ADC و مفهوم کوانتیزاسیون
مقدار واقعی و مقدار اندازه‌گیری شده توسط ADC و مفهوم کوانتیزاسیون

در تصویر بالا می‌بینید که مقدار اندازه‌گیری شده توسط ADC، کمی با مقدار واقعی متفاوت است. در این موقع می‌گوییم که مقدار آنالوگ به معادل دیجیتال آن کوانتیزه شده است. و به اختلاف بین مقدار واقعی با مقدار کوانتیزه شده خطای کوانتیزاسیون می‌گویند.

افزایش بیت‌های کوانتیزاسیون می‌تواند خطا را کاهش دهد و به دقت ADC کمک کند تا در نهایت مقدار دیجیتال اندازه‌گیری شده به مقدار واقعی آنالوگ نزدیک‌تر شود.

تاثیر افزایش بیت‌های کوانتیزاسیون را در ادامه توضیح خواهم داد.

تاثیر افزایش بیت‌های کوانتیزاسیون در ADC
تاثیر افزایش بیت‌های کوانتیزاسیون در ADC

در تصویر بالا دو ADC با 3 و 4 بیت کوانتیزاسیون داریم. همانطور که از قبل گفتیم و در تصویر نیز مشخص است اگر در یک بازه از یک سیگنال آنالوگ نمونه بگیریم، فقط می‌تواند به یکی از پلکان موجود تبدیل شود.

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

 

رزولوشن

احتمالا مفهمومی به اسم رزولوشن را شنیده باشید. حال که با مفهوم کوانتیزاسیون آشنا شدیم بهتر است در همینجا رزولوشن را هم تعریف کنیم.

در واقع به تعداد بیت‌های کوانتیزاسیون، رزولوشن گفته می‌شود. با توجه به تعریفی که از کوانتیزاسیون کردیم قابل درک است که به تبع آن رزولوشن هم معیاری از دقت باشد و هر چه تعداد بیت‌های کوانتیزاسیون یا رزولوشن بیشتر باشد، دقت بهتری خواهیم داشت.

البته رزولوشن تعاریف دیگری نیز دارد، اما همه‌ی این تعاریف مفهوم یکسانی دارند و ما سعی کردیم مرسوم‌ترین تعریف رزولوشن که در ADCها به کار می‌رود را بیان بکنیم.

 

فرکانس نمونه‌برداری

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

هر کدام از پارامترهای رزولوشن و فرکانس نمونه‌برداری بسیار مهم هستند و به عنوان دو مشخصه مهم در ADCها باید به آن‌ها توجه بشود. برای اینکه بدانید تاثیر افزایش رزولوشن و فرکانس نمونه‌بردای بر روی سیگنال چگونه است ابتدا به تصویر زیر دقت کنید:

تاثیر افزایش رزولوشن و نرخ نمونه‌برداری

در تصویر بالا یک سیگنال آنالوگ با رزولوشن و فرکانس نمونه‌برداری مشخص وجود دارد، در پایین تصویر، در سمت راست و سمت چپ به ترتیب رزولوشن و فرکانس نمونه‌برداری افزایش پیدا کرده است.

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

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

حالا فرض کنید ما برای نیاز خودمان می‌خواهیم ADC مناسبی انتخاب کنیم. معیار صحیح برای انتخاب رزولوشن و فرکانس نمونه‌برداری مناسب چیست؟

 

انتخاب رزولوشن و فرکانس نمونه‌برداری

برای انتخاب رزولوشن باید محدوده ولتاژ سیگنال ورودی و کمترین مقداری که نیاز است اندازه بگیریم، را در نظر بگیریم تا رزولوشن مناسب را بدست آوریم.

رابطه بین خروجی دیجیتال ADC، ولتاژ ورودی، ولتاژ رفرنس و رزولوشن به صورت زیر است:

رابطه بین خروجی دیجیتال ADC، ولتاژ ورودی، ولتاژ رفرنس و رزولوشن
رابطه بین خروجی دیجیتال ADC، ولتاژ ورودی، ولتاژ رفرنس و رزولوشن

برای بدست آوردن حداقل مقدار قابل اندازه‌گیری توسط ADC باید Digital output را در فرمول بالا برابر با عدد 1 قرار بدهید.

برای انتخاب فرکانس نمونه‌برداری هم باید شبیه به رزولوشن یک سری پارامتر را در نظر بگیریم تا فرکانس نمونه‌برداری مناسب را بدست آوریم.

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

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

اجازه بدهید قانون نایکوئیست را کمی دقیق‌تر بیان بکنم.

 

قضیه نایکوئیست

بر اساس قانون نایکوئیست، برای اینکه بتوان یک سیگنال پیوسته با پهنای باند محدود را پس از نمونه‌برداری از روی نمونه‌ها بازسازی کرد، فرکانس نمونه‌برداری از سیگنال، باید حداقل دو برابر فرکانس خود سیگنال باشد.

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

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

خب این تمامی آن نکات لازمی بود که شما باید برای درک عملکرد ADC می‌دانستید. شما با دانستن نکاتی که ذکر شد به طور کامل عملکرد ADC را درک می‌کنید و دیگر نیازی به ذکر جزئیات بیشتر نیست.

اکنون می‌خواهیم ویژگی‌های ADC در میکروکنترلرهای STM32 را بررسی بکنیم.

 

ADC در میکروکنترلرهای STM32

تمامی پارامترهایی که در بالا برای ADC ذکر کردیم برای ADCهای نهفته در میکروکنترلرهای STM32 نیز صادق است و در ادامه فقط مشخصات و امکانات اضافه‌ای که در ADC میکروکنترلرهای STM32 وجود دارد را بررسی می‌کنیم.

این ADC از نوع Successive approximation یا همان تقریب متوالی است که دارای رزولوشن 12 بیت و 18 کانال مالتی پلکس است. از این کانال‌های مالتی پلکس، 16 کانال به صورت خارجی و 2 کانال به صورت داخلی است که یکی از این کانال‌های داخلی به سنسور دما موجود در میکروکنترلر متصل است.

دقت کنید که ما با استفاده از یک ADC می‌توانیم، 18 کانال ورودی را به صورت مالتی پلکس بخوانیم، نه اینکه 18 عدد ADC وجود داشته باشد.

کانال‌های ورودی ADC در میکروکنترلر STM32
کانال‌های ورودی ADC در میکروکنترلر STM32

همانند تصویر بالا در نهایت یکی از کانال‌های ورودی از Analog MUX عبور کرده و برای نمونه‌برداری به ADC متصل می‌شود.

این ADC به صورت خودکار کالیبره می‌شود و تبدیل سیگنال را انجام می‌دهد، و پس از اینکه تبدیل به پایان رسید، فلگ EOC مقدارش 1 می‌شود و ما از پایان تبدیل با خبر خواهیم شد. همچنین نتیجه تبدیل به صورت یک عدد 12 بیتی که در یک رجیستر 16 بیتی ذخیره خواهد شد.

یک امکان دیگر که در این ADC اضافه شده است، وجود وقفه هنگام اتمام کار تبدیل است. اگر این وقفه فعال باشد، هنگام رخداد وقفه ما به زیر روال وقفه رفته و مقدار رجیستر دیتا را می‌خوانیم و دیگر نیاز نیست که فلگ EOC را مدام بررسی کنیم.

کلاک ورودی به واحد ADC نباید از 14MHZ بیشتر باشد و اگر از این مقدار بیشتر باشد مقدار نمونه‌گیری شده توسط ADC اشتباه است.

طبق گفته دیتاشیت حداقل زمانی که طول می‌کشد تا یک نمونه تبدیل شود برابر با 1µs است، یعنی حداکثر نرخ نمونه‌برداری، 1Ms/s است. البته یک امکان دیگر که وجود دارد، استفاده از حالت Fast است که در این حالت نرخ نمونه‌برداری به 2Ms/s افزایش می‌یابد.

در ADC میکروکنترلر STM32، برای نمونه‌بردای از یک سیگنال آنالوگ و تبدیل آن به یک نمونه دیجیتال، یک زمان ثابت و یک زمان متغیر داریم.

ابتدا به فرمول زیر دقت کنید:

Tconv = Sampling time + 12.5 cycles

همانطور که از فرمول مشخص است، 12.5 سیکل به علاوه یک زمان Sampling time، کل زمانی است که یک تبدیل انجام می‌شود. Sampling time می‌تواند 8 مقدار متفاوت داشته باشد که این 8 مقدار با توجه به یک عدد 3 بیتی در رجیستر ADC_SMPR، مانند زیر مشخص می‌شود.

000: 1.5 cycles
001: 7.5 cycles
010: 13.5 cycles
011: 28.5 cycles
100: 41.5 cycles
101: 55.5 cycles
110: 71.5 cycles
111: 239.5 cycles

با توجه به مقادیر بالا، کمترین مقدار Sampling time برابر با 1.5 سیکل است، که این عدد بیشترین سرعت تبدیل یعنی همان 1Ms/s را به ما می‌دهد.

اگر کلاک ADC برابر با 14MHz باشد، آنگاه داریم:

Tconv = 1.5 + 12.5 = 14 cycles = 1 µs

امکانات بسیار زیادی به صورت سخت‌افزاری در کنار ADC میکروکنترلرهای STM32 وجود دارد. این امکانات می‌توانند قابلیت‌های بسیار زیادی به ما بدهند که باعث می‌شوند تا حد زیادی حجم پردازشی را از دوش نرم‌افزار بردارند.

یکی از این امکانات وجود مُدهای کاری مختلف است که به ما امکان می‌دهد در حالت‌های بسیار زیادی از ADC استفاده بکنیم بدون اینکه بخواهیم در نرم‌افزار تنظیمات خاصی را اعمال کنیم. در ادامه بیشتر با این مُدهای کاری آشنا خواهیم شد.

 

مُدهای کاری ADC در میکروکنترلرهای STM32

در یک ADC، سه مُد کاری Continuous ،Single و Scan وجود دارد که خود مُد Scan شامل Single و Continuous می‌شود. البته این مدهای کاری فقط برای یک ADC هست. با توجه به یک سری پارامتر دیگر و اینکه از یک ADC استفاده می‌کنیم یا دو ADC مُد‌های کاری دیگری نیز وجود دارد، اما همین سه مُد ذکر شده در بالا مُدهای اصلی هستند. که در ادامه به توضیح این مُدها می‌پردازیم.

مُد Single: از این مُد زمانی استفاده می‌شود که بخواهیم فقط یک بار، یک نمونه از یک کانال را تبدیل بکنیم. این کانال می‌تواند توسط نرم‌افزار یا یک تریگر خارجی فعال بشود. در این مُد باید فلگ CONT برابر با 0 باشد.

مُد Continuous: از این مُد زمانی استفاده می‌شود که بخواهیم به صورت پیوسته یک کانال را تبدیل بکنیم. این کانال می‌تواند توسط نرم‌افزار یا یک تریگر خارجی فعال بشود. در این مُد باید فلگ CONT برابر با 1 باشد.

مُد Scan: این مُد زمانی استفاده می‌شود که بخواهیم چندین کانال ورودی آنالوگ را به صورت گروهی اسکن کنیم. این مُد هم می‌تواند با مُد Single و هم با مُد Continuous ترکیب بشود.

 

کانال‌های Regular و Injected

کانال‌های Regular و Injected در میکروکنترلر STM32
کانال‌های Regular و Injected در میکروکنترلر STM32

کانال‌های ورودی، پس از عبور از مالتی پلکسر به دو گروه کانال‌های Regular و Injected تقسیم می‌شوند. این دو گروه از همان امکاناتی است که قبلا گفتیم به ما قابلیت‌هایی می‌دهند که حجم پردازشی نرم‌افزار کمتر بشود. با وجود این امکانات ما دارای قدرت انتخاب و انعطاف بیشتری خواهیم بود.

ما می‌توانیم چندین کانال را در گروه Regular و چندین کانال دیگر را در گروه Injected قرار بدهیم و تفاوت بین کانال‌های Regular و Injected در اولویت بین آن‌هاست که در ادامه این تفاوت اولویت را مفصلا شرح می‌دهم.

اگر حالت Triggered injection فعال باشد، ابتدا کانال‌هایی که در گروه Regular هستند، با توجه به آن ترتیبی که از قبل تعیین کردیم، شروع به تبدیل شدن می‌کنند. حال اگر در حین تبدیل شدن کانال‌های Regular، یک تریگر Injected رخ بدهد، کانال اخیری که در حال تبدیل شدن بود ریست می‌شود و کانال‌های گروه Injected با توجه به ترتیبی که دوباره از قبل تعیین کرده بودیم شروع به تبدیل شدن می‌کنند. پس از اینکه تبدیل کانال‌های گروه Injected به پایان رسید، تبدیل کانال‌های گروه Regular، از همان جایی که قطع شد، از سر گرفته می‌شود.

توجه کنید که در حالت Triggered injection اگر در حین تبدیل گروه Injected، یک تریگر Regular رخ بدهد هیچ اثری نخواهد داشت. پس می‌توانیم نتیجه بگیریم که در این حالت اولویت با کانال‌های گروه Injected است.

حال اگر حالت Auto-injection فعال باشد، کانال‌های گروه Injected به صورت اتوماتیک پس از کانال‌های گروه Regular شروع به تبدیل شدن می‌کنند. در این حالت باید تریگر Injected غیر فعال باشد و همچنین اگر فلگ CONT برابر با 1 باشد، این چرخه مدام تکرار می‌شود.

پس می‌توانیم نتیجه بگیریم که در این حالت اولویت با کانال‌های گروه Regular است.

در واقع با توجه به اینکه کدام مُد کاری فعال است، اولویت بین Regular و Injected می‌تواند متفاوت باشد.

خب تا اینجا توضیحات مربوط به مُدهای مختلف را بیان کردم، در ادامه می‌خواهیم مقدار یک کانال ADC را در حالت Continuous راه‌اندازی کنیم.

نحوه‌ی کار به این صورت است که ابتدا یک کانال ADC را در حالت Continuous راه‌اندازی می‌کنیم و در تابع وقفه ADC، مقدار ولتاژ پین میکروکنترلر که 3.3 ولت است را می‌خوانیم. سپس مقدار خوانده شده که به صورت یک عدد دیجیتال بین 0 تا 4095 است را با استفاده از فرمول تناسبی که قبلا گفتیم به یک عدد بین 0 تا 3.3 ولت تبدیل کرده و در نهایت این عدد را با استفاده از UART برای کامپیوتر می‌فرستیم تا نتیجه را بر روی کامپیوتر مشاهده بکنیم.

اجازه بدهید بقیه مراحل را در نرم‌افزار توضیح بدهم.

در نرم‌افزار STM32CubeMX از قسمت Analog، مانند تصویر زیر، ADC1 را تنظیم می‌کنیم:

تنظیمات ADC در نرم‌افزار STM32CubeMX
تنظیمات ADC در نرم‌افزار STM32CubeMX

کانال 0 را فعال کرده، Continuous Conversion Mode را Enable و Sampling time را بر روی 1.5 سیکل تنظیم می‌کنیم، سایر تنظیمات را به صورت پیش‌فرض باقی می‌گذاریم.

همچنین از قسمت NVIC Settings، وقفه مربوط به ADC را فعال می‌کنیم تا بتوانیم دیتای ADC را از طریق وقفه بخوانیم.

فعال کردن وقفه ADC در نرم‌افزار STM32CubeMX

پریفرال UART را هم مانند قسمت هشتم فعال کرده و برای ادامه‌ی کار به نرم‌افزار Keil می‌رویم.

قبل از هر کاری ابتدا درون فایل main متغیرهای زیر را تعریف می‌کنیم:

volatile uint16_t ADC_Value;
float Voltage;
char str[21];
uint8_t i = 0;

سپس درون main برنامه کدهای زیر را می‌نویسیم:

LL_ADC_Enable(ADC1);
LL_ADC_EnableIT_EOS(ADC1);
LL_ADC_IsCalibrationOnGoing(ADC1);
LL_ADC_REG_StartConversionSWStart(ADC1);

کدهای بالا ابتدا ADC و وقفه‌اش را فعال، سپس ADC را کالیبره و در نهایت کار تبدیل را آغاز می‌کند.

تابع LL_ADC_REG_StartConversionSWStart برای زمانی است که ما نمی‌خواهیم از تریگر خارجی استفاده کنیم و ADC به صورت نرم‌افزاری برای عمل تبدیل فعال می‌شود.

سپس به فایل stm32f1xx_it می‌رویم و در تابع وقفه ADC، کد زیر را می‌نویسیم:

void ADC1_2_IRQHandler(void)
{
  /* USER CODE BEGIN ADC1_2_IRQn 0 */
	ADC_Value = LL_ADC_REG_ReadConversionData12(ADC1);
  /* USER CODE END ADC1_2_IRQn 0 */

  /* USER CODE BEGIN ADC1_2_IRQn 1 */

  /* USER CODE END ADC1_2_IRQn 1 */
}

تنها کاری که ما در تابع ADC1_2_IRQHandler انجام می‌دهیم، خواندن مقدار ADC با استفاده از تابع LL_ADC_REG_ReadConversionData12 است.

همچنین توجه داشته باشید که کلاس متغیر ADC_Value از نوع volatile است که باید در فایل stm32f1xx_it به صورت extern و با کلاس volatile تعریف شود تا به آن دسترسی داشته باشیم.

در نهایت درون حلقه while برنامه هم کد زیر را می‌نویسم:

Voltage = (float)(ADC_Value * 3.3) / (4095);
sprintf(str, "Voltage is: %0.2f\r\n", Voltage);
for (i; i<19; i++)
{
	LL_USART_TransmitData8(USART1, str[i]);
	while(!LL_USART_IsActiveFlag_TXE(USART1));			
}
i = 0;

LL_mDelay(500);

کد بالا ابتدا مقدار دریافتی از ADC، که یک عدد دیجیتال بین 0 تا 4095 است را به عددی بین 0 تا 3.3 ولت تبدیل می‌کند. سپس این عدد را با استفاده از تابع sprintf به رشته تبدیل کرده و در نهایت با استفاده از UART و یک مبدل USB به سریال، این رشته را برای کامپیوتر می‌فرستد.

برای اینکه بتوانیم نتیجه را بر روی کامپیوتر بهتر مشاهده کنیم، 500 میلی ثانیه تاخیر به انتهای کد اضافه کردیم.

پس از ارسال رشته str نتیجه زیر را بر روی کامپیوتر مشاهده خواهیم کرد:

ولتاژ اندازه‌گیری شده توسط ADC
ولتاژ اندازه‌گیری شده توسط ADC

در قسمت یازدهم در رابطه با مبدل دیجیتال به آنالوگ (DAC) صحبت خواهیم کرد.

کانال تلگرام آرملینکس

برای دسترسی به کانال تلگرام و دانلود فایل‌های پروژه و ویدئو، بر روی دکمه زیر کلیک کنید:

4 دیدگاه دربارهٔ «آموزش STM32 با توابع LL قسمت دهم: مبدل آنالوگ به دیجیتال (ADC)»

    1. سلام علیرضا. در حال مرتب کردن فایل‌ها هستم، به زودی آن‌ها را در کانال تلگرام قرار می‌دهم.

  1. سلام، روز بخیر.
    موارد گفته شده را برای STM32F407 انجام دادم، اما ارور invalin in c99 را برای تابع های زیر میدهد. چگونه ارور ها را رفع کنم؟ سپاس.

    LL_ADC_EnableIT_EOS(ADC1);
    LL_ADC_IsCalibrationOnGoing(ADC1);

دیدگاه‌ خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

اسکرول به بالا