Open Thermaltake opened 1 year ago
Была попытка привести инициализация таймера к такому виду
TIM_TypeDef *tim = TIM3;
RCC_TypeDef *rcc = RCC;
rcc->APB1RSTR |= (0x1U << (1U)); /* 0x00000002 = put Timer 3 into the reset state */
rcc->APB1RSTR &= ~(0x1U << (1U)); /* release Timer 3 */
rcc->APB1ENR |= (0x1U << (1U)); // Разрешаем тактирование таймера 3
tim->CR1 = BIT(7); // 1: TIMx_ARR register is buffered.
tim->CR2 = 0;
tim->PSC = 0; // Предделитель генерирует частоту 72 МГц
tim->ARR = 90 - 1 + 50; // Перегрузка таймера каждые 1.25 мкс
tim->CCMR1 = 0
+ LSHIFT(6, 12) // TIM_CCMR1_OC2M: Output compare 3 mode | 110: PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT<TIMx_CCR1 else inactive.
+ LSHIFT(1, 11) // TIM_CCMR1_OC2PE: Output compare 3 preload enable
+ LSHIFT(0, 8) // TIM_CCMR1_CC2S: Capture/Compare 3 selection | 00: CC3 channel is configured as output
;
tim->CNT = 0;
tim->CCR2 = 0;
tim->DIER = BIT(10); // Bit 11 CC3DE: Capture/Compare 3 DMA request enable. Разрешаем запросы DMA
tim->CR1 |= BIT(0); // Запускаем таймер
tim->CCER = BIT(4); // Разрешаем работы выхода, чтобы возникали сигналы для DMA
и инициализацию dma
DMA_Stream_TypeDef *dma_ch = DMA1_Stream5;
RCC_TypeDef *rcc = RCC;
rcc->AHB1ENR |= BIT(21); // Разрешаем DMA1 bit 21
dma_ch->CR = 0; // Выключаем стрим
dma_ch->PAR = (unsigned int)&(TIM3->CCR2) + 1; // Назначаем адрес регистра данных ADC
dma_ch->M0AR = (unsigned long)&DMA_buf;
dma_ch->NDTR = (LEDS_NUM + 2) * COLRS * 8;
dma_ch->CR =
LSHIFT(5, 25) + // CHSEL[2:0]: Channel selection | 010: channel 2 selected
LSHIFT(0, 23) + // MBURST: Memory burst transfer configuration | 00: single transfer
LSHIFT(0, 21) + // PBURST[1:0]: Peripheral burst transfer configuration | 00: single transfer
LSHIFT(0, 19) + // CT: Current target (only in double buffer mode) | 0: The current target memory is Memory 0 (addressed by the DMA_SxM0AR pointer)
LSHIFT(0, 18) + // DBM: Double buffer mode | 0: No buffer switching at the end of transfer
LSHIFT(3, 16) + // PL[1:0]: Priority level | 11: Very high. PL[1:0]: Priority level
LSHIFT(0, 15) + // PINCOS: Peripheral increment offset size | 0: The offset size for the peripheral address calculation is linked to the PSIZE
LSHIFT(1, 13) + // MSIZE[1:0]: Memory data size | 00: 8-bit. Memory data size
LSHIFT(1, 11) + // PSIZE[1:0]: Peripheral data size | 00: 8-bit. Peripheral data size
LSHIFT(1, 10) + // MINC: Memory increment mode | 1: Memory address pointer is incremented after each data transfer (increment is done according to MSIZE)
LSHIFT(0, 9) + // PINC: Peripheral increment mode | 0: Peripheral address pointer is fixed
LSHIFT(1, 8) + // CIRC: Circular mode | 1: Circular mode enabled
LSHIFT(1, 6) + // DIR[1:0]: Data transfer direction | 01: Memory-to-peripheral
LSHIFT(0, 5) + // PFCTRL: Peripheral flow controller | 1: The peripheral is the flow controller
LSHIFT(1, 4) + // TCIE: Transfer complete interrupt enable | 1: TC interrupt enabled
LSHIFT(0, 3) + // HTIE: Half transfer interrupt enable | 0: HT interrupt disabled
LSHIFT(0, 2) + // TEIE: Transfer error interrupt enable | 0 : TE interrupt disabled
LSHIFT(0, 1) + // DMEIE: Direct mode error interrupt enable | 0: Direct mode error interrupt disabled
LSHIFT(0, 0) + // EN: Stream enable | 1: Stream enabled
0;
dma_ch->FCR =
LSHIFT(0, 7) + // FEIE: FIFO error interrupt enable
LSHIFT(1, 2) + // DMDIS: Direct mode disable | 1: Direct mode disabled. Разрешаем чтобы была возможность пересылки из байт в двухбайтовый регистр
LSHIFT(1, 0) + // FTH[1:0]: FIFO threshold selection | 01: 1/2 full FIFO
0;
dma_ch->CR |= BIT(0); // 1: Stream enabled
Это опираясь на документацию по таймерам, но не сработало.
Пытаюсь запустить работу на другом выводе, например, pb5. Сменил на TIM3, Канал 2, DMA1_Stream5. Но не запускается.
TIM_TypeDef *tim = TIM3;
DMA_Stream_TypeDef *dma_ch = DMA1_Stream5;
dma_ch->PAR = (unsigned int)&(TIM3->CCR3) + 1; // Назначаем адрес регистра данных ADC
По остальным значениям пробовал по документации менять, но ничего не заработало.stm32f401ccu6 . На pb8 работало, но с перезагрузкой таймера 139.