Hello, everyone.
I have a little problem with the PWM on a STM32L475
It seems that an incoming UART message resets the PWM, but only if the PWM is currently in HighLevel.
Background. I have implemented the PWM once by interrupt and once by DMA request. The goal should be to set a GPIO port via the BSRR register. The PWM works with a frequency of 20 kHz and 100 ticks. On PORTD i have connected Mosfets to switch the Batteryvoltage in high and low level.
In the interrupt configuration the high level is set by a function in the config callback (update event) and the low level by a function in the callback of the capture compare register interrupt.
In the DMA variant two uint32_t variables are sent per DMA request, once at the update event to the BSRR register of the port and once at the channel event.
In both cases the TIM8 is used in the PWM configuration Interrupts high prio and in the DMA configuration TIM8_UP and TIM_8_CH4 on the DMA2 streams 1 and 2.
The USART1 DMA Streams are also on DMA2 but i have also change it to DMA1. Same result
In this picture below i change the dutycycle from 25% to 50% and send UART messages. you can see the first four periods are on low level and everything is fine. After that The message comes in at High level PWM and reset the Period ( red line)
Thanks!
Hardware PWM issues
Moderators: RoccoMarco, barthess
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: Hardware PWM issues
Hi,
It is not very clear to me.
Are your DMA channels programmed in circular mode? without that the DMA would stop after the 1st transfer.
Giovanni
It is not very clear to me.
Are your DMA channels programmed in circular mode? without that the DMA would stop after the 1st transfer.
Giovanni
Re: Hardware PWM issues
Hey Giovanni,
yes the DMA should be correctly programmed. And works fine. Only if a message is incomming from USART1 and the PWM is High, that looks like reset the PWM.
Here are the DMA configs to load stuff into the BSRR of PortD
PWM Defines:
PWM channel config:
DMA configuration
yes the DMA should be correctly programmed. And works fine. Only if a message is incomming from USART1 and the PWM is High, that looks like reset the PWM.
Here are the DMA configs to load stuff into the BSRR of PortD
PWM Defines:
Code: Select all
/*******************************************************
* Defines
******************************************************/
#ifndef PERIPHERY_INC_PWM_H_
#define PERIPHERY_INC_PWM_H_
#define PWM_PERIOD 100U
#define PWM_FREQUENCY 15000U
#define PWM_SERIAL_POS 0x990066 // values for BSRR on Port D
#define PWM_BYPASS_POS 0xAA0055 // values for BSRR on Port D
#define PWM_SERIAL_NEG 0x660099 // values for BSRR on Port D
#define PWM_BYPASS_NEG 0x5500AA // values for BSRR on Port D
PWM channel config:
Code: Select all
static PWMConfig pwmcfg = {
(PWM_PERIOD*PWM_FREQUENCY), //test with 12,5kHz (100000U), 10kHz are (80000U), old: (125000U), /* goal: 15,625kHz PWM width (Corresponding to AFE clock). (PWM frequency * period) should give that value. */
PWM_PERIOD, /* PWM period width is 8 ticks. With the frequency of 125000 Hz from above this gives the desired 15,625kHz */
NULL,
{
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL}
},
0, // cr2 register - usually zero
.dier = TIM_DIER_UDE| TIM_DIER_CC4DE,
};
DMA configuration
Code: Select all
uint32_t g_pwm_bsrr_buffer_cc[1] = {PWM_BYPASS_POS};
uint32_t g_pwm_bsrr_buffer_up[1] = {PWM_SERIAL_POS};
void stabl_TIM8_DMA_init(void){
//Configure DMA Stream DMA2 Channel 1 TIM8_UP
const stm32_dma_stream_t* dma_up = dmaStreamAlloc(STM32_DMA_STREAM_ID(2, 1), 10, NULL, NULL);
const stm32_dma_stream_t* dma_cc = dmaStreamAlloc(STM32_DMA_STREAM_ID(2, 2), 10, NULL, NULL);
//use CaptureCompare Register 4 from TIM8
dmaStreamSetPeripheral(dma_up, &(GPIOD->BSRR));
dmaStreamSetPeripheral(dma_cc, &(GPIOD->BSRR));
// link BSRR Framebuffer to DMA Memory
dmaStreamSetMemory0(dma_up, g_pwm_bsrr_buffer_up);
dmaStreamSetMemory0(dma_cc, g_pwm_bsrr_buffer_cc);
// configure Trasmission Size
dmaStreamSetTransactionSize(dma_up, 1);
dmaStreamSetTransactionSize(dma_cc, 1);
//Set config Register: Channel 1 TIM8_UP | Circular Mode | Memory to Peripherie |
// Peripherie & Memorysize 32 Bit | Priority very High
dmaStreamSetMode(dma_up,
STM32_DMA_CR_CHSEL(7) | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD |
STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
//Set config Register: Channel 2 TIM8_CH4 | Circular Mode | Memory to Peripherie |
// Peripherie & Memorysize 32 Bit | Priority very High
dmaStreamSetMode(dma_cc,
STM32_DMA_CR_CHSEL(7) | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD |
STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
// Start DMA
dmaStreamEnable(dma_up);
dmaStreamEnable(dma_cc);
}
Who is online
Users browsing this forum: No registered users and 21 guests