STM32F4 PWM and interrupt with the same timer - c

I have a STM32F407x. Is it possible to have a PWM Signal on a Pin and at the same time getting a timer interrupt if the UPPER value is reached? I tried the following code, but I only get once an interrupt (count stays at 1 forever if I use the debugger), but the PWM Signal is still available at PB6:
volatile int count=0;
void TM_LEDS_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
/* Clock for GPIOB */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* Alternating functions for pins */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM4);
/* Set pins */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void TM_TIMER_Init(void) {
TIM_TimeBaseInitTypeDef TIM_BaseStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
TIM_BaseStruct.TIM_Prescaler = 100;
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseStruct.TIM_Period = 256;
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
}
void TM_PWM_Init(void) {
TIM_OCInitTypeDef TIM_OCStruct;
TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCStruct.TIM_Pulse = 150; /* 25% duty cycle */
TIM_OC1Init(TIM4, &TIM_OCStruct);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Clear Interrupt */
for(int i=0; i<3; i++)
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
/* Enable Interrupt */
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM4, ENABLE);
}
void configNVIC(void)
{
NVIC_InitTypeDef initNVICStruct;
/* Enable the TIM2 global Interrupt */
initNVICStruct.NVIC_IRQChannel = TIM4_IRQn;
initNVICStruct.NVIC_IRQChannelPreemptionPriority = 1;
initNVICStruct.NVIC_IRQChannelSubPriority = 3;
initNVICStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&initNVICStruct);
}
void TIM4_IRQHandler(void) //This Interrupt changes changes state from x to x+-1
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
count++;
}
}
int main(void) {
/* Initialize system */
SystemInit();
configNVIC();
/* Init leds */
TM_LEDS_Init();
/* Init timer */
TM_TIMER_Init();
/* Init PWM */
TM_PWM_Init();
int i=0;
while (1) {
i=count;
}
}

If you're trying to count pulses or stop at a certain pulse this post may help
Stop PWM output after N steps

Related

STM32 Blinking LEDs with a Timer

I'm trying to blink 4 LEDs with a Timer Interrupt, at different frequencies.
I came up with this code
/*********** Includes ****************/
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
/*********** Defines *****************/
#define TIM3_CK_CNT 50000
/*********** Declarations *************/
/*------ Function prototypes ---------*/
void TimerConfiguration(void);
/* ----- Global variables ----------- */
volatile uint16_t CCR1_Val = 50000;
volatile uint16_t CCR2_Val = 40000;
volatile uint16_t CCR3_Val = 30000;
volatile uint16_t CCR4_Val = 20000;
/************ Main *********************/
int main(void)
{
// LED initialization
STM_EVAL_LEDInit(LED3); // Orange
STM_EVAL_LEDInit(LED4); // Green
STM_EVAL_LEDInit(LED5); // Red
STM_EVAL_LEDInit(LED6); // Blue
/* TIM3 Configuration */
TimerConfiguration();
while (1);
}
/*********** Functions *****************/
/**
* #brief Configure the TIM3 TIMER.
* #param None
* #retval None
*/
void TimerConfiguration(void)
{
uint16_t PrescalerValue = 0;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Prescaler configuration */
PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / TIM3_CK_CNT) - 1;
TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);
/* Output Compare Timing Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
/*Channel2 */
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
/*Channel3 */
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
/*Channel4 */
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
/* Configure the TIM3 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM Interrupts enable */
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC4, ENABLE);
/* TIM3 counter enable */
TIM_Cmd(TIM3, ENABLE);
}
int LedCount6 = 0;
int LedCount5 = 0;
int LedCount4 = 0;
int LedCount3 = 0;
/************ Interrupt Handlers *************/
/**
* #brief This function handles TIM3 global interrupt request.
* #param None
* #retval None
*/
void TIM3_IRQHandler(void)
{
uint16_t capture = 0;
LedCount6++;
LedCount5++;
LedCount4++;
LedCount3++;
if ((TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET) && (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) && (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET) && (TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET))
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
int val6 = 100000;
int val5 = 70000;
int val4 = 60000;
int val3 = 50000;
if (LedCount6 >= val6 ) {
/* LED6 toggling */
STM_EVAL_LEDToggle(LED6);
LedCount6 = 0;
/* Update CH1 OCR */
capture = TIM_GetCapture1(TIM3);
TIM_SetCompare1(TIM3, capture + CCR1_Val);}
if (LedCount5 >= val5) {
/* LED5 toggling */
STM_EVAL_LEDToggle(LED5);
LedCount5 = 0;
/* Update CH2 OCR */
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + CCR2_Val);}
if (LedCount4 >= val4) {
/* LED4 toggling */
STM_EVAL_LEDToggle(LED4);
LedCount4 = 0;
/* Update CH3 OCR */
capture = TIM_GetCapture3(TIM3);
TIM_SetCompare3(TIM3, capture + CCR3_Val);}
if (LedCount3 >= val3 ) {
/* LED3 toggling */
STM_EVAL_LEDToggle(LED3);
LedCount3 = 0;
/* Update CH4 OCR */
capture = TIM_GetCapture4(TIM3);
TIM_SetCompare4(TIM3, capture + CCR4_Val);}
}
}
Now, all the code that blinks the 4 leds is inside the interrupt handler (void TIM3_IRQHandler(void)).
The 4 LEDs blink, but blink all at the same time, how can i change their frequencies to be all different?
Changing the TIM3_CK_CNT value will change the frequency of all 4, but because it's a define i cannot manipulate it through the code to change for each led.
The TIMER (TIM3) has 4 channels which all can cause an interrupt, but the interrupt handler will be the same one for all channels.
Replace your IRQ handler like this (Change the LED toggle as you wish):
void TIM3_IRQHandler(void)
{
uint16_t capture = 0;
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
/* LED6 toggling */
STM_EVAL_LEDToggle(LED6);
/* Update CH1 OCR */
capture = TIM_GetCapture1(TIM3);
TIM_SetCompare1(TIM3, capture + CCR1_Val);
}
else if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
/* LED5 toggling */
STM_EVAL_LEDToggle(LED5);
/* Update CH2 OCR */
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + CCR2_Val);
}
else if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
/* LED4 toggling */
STM_EVAL_LEDToggle(LED4);
/* Update CH3 OCR */
capture = TIM_GetCapture3(TIM3);
TIM_SetCompare3(TIM3, capture + CCR3_Val);
}
else if (TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
/* LED3 toggling */
STM_EVAL_LEDToggle(LED3);
/* Update CH4 OCR */
capture = TIM_GetCapture4(TIM3);
TIM_SetCompare4(TIM3, capture + CCR4_Val);
}
}
With this change, LED will toggle with respect to each channel interrupt. i.e Only one LED blinks at each interrupt. In order to Blink with different frequencies, you need to check the datasheet, how configure different frequency for different LED channel.
The code is too large to place it here.
Here is my solution:
https://www.diymat.co.uk/arm-blinking-led-driver/
Any number of LEDs, any frequencies (off and on time can be different) any number of blinks (+continous) and the callbacks at the end of the sequence.

smt32 interrupts. why my diode is not blinking?

I have smt32l1xx board and this code below is not working. Debugger shows pinA5 is set, but diode connected to this pin is still not lightening. I dont know why. Even i add delay after setting bit it is not working. diode is connected to PA5 and GND on board.
#include <stm32l1xx.h>
#define ENABLE 1
#define DISABLE 0
void TIM2_IRQHandler() //interrupt
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_5))
GPIO_ResetBits(GPIOA, GPIO_Pin_5); //LED OFF
else
GPIO_SetBits(GPIOA, GPIO_Pin_5); //LED ON <- im here and still nothing
}
}
int main(void)
{
/* gpio init struct */
GPIO_InitTypeDef gpio;
TIM_TimeBaseInitTypeDef tim;
NVIC_InitTypeDef nvic;
/* reset rcc */
RCC_DeInit();
RCC_APB2PeriphClockCmd(RCC_AHBENR_GPIOAEN, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
GPIO_StructInit(&gpio);
/* use pin 0 */
gpio.GPIO_Pin = GPIO_Pin_5;
/* mode: output */
gpio.GPIO_Mode = GPIO_Mode_OUT;
/* apply configuration */
GPIO_Init(GPIOA, &gpio);
TIM_TimeBaseStructInit(&tim); //timer
tim.TIM_CounterMode = TIM_CounterMode_Up;
tim.TIM_Prescaler = 64000 - 1;
tim.TIM_Period = 1000 - 1;
TIM_TimeBaseInit(TIM2, &tim);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
nvic.NVIC_IRQChannel = TIM2_IRQn; //interrupt
nvic.NVIC_IRQChannelPreemptionPriority = 0;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
while (1)
{
}
/* never reached */
return 0;
}
To make sure that your hardware is properly initialized, you should use STM32CubeMX.
It seems that the GPIOA clock is on the AHB bus, however you call RCC_APB2PeriphClockCmd which is for APB2. So try to use the equivalent for AHB something like RCC_AHBPeriphClockCmd

STM32F429I Timer Interrupt

I try to implement a timer interrupt on a STM32F429I, but I had no success yet.
The Timer runs fine (observed with debugger) but the interrupt function never gets a call. Also the system seems to hang if I activate the interrupt and then call the function GPIO_WriteBit(), at least when I use the debugger and the function gets called, the debugger hangs. Here is the code so far:
#include "stm32f4xx.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_syscfg.h"
//****************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* pin configuration */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM2); // PA6 TIM2_CH1
}
//****************************************************************************
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
int i;
/* Enable TIM2 Peripheral clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Prescaler = 60000;
TIM_TimeBaseStructure.TIM_Period = 1500; //1Hz Interrupt frequency
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE);
// Likely will interrupt initially unless we clear it
for(i=0; i<3; i++)
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}
//****************************************************************************
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_ToggleBits(GPIOA, GPIO_Pin_6);
}
}
//****************************************************************************
void NVIC_Configuration(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//****************************************************************************
int main(void)
{
SystemInit();
if (SysTick_Config(SystemCoreClock / 1000))
{
/* Capture error */
while (1);
}
NVIC_Configuration();
GPIO_Configuration();
TIM2_Configuration();
GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
while(1) {
}
}
//******************************************************************************

STM32F407 PWM control phase shift, dutycycle

I'm new with the stm32f407 discovery board and I'm trying to make 4 signals which I can control phase shift and dutycycle. The thing is, when i set my timer on PWM mode I can't control phase shift between channel_1 and channel_2. I know I have to use interrupts but I can't figure out what i should code inside it. I would be grateful if you could help me.
Here is my code, I use one interrupt which switches on/off a LED every some time (the delay is not well synchronized yet).
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "misc.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_usart.h"
#include "delay.h"
/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Private define ------------------------------------------------------------*/
#define frequency 42500
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
int Prescaler = 0;
int Period = 84000000 / frequency; // ~42.5KHz
int pulse_width;
/* Private function prototypes -----------------------------------------------*/
void GPIO_Config(void);
void PWM_Config(void);
void PWM_SetDC(int channel,int dutycycle);
void Delay(__IO int nCount);
void LED_Config(void);
/* Private functions ---------------------------------------------------------*/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
Delay(10000000);
GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
}
}
/**
* Main program
*/
int main(void)
{
/* GPIO Configuration */
GPIO_Config();
LED_Config();
/* PWM Configuration */
PWM_Config();
PWM_SetDC(1,80);
PWM_SetDC(2,40);
PWM_SetDC(3,0);
PWM_SetDC(4,0);
while (1)
{
}
}
/**
* Configure the TIM2 Output Channels.
*/
void GPIO_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOC Configuration: TIM2 CH1 (PA0), TIM2 CH2 (PA1), TIM2 CH3 (PA2), TIM2 CH4 (PA3) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect TIM2 pins to AF2 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2);
}
void PWM_Config(void)
{
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
////////////////////////* TIM INTERRUPT enable *////////////////////////////
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
////////////////////////////////////////////////////////////////////////////
/* PWM1 Mode configuration: Channel2 */
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel3 */
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel4 */
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetDC(int channel,int dutycycle)
{
if (dutycycle <= 100 && dutycycle >= 0)
{
pulse_width=(Period*dutycycle)/100;
if (channel == 1)
{
TIM2->CCR1 = pulse_width;
}
else if (channel == 2)
{
TIM2->CCR2 = pulse_width;
}
else if (channel == 3)
{
TIM2->CCR3 = pulse_width;
}
else
{
TIM2->CCR4 = pulse_width;
}
}
}
void LED_Config(void)
{
/* GPIOD Peripheral clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Configure PD12, PD13, PD14 and PD15 in output push-pull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
/* Delay Function.
* nCount:specifies the Delay time length.
*/
void Delay(__IO int nCount)
{
while(nCount--)
{
}
}
I think I can Help you if you make you Question a bit clear..
As for as I can understand your Question:-> I think you want 2 PWM's with Phase shift?
so if you want simple phase shift between two pwm simply use this Let's say if you want a delay of 1ms. -> you have to use two different timers then..
TIM_Cmd(TIM2, ENABLE);
Delay(1000);
TIM_Cmd(TIM3, ENABLE);

STM32 Can't clear PWM interrupt flag

I'm trying to generate a 2MHz PWM with a duty-cycle of 50%. My problem is that I can't clear the interrupt flag. Here is my code:
#include "includes.h"
TIM_TimeBaseInitTypeDef TIM1_InitStruncture;
TIM_TimeBaseInitTypeDef TIM3_InitStruncture;
TIM_OCInitTypeDef TIM3_OCInitStructure;
SPI_InitTypeDef SPI_InitStructure;
void Timer3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
{
TIM_ClearFlag(TIM3, TIM_IT_CC3);
//dummy code
++StatusReg;
}
}
void CLK_init()
{
//activez HSI
RCC_HSICmd(ENABLE);
//astepst sa se activeze HSI
while( RCC_GetFlagStatus( RCC_FLAG_HSIRDY) == RESET );
//setez HSI ca sursa de clock
RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );
//activez HSE
RCC_HSEConfig( RCC_HSE_ON );
//astept sa se termine secventa de activare
while( RCC_GetFlagStatus( RCC_FLAG_HSERDY) == RESET );
//setez HSE (8MHz) ca input py PLL
//setez factotul de multiplicare 9
RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
//activez PLL-ul
RCC_PLLCmd(ENABLE);
//astept sa se termine secventa de activare
while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY) == RESET );
#ifdef EMB_FLASH
// 5. Init Embedded Flash
// Zero wait state, if 0 < HCLK 24 MHz
// One wait state, if 24 MHz < HCLK 56 MHz
// Two wait states, if 56 MHz < HCLK 72 MHz
// Flash wait state
FLASH_SetLatency(FLASH_Latency_2);
// Half cycle access
FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_Disable);
// Prefetch buffer
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
#endif // EMB_FLASH
//setez iesirea de la PLL ca sursa de CLK
RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
}
void Port_C_Enable()
{
//GPIO_InitTypeDef GPIOC_InitStructure;
//resetez portul C (just in case)
RCC->APB2RSTR |= RCC_APB2RSTR_IOPCRST;
RCC->APB2RSTR &= ~RCC_APB2RSTR_IOPCRST;
//activez CLK-ul pentru portul C
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
/*
GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIOC_InitStructure);
*/
}
void Timer3_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//reset Timer3 (just in case)
//RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST;
//RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST;
//give clock to Timer-ul 3
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
//frequency 2Mhz
TIM3_InitStruncture.TIM_Period = 36;
TIM3_InitStruncture.TIM_Prescaler = 0;
TIM3_InitStruncture.TIM_ClockDivision = 0;//TIM_CKD_DIV1;
TIM3_InitStruncture.TIM_CounterMode = TIM_CounterMode_CenterAligned3;
TIM_TimeBaseInit(TIM3, &TIM3_InitStruncture);
TIM_ITConfig(TIM3, TIM_IT_CC3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
//dutycicle 50%
TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM3_OCInitStructure.TIM_Pulse = 18;
TIM_OC3Init(TIM3, &TIM3_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*GPIOB Configuration: TIM3 channel1, 2, 3 and 4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;*/
//GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
/* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void NVIC_init(void)
{
// NVIC init
#ifndef EMB_FLASH
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
void SPI_init()
{
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init(SPI2, &SPI_InitStructure);
}
void main(void)
{
#ifdef DEBUG
debug();
#endif
// NVIC_SETPRIMASK();
CLK_init();
NVIC_init();
Port_C_Enable();
GPIO_Configuration();
//Timer1_Init();
Timer3_Init();
TIM_Cmd(TIM1, ENABLE);
unsigned int j=0;
while(1)
{
//dummy code
++j;
if(j == 0xff)
{
j=0;
}
}
}
Can anyone tell me why the CCR3 (Capture/Compare Register 3 Flag) stays high?
Thanks.
Pay attention to not mixing the following:
TIM_ClearFlag which shall be used together with TIM_FLAG_CC1
TIM_ClearITPendingBit which shall be used together with TIM_IT_CC1
as far as I understand. Otherwise you could have some masks which avoid to flag to be set.
Thanks aamxip for your answer.
I found the problem. It seems that the configuration is correct but i don't have enough time to execute the ISR(interrupt service routine). Once every 36 CLK's a new interrupt is generated and it takes me somewhere around 30 instructions or more only to enter in the ISR.
After more research i found out that i don't really need that frequency and i adopted a different approach, bit-banging.

Resources