خانه / میکروکنترلرها / میکروکنترلر های ARM / مطالب آموزشی میکروکنترلرهای ARM / آموزش میکروکنترلرهای LPC1768 جلسه ششم: مبدل آنالوگ به دیجیتال lpc17xx_adc.h

 

آموزش میکروکنترلرهای LPC1768 جلسه ششم: مبدل آنالوگ به دیجیتال lpc17xx_adc.h

اگر جلسات قبلی آموزش میکروکنترلرهای LPC1768 را دنبال کرده باشید میدانید که در جلسه قبلی پورت های ورودی و خروخی LPC1768 را برسی کردیم و یادگرفتیم چطوری پورت ها را بعنوان ورودی/ خروجی تعریف کنیم و مقادیر را روی آنها بنویسیم و یا بخوانیم و همه این کارها را با توابع CMSIS انجام دادیم. در این جلسه به برسی مبدل آنالوگ به دیجیتال lpc17xx_adc.h می پردازیم.

مبدل آنالوگ به دیجیتال lpc17xx_adc.h

مبدل آنالوگ به دیجیتال یا ADC چیست ؟

فرض کنید یک سنسور دما مانند LM35 داریم که به ازای هر درجه سانتی گراد 10mV خروجی دارد.مثلا اگر دما 1درجه سانتیگراد باشد ولتاژ خروجی سنسور 10mV میشه. برای اینکه مقدار دمای این سنسور را بصورت دیجیتالی(روی سون سگمنت ، نمایشگر ال_سی_دی و..) نمایش دهیم باید این مقدار آنالوگ را به دیجیتال تبدیل کنیم.

آیسی های مبدل آنالوگ به دیحیتال یا ADC این کار را برای ما انجام میدهند. روی میکروکنترلرهای ARM و خیلی دیگر از میکروکنترلرها یک ADC نسبتا خوب پیش بینی شده که در موارد زیادی میتواند کارراه انداز باشد.

مشخصات ADC میکروکنترلر LPC1768

  • دقت 12 بیتی (هر مقدار آنالوگ در 12 بیت ذخیره میشود.)
  • بازه یا محدوده اندازه گیری از VREFN تا VREFP میباشد.
  • دارای حالت کاهش توان میباشد.
  • ورودی این ADC مالتی پلکس شده روی 8 پین از پورت های ورودی/خروجی میکروکنترلر
  • سرعت نمونه برداری 200KSPS یا 200000 نمونه در ثانیه
  • هر کانال ورودی دارای یک رجیستر مخصوص جهت نگهداری آخرین وضعیت

مراحل تنظیم و راه اندازی ADC

  1. فعال سازی بیت توان از قسمت ادوات جانبی از رجیستر PCONP
  2. فعال سازی بیت PDN در رجیستر AD0CR
  3. تنظیم کلاک ADC با بیت های 24 و 25 در رجیستر PCLKSEL0
  4. انتخاب حالت ADC برای پین های مورد نظر از رجیستر های PINSEL
  5. تنظیم وقفه های ADC
حتما در ادامه این مطلب را هم بخوانید:  معرفی معماری RISC در پردازنده های ARM

نکته : حداکثر کلاک قابل اتصال به واحد مبدل آنالوگ به دیجیتال 13مگاهرتز میباشد.

نکته : دقت یا رزولیشن مبدل برابر است با 0.8mV

پایه های ADC روی میکروکنترلر

دو نوع پایه روی میکروکنتلر برای ADC وجود دارد یکی پایه های تغذیه و رفرنس (VDDA,VSSA.VREFN,VREFP) دیگری پایه های کانال ها از ADC0[0-7]

پایه های رفرنس و تغذیه ADC روی میکروکنترلر باید به ولتاژ مناسب وصل شود.معمولا VREFP را به VDD و VREFN را به GND  وصل میکنن و همچنین پایه های تغذیه VDDA را به 3.3 ولت و VSSA را هم به زمین وصل میکنن.

پین های کانال های ADC
کانال ADC
پورت و پین
عملکرد های دیگر پین
AD0 P0.23 0-GPIO, 1-AD0[0], 2-I2SRX_CLK, 3-CAP3[0]
AD1 P0.24 0-GPIO, 1-AD0[1], 2-I2SRX_WS, 3-CAP3[1]
AD2 P0.25 0-GPIO, 1-AD0[2], 2-I2SRX_SDA, 3-TXD3
AD3 P0.26 0-GPIO, 1-AD0[3], 2-AOUT, 3-RXD3
AD4 P1.30 0-GPIO, 1-VBUS, 2- , 3-AD0[4]
AD5 P1.31 0-GPIO, 1-SCK1, 2- , 3-AD0[5]
AD6 P0.3 0-GPIO, 1-RXD0, 2-AD0[6], 3-
AD7 P0.2 0-GPIO, 1-TXD0, 2-AD0[7], 3-

توابع کار با ADC در داخل lpc17xx_adc.h

تابع ADC_Init

این تابع برای پیکربندی اولیه ADC ، اتصال کلاک و تنظیم فرکانس ADC

void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t rate);

وروی های تابع :

اولی باید LPC_ADC باشه (اشاره گر از نوع LPC_ADC_TypeDef )

دومی فرکانس کاری ADC میباشد که حداکثر میتونه 200000 باشه

تابع ADC_IntConfig

تنظیم وقفه ADC

void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState);

ورود اول که باید LPC_ADC باشه

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

حتما در ادامه این مطلب را هم بخوانید:  واحد کنترل اینتراپت بخش سوم(آخر)

ورودی سوم برای فعال سازی یا غیر فعال سازی وقفه مربوطه هست که با SET فعال و با RESET غیر فعال میشه.

تابع ADC_ChannelCmd

void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState);

این تابع کانال های ADC را فعال یا غیر فعال میکنه.

ورود اول که باید LPC_ADC باشه 🙂

ورودی دوم شماره کانال

ورودی سوم فعال و غیر فعال سازی با ENABLE فعال و با DISABLE غیر فعال میشه

تابع ADC_StartCmd

void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode);

ورود اول که باید LPC_ADC باشه

ورودی دوم حالت نمونه برداری میباشد که میتونه پیوسته نمونه برداری کنه و یا فقط یک نمونه برداره و موارد دیگر که در زیر همه موارد هستن و عملکرد هر کدام را میتونید تحقیق کنید و ما فعلا با ADC_START_NOW کار کنیم و بعدا میریم سراغ بقیه.

*                 – ADC_START_CONTINUOUS
*                 – ADC_START_NOW
*                 – ADC_START_ON_EINT0
*                 – ADC_START_ON_CAP01
*                – ADC_START_ON_MAT01
*                – ADC_START_ON_MAT03
*                – ADC_START_ON_MAT10
*                – ADC_START_ON_MAT11

تابع ADC_ChannelGetStatus

FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType);

این تابع وضعیت پرچم تبدیل های انجام شده را میخونه

ورودی اول تابع که LPC_ADC هست

ورودی دوم تابع شماره کانال

ورودی سوم تابع ، اگر یک باشه پرچم DONE را میخونه و اگر 0 باشه پرچم BURST را میخونه.

تابع ADC_ChannelGetData

uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel);

این تابع مقدار ADC را میخونه

ورودی اول LPC_ADC است

ورودی دوم شماره کانال مورد نظر میباشد

تابع ADC_DeInit

void ADC_DeInit(LPC_ADC_TypeDef *ADCx)

این تابع هم ADC را غیر فعال میکنه.

حتما در ادامه این مطلب را هم بخوانید:  فیلم های آموزشی میکروکنترلرهای ARM

مثال راه اندازی ADC میکروکنترلرLPC1768

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

نکته دوم اینکه همانطور که میدانید شاید یک پین میکروکنترلر چندین عملکرد داشته باشد که در جلسه قبلی بحث کردیم.برای انتخاب حالت ADC  عملکرد پین مورد نظر از کتابخونه lpc17xx_pinsel.h استفاده میکنیم که در زیر نحوه پیکر بندی آن آمده است.

پین استفاده شده AD0[5] میباشد. که روی پایه P1[31] قرار دارد.

//begin pinsel confing
	PINSEL_CFG_Type PinCfg;
	PinCfg.Funcnum = 3;
	PinCfg.OpenDrain = PINSEL_PINMODE_NORMAL;
	PinCfg.Pinmode = PINSEL_PINMODE_TRISTATE;
	PinCfg.Pinnum = 31;
	PinCfg.Portnum = 1;
	PINSEL_ConfigPin(&PinCfg);
	 //end pinsel confing

مثال :

#include "lpc17xx.h"
#include "lpc17xx_adc.h"
#include "lpc17xx_pinsel.h"
#include "debug_frmwrk.h"


 void delay(void){
  uint32_t i=0;
  for(i=0;i<9999999;i++);
 }
uint16_t read_adc(adc_channel_number)
{
//this function writed by Melec.ir	 
	uint16_t adc_value;

	//adc init
	ADC_Init(LPC_ADC, 100000);
	//adc interrupt DISABLE
	ADC_IntConfig(LPC_ADC,adc_channel_number,DISABLE);
	//adc channel on
	ADC_ChannelCmd(LPC_ADC,adc_channel_number,ENABLE);

		// Start conversion
		ADC_StartCmd(LPC_ADC,ADC_START_NOW);
		//Wait conversion complete
		while (!(ADC_ChannelGetStatus(LPC_ADC,adc_channel_number,ADC_DATA_DONE)));
		//read adc channel
		adc_value = ADC_ChannelGetData(LPC_ADC,adc_channel_number);
	return adc_value;
}


int main (void){
    uint16_t V;
	//begin pinsel confing
	PINSEL_CFG_Type PinCfg;
	PinCfg.Funcnum = 3;
	PinCfg.OpenDrain = PINSEL_PINMODE_NORMAL;
	PinCfg.Pinmode = PINSEL_PINMODE_TRISTATE;
	PinCfg.Pinnum = 31;
	PinCfg.Portnum = 1;
	PINSEL_ConfigPin(&PinCfg);
	 //end pinsel confing 
	 SystemInit();
	 	debug_frmwrk_init();
		
		while(1){

		V=read_adc(5);
		  
		_DBG("ADC= ");
	   	_DBD32(V);
		_DBG("\n");
		delay();
		}

   return 1;
 }

برای راحتی کار یک تابع به اسم uint16_t read_adc(adc_channel_number) نوشتن ورودی آن شماره کانال و خروجی آن مقدار ADC میباشد. بطور مثال در کد بالا با فراخوانی   V=read_adc(5)  مقدار ولتاژ روی کانال 5 را میریزه داخل متغیر V و با توابع  _DBG مقدار تابع را میفرستیم روی پورت  UART0

خروجی روی پورت سریال

مبدل آنالوگ به دیجیتال lpc17xx_adc.h

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

ادامه آموزش ها را از ایجا بخوانید.

درباره ی جهاندیده

با سلام درود به شما که مطالب سایت خودتان را مطالعه می کنید امیدوارم مطالب سایت برایتان مفید باشد و باعث پیشرفت روز افزون شما شود. دوران راهنمایی در کار منتاژ کیت های الکترونیکی بودم تا رفتم هنرستان ^_^ دو سال هنرستان الکترونیک خیلی چیزها یاد گرفتم ! دو سال کاردانی الکترونیک و کارشناسی ICT گرایش بهره برداری از سیستم های مخابراتی پر از تجربه بود و مدتی است در الکترونیک دنیای مشغولم . الکترونیک – تکنولوژی – ICT ، برنامه نویسی …

2 دیدگاه

  1. مطمئن هستین کد درست هست.
    مثلا تو قسمت uint16_t read_adc(adc_channel_number) نباید type آرگمان ورودی مشخص بشه؟
    کامپایلر من keil هست و خطا میگیره از برنامه شما .

پاسخ دهید

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