#include "main.h" /* Простейшее сглаживание амплитуды (IIR), чтобы картинка не "скакала". Это как раз про замечание из файла: сначала конвертация, потом сглаживание. */ static uint8_t SmoothAmplitude(uint8_t new_amp) { /* Храним в расширенном виде, чтобы было плавнее */ static uint16_t filt = 0u; uint16_t target; target = (uint16_t)new_amp * 256u; /* alpha = 1/8: filt += (target - filt)/8 */ filt = (uint16_t)(filt + (uint16_t)((int32_t)target - (int32_t)filt) / 8); return (uint8_t)((filt + 128u) / 256u); } int main(void) { uint16_t adc_avg; uint8_t amp_raw; uint8_t amp_smooth; uint8_t amp_last; SystemInit(); /* 1) GPIO: PA4 DAC OUT, PA5 ADC IN */ GPIO_Init_All(); /* 2) ADC для потенциометра (PA5) */ ADC1_PA5_Init(); /* 3) DAC + DMA + TIM2 TRGO */ DAC1_Init_All(); /* Сначала базовый синус */ SineBase_Init(); /* Стартовая амплитуда = 0 */ amp_last = 255u; /* чтобы первое обновление точно произошло */ SineBuffer_Update(0u); DMA1_For_DAC1_Init(g_dac_buffer, (uint32_t)SINE_POINTS); /* 100 кГц обновление -> 1 кГц синус при 100 точках */ TIM2_TRGO_Init((uint32_t)DAC_UPDATE_HZ); while (1) { /* Читаем потенциометр */ adc_avg = ADC1_ReadAverage(16u); /* Конвертация в 0..100 (не напрямую в волну!) */ amp_raw = ADC_To_Amplitude_0_100(adc_avg); /* Сглаживаем, чтобы не дрожало */ amp_smooth = SmoothAmplitude(amp_raw); /* Чтобы не пересчитывать буфер каждую итерацию без надобности, обновляем только если изменилось заметно */ if (amp_smooth != amp_last) { amp_last = amp_smooth; SineBuffer_Update(amp_smooth); } } }