Пт мар 11, 2022 23:11:36
Пт мар 11, 2022 23:28:36
Сб мар 12, 2022 07:36:36
Сб мар 12, 2022 11:31:14
Сб мар 12, 2022 11:36:58
Сб мар 12, 2022 11:40:04
Сб мар 12, 2022 11:48:36
Сб мар 12, 2022 11:52:15
Сб мар 12, 2022 11:59:17
Сб мар 12, 2022 12:11:25
Сб мар 12, 2022 12:17:01
Сб мар 12, 2022 12:29:50
Сб мар 12, 2022 13:36:29
Сб мар 12, 2022 14:01:50
Сб мар 12, 2022 15:04:46
Ложим в прерывании ДМА, половинка и полный, 300к с лихуем отсчетов, и без синхронизации и таймеров, хоть синус хоть меандр хоть ШИМ, а далее хоть трумс хоть среднее хоть квадратное.Eddy_Em писал(а):Нужно хотя бы сотню сэмплов на период: тогда и почистить от шума получится, и даже True RMS измерить, если не синусоидальный сигнал.
Сб мар 12, 2022 15:30:13
Сб мар 12, 2022 17:03:51
stm32f030f4p6Eddy_Em писал(а):Это ж сколько оперативы нужно на 300 тысяч отсчетов? Где ты видел недорогой STM32 с мегабайтом ОЗУ?
С чего это ты взял?Eddy_Em писал(а):если тупо делать непрерывные измерения, невозможно гарантировать, что они имеют равноотстоящие отсчеты по времени.
И это с чего?Eddy_Em писал(а):Да и промежутки между измерениями неизвестны с нужной точностью.
А для чего ее мерить, особенно сетевые 50Гц?Eddy_Em писал(а):Частоту не измеришь.
Сб мар 12, 2022 17:19:44
void init(void) {
DBGMCU->CR |= DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP;
RCC->AHBENR = RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOFEN | RCC_AHBENR_DMAEN | RCC_AHBENR_SRAMEN; // All GPIO + DMA, Enable SRAM during sleep mode.
<...>
// ADC
ADC1->CR = ADC_CR_ADCAL; // Run calibration
while (ADC1->CR & ADC_CR_ADCAL) {}; // Wait till done
ADC1->CR = ADC_CR_ADEN; // Enable ADC
ADC1->SMPR = 4; // 41.5 ADC clocks to aquire voltage
delay_ms(2);
ADC1->CR = ADC_CR_ADEN | ADC_CR_ADSTART;
while ((ADC1->ISR & ADC_ISR_EOC) == 0) {};
ADC_Value = (ADC1->DR * 1730) / 1000;
// ADC DMA
SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_ADC_DMA_RMP;
DMA1_Channel1->CCR = DMA_CCR_PL_0 | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_TCIE;
DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR);
DMA1_Channel1->CNDTR = Len;
DMA1_Channel1->CMAR = (uint32_t)&(Samples);
NVIC_SetPriority(DMA1_Channel1_IRQn, 7);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
// TIM1 Update used as TRGO (Trigger Out)
TIM1->CR2 = TIM_CR2_MMS_1;
// 16MHz / 2500 = 6400Hz -> 80ms to 512 samples
// 20MHz / 6400Hz = 3125 -1 = 3124, but... let it bee~ in run time.
TIM1->ARR = (SystemCoreClock / 6400) - 1;
TIM1->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
// ----------
};
int main (void) {
<...>
init();
while (1) {
<...> main loop code
// ----------
ADC1->CR = ADC_CR_ADDIS; // Disable ADC
while (ADC1->CR & ADC_CR_ADEN) {}; // Wait till OFF
ADC1->CFGR1 = ADC_CFGR1_EXTEN | ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_DISCEN;
ADC1->CHSELR = (1 << 2); // Channel 2 [Radio ADC]
ADC1->CR = ADC_CR_ADEN; // Enable ADC
while (!(ADC1->ISR & ADC_ISR_ADRDY)); // Wait till ready.
TIM1->CR1 |= TIM_CR1_CEN;
ADC1->ISR = 0x1F; // Clear flags.
ADC1->CR = ADC_CR_ADSTART; // Required!
DMA1_Channel1->CNDTR = Len;
DMA1_Channel1->CCR |= DMA_CCR_EN;
// ----------
<...>
__WFI();
#define Len 512
volatile short Samples[Len] __attribute ((aligned (4)));
void DMA1_Channel1_IRQHandler(void) {
DMA1->IFCR = 0x0000000F; // Clear ALL bits.
DMA1_Channel1->CCR &= ~DMA_CCR_EN;
TIM1->CR1 &= ~TIM_CR1_CEN;
ADC_Samples_Ready = 1;
};
Сб мар 12, 2022 17:53:49
Сб мар 12, 2022 21:21:07