Bu yazımda
STM32F4 Discovery ile ADC kullanımı anlatacağım. Uygulamayı Keil Uvision 5
derleyicisi ve Standart Peripheral Kütüphanesini kullanarak yapacağım. STM32F4’te
ADC 6-bit 8-bit 10-bit ve 12-bit çözünürlüklerde dönüşüm yapabilir. 6-bit en
düşük hasasiyete 12-bit ise en yüksek hassasiyete sahiptir. STM32F4’te 3 ADC ve herbirine bağlı 16 channel bulunmaktadır.
ADC’lerin pinleri aşağıdaki tabloda gösterilmektedir. Seçeceğimiz channel ve ADC’ye göre tabloda
belirtilen çıkışa potansiyometre bağlayacağız. Bu ugulamada ADC 2’yi Kullanacağız.
ADC’yi ve A
portunu kullanmak için öncelikle ADC’nin ve Bportunun bulunduğu clock hatlarını
enable etmemiz yani aktifleştimemiz gerekmektedir. Bunun için Stm32f4xx_rcc.c dosyasından ADC’nin ve B
portunun hangi clock hattına bağlı olduklarına bakıyoruz. ADC 2
APB2 ve B portu AHB1 clock hatlarına bağlı olduğu için bu
hatları(bus) aktifleştiriyoruz.
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); |
Potansiyometre bağlayacağımız PA0 portunun
konfigürasyon ayarlarlamalarını yapıyoruz
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); |
PA1-PA5 portunu led çıkışları olarak
kullanacağız.
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStruct.GPIO_OType =GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); |
| ADC_InitTypeDef ADC_InitStruct; ADC_CommonInitTypeDef ADC_CommonInitStruct; ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div4;ADC_CommonInit(&ADC_CommonInitStruct); ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruct.ADC_ExternalTrigConv = ENABLE; ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStruct.ADC_NbrOfConversion = 1; ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; ADC_InitStruct.ADC_ScanConvMode = DISABLE; ADC_Init(ADC1, &ADC_InitStruct);
ADC_Cmd(ADC1, ENABLE);
|
ADC datalarını okumak için ADC_Read() fonksiyonunu kullanıcaz.
uint16_t ADC_Read(void) { ADC_SoftwareStartConv(ADC1);//ADC'nin dönüşümünü başlatıyor while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Dönüşüm bitene kadar bekliyor return ADC_GetConversionValue(ADC1); } |
ADC ve Port ayarlamalarını tamamladık. Yazdığımız bu kodları birleştirererk main programını yazacağız. ADC'ye gelen 0 - 5V voltaja göre ADC 0 - 4095 arasında bir sayı değeri üretecektir. Programımızda artan ADC değerine göre sırasıyla ledleri yakacağız.
#include "stm32f4xx.h" uint16_t ADC_Read(void) { ADC_SoftwareStartConv(ADC2); while (!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC)); return ADC_GetConversionValue(ADC2); } int main() { uint16_t ADC_Data; GPIO_InitTypeDef GPIO_InitStruct; ADC_InitTypeDef ADC_InitStruct; ADC_CommonInitTypeDef ADC_CommonInitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); GPIO_InitStruct.GPIO_Mode =GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStruct.GPIO_OType =GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_OType =GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd= GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div4; ADC_CommonInit(&ADC_CommonInitStruct); ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; ADC_InitStruct.ADC_ScanConvMode = DISABLE; ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruct.ADC_NbrOfConversion = 1; ADC_Init(ADC2, &ADC_InitStruct); ADC_Cmd(ADC2, ENABLE); while(1) { ADC_Data = ADC_Read(); if(ADC_Data<=700) { GPIO_ResetBits(GPIOA, GPIO_Pin_1); GPIO_ResetBits(GPIOA, GPIO_Pin_2); GPIO_ResetBits(GPIOA, GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_5); } else if( 700 <ADC_Data && ADC_Data <= 1400) { GPIO_SetBits(GPIOA, GPIO_Pin_1); GPIO_ResetBits(GPIOA, GPIO_Pin_2); GPIO_ResetBits(GPIOA, GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_5); } else if( 1400 <ADC_Data && ADC_Data <= 2100) { GPIO_SetBits(GPIOA, GPIO_Pin_1); GPIO_SetBits(GPIOA, GPIO_Pin_2); GPIO_ResetBits(GPIOA, GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_5); } else if( 2100 <ADC_Data && ADC_Data <= 2800) { GPIO_SetBits(GPIOA, GPIO_Pin_1); GPIO_SetBits(GPIOA, GPIO_Pin_2); GPIO_SetBits(GPIOA, GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_5); } else if( 2800 <ADC_Data && ADC_Data <= 3500) { GPIO_SetBits(GPIOA, GPIO_Pin_1); GPIO_SetBits(GPIOA, GPIO_Pin_2); GPIO_SetBits(GPIOA, GPIO_Pin_3); GPIO_SetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_5); } else { GPIO_SetBits(GPIOA, GPIO_Pin_1); GPIO_SetBits(GPIOA, GPIO_Pin_2); GPIO_SetBits(GPIOA, GPIO_Pin_3); GPIO_SetBits(GPIOA, GPIO_Pin_4); GPIO_SetBits(GPIOA, GPIO_Pin_5); } } } |
Bağlantılarımızı aşağıdaki gibi yapıyoruz. PA0
Potansiyometrenin orta bacağına
diğer uçları 5V ve GND'ye bağlıyoruz
PA0 -> Potansiyometre
PA1
-> LED1
PA2
->
LED2
PA3
->
LED3
PA4
->
LED4
PA5
->
LED5
Hiç yorum yok:
Yorum Gönder