2020-05-29 01:39 AM
Hi All,
I want to use timer 1 for my double pulse test. To start with though I want to get it going in a simple PWM mode at first.
I have gone trhough the reference amnual several times and looked at the block diagrams. I have got the registers intialized and the counter, counting. Howver I am gettting nothing at the output when I am trying to toggle the LED. What am I missing?
int init_TIM1()
{
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Enabling Timer clock
RCC->AHBENR |= RCC_AHBENR_GPIOCEN; // Enabling Port C clock
GPIOC->MODER |= (1<<1); // Setting PC0 as alternate function
GPIOC->MODER |= (1<<3); //Setting PC1 as alternate function
GPIOC->OSPEEDR |= (1<<0) |(1<<1) | (1<<2) |(1<<3) ; // PC0, PC1 = High Speed
TIM1->CCMR1 |= (1<<5) | (1<<6); // Setting Channel 1 in PWM Compare mode 1
TIM1->CCMR1 |= (1<<13) | (1<<14); // Setting Channel 2 as PWM Compare mode 1
TIM1->CCMR1 |= (1<<3) | (1<<11); // Enabling OC1 and OC2 preload registers
TIM1->CCMR1 |= (1<<7) |(1<<15) ; // OCxRef is cleared as soon as a high level is detected on ocref_clr_int signal
TIM1->CR1 |= (1<<7); // Enabling the auto reload preload register for the timer (buffered)
TIM1->PSC = 6499; // PSC = 6500 (6499+1) = 36 Mhz / 6500 = 5538
TIM1->ARR = 5538; // approx 1 s delay
TIM1-> CCR1 = 2769;
TIM1->CCR2 = 5538;
TIM1->EGR |= (1<<5); // Enabling capture compare update generation
TIM1->CCER |= (1<<0) | (1<<4); // Enabling OC outputs for ch1 and ch2 which maps them to the pin
TIM1->BDTR |= (1<<15); // Main output enable
TIM1->EGR |= (1<<0); // Reintializing the counter and generates an update of the registers
TIM1->CR1 |= (1<<0); //enable counter
return(0);
}
Cheers
Solved! Go to Solution.
2020-05-29 02:26 AM
Which STM32?
In GPIOx_AFR, you need to select the proper AF number, see the pin assignment table in Datasheet.
You may want to swap the enables, first enable GPIO, so that there's time between enabling GPIO and writing into its registered, see the errata (maybe this does not apply to your MCU but certainly won't harm).
JW
PS. Using symbols defined in the CMSIS-mandated device header increases readability.
2020-05-29 02:26 AM
Which STM32?
In GPIOx_AFR, you need to select the proper AF number, see the pin assignment table in Datasheet.
You may want to swap the enables, first enable GPIO, so that there's time between enabling GPIO and writing into its registered, see the errata (maybe this does not apply to your MCU but certainly won't harm).
JW
PS. Using symbols defined in the CMSIS-mandated device header increases readability.
2020-05-29 02:39 AM
TIM1->EGR |= (1<<5); // Enabling capture compare update generation
This is probably harmless, but does not do what the comment says. Writing 1 to EGR bits fire not enable anything, it generates an internal event (signal).
Also, you don't RMW (|=) into EGR as it's a write-only register, i.e. you only =. Again it's harmless error as EGR reads as constant zero, but wrong practice nonetheless.
Did you copy this code from some source?
JW
2020-05-29 03:47 AM
Hi Jan!
Thanks for your help! It was the alternate functions I forgot to set, it is now working.
With regards to the Internal even you are right , I didn't comment it properly.
This code is all mine I just have been looking at the manual, I admit some bits of it I have not fully comented properly. Also I understand what you're saying about the symbols but sometimes I just find it quicker just to plugin the bit rather than having to look up the symbol in the header file. Then I am putting comments in for readability.
Thanks for your tips. I am a power electronics engineer by trade so I am not great at programming and the STM32 is new to me (I am using STM32F302R8) nucleo to develop my own automated double pulse tester.
Thanks again for the tips!
2020-05-29 04:22 AM
> I just find it quicker just to plugin the bit rather than having to look up the symbol in the header file.
You don't have to look it up, the bitfields are (most of the time) named in a consistent way. So e.g. when the reference manual tells you that you set the CEN bit in CR1 to start the timer, you can just write
TIM1->CR1 |= TIM_CR1_CEN;
It works with with numerical bitfields too, e.g. to set PB2 to AF mode 2, write
GPIOB->AFR[0] = (GPIOB->AFR[0] & ~GPIO_AFRL_AFSEL1) | (2u << GPIO_AFRL_AFSEL1_Pos); // PB1 AF2 = TIM3_CH4
except when the bitfield is non-consecutive, then you have to resort to individual bit macros
TIM1->SMCR = (TIM1->SMCR & ~TIM_SMCR_SMS) | TIM_SMCR_SMS_3;
> I am not great at programming and the STM32 is new to me
You've already achieved more than a lot of people here who don't have the slightest idea wham I'm talking about when I tell them to check bit X in register Y.
2020-05-29 04:36 AM
> This code is all mine I just have been looking at the manual,
Ah I see.
I asked because I see this style quite often here (within the minority of users who don't click in CubeMX), so I suspected there's some common source.
> Also I understand what you're saying about the symbols but sometimes I just find it quicker just to plugin the bit
> rather than having to look up the symbol in the header file.
YMMV
> Then I am putting comments in for readability.
Thumbs up.
JW