Indemsys / ws2812b-protocol-on-STM32-without-empty-loops

MIT License
3 stars 4 forks source link

Как запустить на другом выводе? #1

Open Thermaltake opened 1 year ago

Thermaltake commented 1 year ago

Пытаюсь запустить работу на другом выводе, например, 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.

Thermaltake commented 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

Это опираясь на документацию по таймерам, но не сработало.