8. ünite / 11 · yaklaşık 4 saat
ADC ve DMA
12 bit dönüşüm, örnekleme süresi, tarama kipi; işlemci yerine veriyi taşıyan DMA, dairesel tampon ve yarım/tam aktarım.
Bu ünitenin sonunda
- Gerilimi 12 bitlik ADC koduna ve geri çevirmek; örnekleme süresinin etkisini açıklamak
- Tarama kipinde birden çok kanalın örnekleme hızını hesaplamak
- DMA'nın işlemciyi nasıl rahatlattığını ve dairesel kipin nasıl çalıştığını göstermek
- Yarım ve tam aktarım kesmeleriyle çift tampon kurmak ve taşmayı önlemek
Ders notları
STM32F4'ün ADC'si 12 bitliktir: 0–3,3 V aralığını 4096 basamağa böler, bir basamak ≈ 0,8 mV. Pin önce analog kipe alınır (MODER = 11). Dönüşüm iki aşamadır: örnekleme (iç kondansatör girişe şarj olur) ve çevirme (12 çevrim). Kaynağın direnci büyükse (LDR bölücüsü, uzun kablo) kondansatör tam şarj olamaz; daha uzun örnekleme süresi seçilir.
Neden DMA?
Saniyede 100 000 örnek alıp her biri için kesmeyle işlemciye "oku" demek, işlemcinin zamanının çoğunu yer. DMA (doğrudan bellek erişimi) denetleyicisi veriyi çevre biriminden belleğe işlemci olmadan taşır. Dairesel kipte tampon sonuna gelince başa döner; DMA iki kesme üretir:
- HT (yarım aktarım): tamponun ilk yarısı doldu; DMA şimdi ikinci yarıya yazıyor, işlemci ilk yarıyı işleyebilir.
- TC (tam aktarım): ikinci yarı doldu; DMA başa döndü.
Bu, çift tamponlamadır (ping-pong). Kural: işlemci bir yarıyı, DMA öbür yarıyı doldurmadan bitirmelidir; yoksa veri işlenirken üzerine yazılır (overrun).
Gürültü
Yarım tamponun ortalaması basit ve etkili bir alçak geçiren süzgeçtir. Analog besleme (VDDA) ve toprak düzeni de en az yazılım kadar önemlidir.
Simülasyon
ADC + DMA: dairesel tampon ve yarım/tam aktarım
ADC her dönüşümde DMA ile tampona yazar. Yarım (HT) ve tam (TC) aktarım kesmelerinde işlemci bitmiş yarıyı işler. İşleme süresini uzat ve taşmanın (overrun) nerede başladığını gör.
Kendin dene
DMA simülasyonunda 16 hücreli tampon ve 10 µs örnekleme ile işleme süresini 50 µs'ye ayarla: HT ve TC sırasını izle. İşleme süresini 80 ve 120 µs'ye çıkar: taşma hangi değerde başlıyor ve neden yarı tampon süresiyle ilgili? Tamponu 64 hücreye büyütüp tekrar dene.
Kod
#define N 64
static uint16_t buf[N]; /* DMA buraya yazar */
volatile uint32_t avg_lo, avg_hi;
void adc_start(void) {
/* CubeMX: ADC1 IN0 (PA0), sürekli kip, DMA2 Stream0 dairesel, yarım kelime */
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)buf, N);
}
static uint32_t mean(const uint16_t *p, int n) { uint32_t s = 0; for (int i = 0; i < n; i++) s += p[i]; return s / n; }
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *h) { avg_lo = mean(buf, N / 2); } /* DMA ikinci yarıya yazıyor */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *h) { avg_hi = mean(buf + N / 2, N / 2); } /* DMA başa döndü */
/* mV = code * 3300 / 4096 */Sık yapılan hatalar
- Pini analog kipe almadan ADC okumak: değer anlamsız gelir.
- Yüksek dirençli kaynağı en kısa örnekleme süresiyle okumak: değer gerçeğin altında çıkar.
- DMA tamponunu yerel (yığında) değişken yapmak: fonksiyon dönünce DMA başka verinin üzerine yazar.
- Önbellekli çekirdeklerde (M7) DMA tamponunun önbellek tutarlılığını unutmak.
Yazılım mühendisliği bağlantısı
DMA ile işlemci arasındaki sözleşme zamana bağlıdır: işleme süresi bütçesi yarı tampon süresidir.
- İşleme süresini DWT çevrim sayacıyla ölç ve bir testte bütçeyle karşılaştır.
- Süzgeç ve ölçekleme kodunu saf fonksiyon yapıp kayıtlı ADC verisiyle bilgisayarda test et.
Kendini sına
12 bit ADC, Vref = 3,3 V. 1,65 V hangi koda karşılık gelir?
Dairesel DMA'da HT kesmesi geldiğinde işlemci ne yapmalı?
Yarı tampon 80 µs'de doluyorsa işleme süresi için koşul?
DMA tamponu neden yerel değişken olmamalı?
Bu üniteden sonra bitirme projesinde
- Ölçüm ve güvenlik: ADC + DMA ile motor akımı (ya da potansiyometre) ölçümü, aşırı akımda durdurma, buton ile acil dur (EXTI).