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

0
45
مبدل آنالوگ به دیجیتال (ADC)‍‍‍
مبدل آنالوگ به دیجیتال (ADC)

در قسمت یازدهم آموزش میکروکنترلر STM8 راه اندازی LCD کاراکتری توسط میکروکنترلر STM8 را آموزش دادیم. در این قسمت از مجموعه مقالات آموزش میکروکنترلر STM8 قصد داریم مبحث مهم و کاربردی مبدل آنالوگ به دیجیتال (ADC) را آموزش دهیم. با ما همراه باشید.

مبدل آنالوگ به دیجیتال (ADC):

گاهی لازم‌است ورودی آنالوگ به میکروکنترلر داده‌شود و این ورودی مورد‌پردازش قرار‌گیرد. در میکروکنترلرهای مدرن امروزی مبدل آنالوگ به دیجیتال (ADC) قابلیت‌مهمی به‌شمار می‌آید. برای خواندن خروجی آنالوگ از سنسورها، اندازه‌گیری ولتاژ و غیره از ADC استفاده میشود. برای‌مثال، ما می‌توانیم از یک ADC برای خواندن سنسور دمای LM35 استفاده‌کنیم. ولتاژ خروجی سنسور متناسب با درجه حرارت است و ما می‌توانیم از اطلاعات ولتاژ برای محاسبه دما استفاده‌کنیم. میکروکنترلر STM8 دارای چندین کانال و بلوک ADC است. به‌عنوان‌مثال، STM8S3F3 دارای ۵کانال و یک بلوک ADC است. ADC میکروکنترلر STM8 نیز مانند ADC دیگر میکروکنترلرهاست. تنها چند ویژگی اضافی دارد. شکل‌زیر نشانگر بلوک ADC میکروکنترلر STM8 است:

بلوک ADC میکروکنترلر STM8
بلوک ADC میکروکنترلر STM8

 

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

  • امپدانس ورودی باید کمتر از ۱۰kΩ باشد.
  • بهتر است کلاک ADC را در حدود ۴مگاهرتز یا کمتر قراردهید.
  • اشیمیت تریگر باید غیرفعال شود.
  • درصورت امکان، از بافر ورودی و مدار فیلتر استفاده‌کنید.
  • اگر ADC دارای پین رفرنس باشد، این پین باید به یک رفرنس دقیق مانند LM336 متصل‌شود. توصیه می‌شود از یک تراشه رگولاتور LDO مناسب استفاده‌کنید.
  • پین‌های ADC که مورداستفاده قرار نمی‌گیرند باید غیرفعال یا پیکربندی شوند. این کار باعث کاهش مصرف‌برق خواهدشد.
  • خواندن ADC باید در فواصل زمانی منظم و ثابت باشد تا از نوسانات زمانی در خواندن ADC جلوگیری‌شود.
  • برای افزایش پایداری بهتر است از بیت‌های سمت راست (بیت‌های پرارزش ADC) استفاده‌کنید تا تأثیرات نویز را حذف نمایید.
  • فاصله ترک‌های PCB / سیم‌ها به کانال‌های ADC باید کوتاه باشد تا نویز را کاهش‌دهند.

اتصالات سخت افزاری

اتصالات سخت افزاری
اتصالات سخت افزاری

 

کد نمونه ADC

#include "STM8S.h"
#include "STM8S_lcd.h"


void clock_setup(void);
void GPIO_setup(void);
void ADC1_setup(void);
void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value);


void main()
{
int j;
unsigned int A0 = 0x0000;

clock_setup();
GPIO_setup();
ADC1_setup();

LCD_init(); 
LCD_clear_home(); 

LCD_goto(4, 0);
LCD_putstr("STM8 ADC");
LCD_goto(4, 1);
LCD_putstr("A0");

while(TRUE)
{
ADC1_StartConversion();
while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == FALSE);

A0 = ADC1_GetConversionValue();
ADC1_ClearFlag(ADC1_FLAG_EOC);

lcd_print(8, 1, A0);
for(j=0;j<9000;j++);
};
}


void clock_setup(void)
{
CLK_DeInit();

CLK_HSECmd(DISABLE);
CLK_LSICmd(DISABLE);
CLK_HSICmd(ENABLE);
while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);

CLK_ClockSwitchCmd(ENABLE);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);

CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, 
DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
}


void GPIO_setup(void)
{
GPIO_DeInit(GPIOD);
GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_FL_NO_IT);

GPIO_DeInit(GPIOC);

GPIO_DeInit(GPIOB);
}


void ADC1_setup(void)
{
ADC1_DeInit(); 

ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, 
ADC1_CHANNEL_4,
ADC1_PRESSEL_FCPU_D18, 
ADC1_EXTTRIG_GPIO, 
DISABLE, 
ADC1_ALIGN_RIGHT, 
ADC1_SCHMITTTRIG_CHANNEL4, 
DISABLE);

ADC1_Cmd(ENABLE);
}


void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value)
{
char chr = 0x00;

chr = ((value / 1000) + 0x30); 
LCD_goto(x_pos, y_pos);
LCD_putchar(chr); 

chr = (((value / 100) % 10) + 0x30);
LCD_goto((x_pos + 1), y_pos);
LCD_putchar(chr); 

chr = (((value / 10) % 10) + 0x30);
LCD_goto((x_pos + 2), y_pos);
LCD_putchar(chr); 

chr = ((value % 10) + 0x30);
LCD_goto((x_pos + 3), y_pos);
LCD_putchar(chr); 
}

 

توضیحات

در ابتدا، باید کلاک ماژول ADC را فعال‌کنیم:

CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);

 

در مرحله دوم، باید پین ADC را به‌عنوان یک GPIO شناور بدون‌وقفه تنظیم‌کنیم.

GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_FL_NO_IT);

 

برای راه‌اندازی ADC به اطلاعاتی درمورد کانال ADC موردنظر نیاز است:

void ADC1_setup(void)
{
ADC1_DeInit(); 

ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, 
ADC1_CHANNEL_4,
ADC1_PRESSEL_FCPU_D18, 
ADC1_EXTTRIG_GPIO, 
DISABLE, 
ADC1_ALIGN_RIGHT, 
ADC1_SCHMITTTRIG_CHANNEL4, 
DISABLE);

ADC1_Cmd(ENABLE);
}

 

خط‌دوم تابع فوق بیان میکند که ما قصد داریم از کانال ADC 4 (PD3) بدون هیچ اشمیت تریگری استفاده‌کنیم. همچنین نمی‌خواهیم از تریگرهای خارجی ماژول GPIO استفاده‌کنیم. از آنجاکه کلاک اصلی در ۸مگاهرتز درحال‌اجرا است، ADC با تقسیم کلاک اصلی / کلاک ADC فرکانس نمونه‌برداری ۴۴۴کیلوهرتز را دریافت میکند.همچنین میخواهیم از حالت تبدیل مستمر استفاده‌کنیم زیرا میخواهیم به‌طورمداوم ورودی ADC را بخوانیم و نمی‌خواهیم آن را در فواصل خاص اندازه‌گیری کنیم. درنهایت استفاده‌از بیت‌های سمت راست ADC باعث می‌شود مقدار پایدارتری داشته‌باشیم.

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

ADC1_StartConversion();
while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == FALSE);

A0 = ADC1_GetConversionValue();
ADC1_ClearFlag(ADC1_FLAG_EOC);

 

بقیه کد مربوط‌به چاپ داده‌های ADC برروی LCD است.

چاپ داده‌های ADC برروی LCD
چاپ داده‌های ADC برروی LCD

 

در قسمت سیزدهم قصدداریم تایمر نگهبان آنالوگ (AWD) را آموزش‌دهیم. در ادامه آموزش‌های میکروکنترلر STM32 ما را همراهی کنید.

 

 

منبع:‌سیسوگ

برای این مقاله نظر بگذارید:

لطفا دیدگاه خود را بنویسید
لطفا نام خود را وارد کنید