مبدل آنالوگ به دیجیتال میکروکنترلرهای LPC1768

0
23
مبدل آنالوگ به دیجیتال میکروکنترلرهای LPC1768
مبدل آنالوگ به دیجیتال میکروکنترلرهای LPC1768

در این جلسه به برسی مبدل آنالوگ به دیجیتال lpc17xx_adc.h می‌پردازیم.

مبدل آنالوگ به دیجیتال میکروکنترلرهای LPC1768
مبدل آنالوگ به دیجیتال میکروکنترلرهای LPC1768

مبدل آنالوگ به دیجیتال یا 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
  • نکته : حداکثر کلاک قابل اتصال به واحد مبدل آنالوگ به دیجیتال 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 را غیر فعال می‌کنه.

مثال راه‌اندازی 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

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

مبدل آنالوگ به دیجیتال میکروکنترلرهای LPC1768
مبدل آنالوگ به دیجیتال میکروکنترلرهای LPC1768

 

 

منبع:  میکرودیزاینرالکترونیک

 

مطلب قبلیترمیستور چیست؟
مطلب بعدیآموزش راه‌اندازی LDR با آردوینو

پاسخ دهید

لطفا نظر خود را وارد کنید!
لطفا نام خود را در اینجا وارد کنید