Приветствую всех!
Вопрос по работе затертого уже всеми давно до дыр stm32f103 в части связки PWM + DMA
Обратился бывший коллега - задача проста, выдавать в PWM аналоговый сигнал, при чем больше
частота PWM - тем лучше.
Частоты CPU 72000000 PWM 400000 - разрешение получается 180 отсчетов CPU.
Выдаем четыре отсчета в кольцевом режиме
Код
mas_sin[0]=160; //!!!!!!!!!!! если здесь заменить на 170 то увидим сдвиг
mas_sin[1]=90;
mas_sin[2]=30;
mas_sin[3]=10;
Наблюдаемый эффект: при небольшом заполнении PWM все хорошо, при приближении заполнения к 100%
- импульс дублируется в следующий, следующий сдвигается в третий, а третий "выпадает"...
Не поверил я что может быть неописанная засада в таком не сложном деле.
Он прислал код. Я проверил и упростил код до минимального "сбоящего" варианта без кучи ненужностей.
Далее собственно полный (не длинный ) код
CODE
// задаем частоты - выдернуто из SystemClock_Config();
FLASH->ACR= LL_FLASH_LATENCY_2;
RCC->CR|= RCC_CR_HSEON;
while ((RCC->CR&RCC_CR_HSERDY)!=(RCC_CR_HSERDY));
RCC->CFGR=(LL_RCC_PLLSOURCE_HSE_DIV_1 & (RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE)) | LL_RCC_PLL_MUL_9;
RCC->CR|=RCC_CR_PLLON;
while((RCC->CR&RCC_CR_PLLRDY)!=RCC_CR_PLLRDY);
RCC->CFGR|=LL_RCC_SYSCLK_DIV_1;
RCC->CFGR|=LL_RCC_SYS_CLKSOURCE_PLL;
while (RCC->CFGR& RCC_CFGR_SWS!= LL_RCC_SYS_CLKSOURCE_STATUS_PLL);
RCC->CFGR|=LL_RCC_APB1_DIV_2;
RCC->CFGR|=LL_RCC_APB2_DIV_1;
mas_sin[0]=160; //!!!!!!!!!!! если здесь заменить на 170 то увидим сдвиг
mas_sin[1]=90;
mas_sin[2]=30;
mas_sin[3]=10;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG;
AFIO->MAPR |= AFIO_MAPR_TIM3_REMAP_PARTIALREMAP | AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
GPIOB->CRL &= ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1;
GPIOB->CRL |= GPIO_CRL_CNF4_1 | GPIO_CRL_MODE4_0 | GPIO_CRL_CNF5_1 | GPIO_CRL_MODE5_0 | GPIO_CRL_CNF0_1 | GPIO_CRL_MODE0_0 | GPIO_CRL_CNF1_1 | GPIO_CRL_MODE1_0;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;
TIM3->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE;
TIM3->CCMR2 |= TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3PE | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4PE;
TIM3->CCMR2 |= TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC3M_1;
TIM3->DIER |= TIM_DIER_CC1DE | TIM_DIER_CC3DE;
TIM3->CR1 |= TIM_CR1_CEN | TIM_CR1_ARPE;
TIM3->PSC = 0;
TIM3->ARR = PREC-1;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel2->CPAR = (uint32_t)&TIM3->CCR3;
DMA1_Channel2->CMAR = (uint32_t)&mas_sin[0];
DMA1_Channel2->CNDTR = POINTS;
DMA1_Channel2->CCR = DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_DIR | DMA_CCR_EN | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0;
while(1);
когда mas_sin[0]==160 видим следующую картинку

но если заполнить еще чуть больше mas_sin[0]==170
то будет вот так:

Долго смотрел в картинку схемы работы узла Capture/Compare -

Может быть запись из DMA по событию совпадения CCR3 == CNT совпадает с событием UEV и пропускается? при этом релоад регистр не переписывается в теневой?
Но с этим должны были столкнуться десятки и сотни?
Не подскажет ли уважаемое сообщество, отчего не едут лыжи.
Заранее спасибо.