How use PWM on STM32F446RE

Thread Starter

specs365

Joined Mar 14, 2019
45
Hi everyone, so for the last few days I have been trying to figure out the STM32F446RE to use for a project. We are not allowed to use libraries such as HAL. So far I have been able to set up my timer 4 as a normal counter. Reading the data sheet I see the registers that I need to use, but I have no idea how to actually use them.

The problem that I have is I don't understand what the channels are and also, what register or bit do I need to look at to see the output of the PWM?

I see using CubeMX that pin PB6 is channel 1 of timer 4. But what registers do I need to edit in order to actually output on that pin. What should I set the pin mode to etc? I'm just really lost at this point.

I am coding in C.

I can maybe clarify more if needed.
 

Thread Starter

specs365

Joined Mar 14, 2019
45
I think what I would need is a list of the registers that I need to configure, and then what I should do with them haha.
 

MrChips

Joined Oct 2, 2009
34,829
I think what I would need is a list of the registers that I need to configure, and then what I should do with them haha.
In that case it is all in the datasheet.
Just so that I know where you're at, do you know how program the STM32 to flash an LED?
 

Thread Starter

specs365

Joined Mar 14, 2019
45
Yes, I am currently reading the datasheet, I can flash an LED using a software delay and also kind of use a timer to flash an LED. My main problem is I don't really understand the input/output capture registers and which ones depend on which ones. What I do understand is the ARR register and how to enable the counter to start counting and things like that. But that's where I get stuck...
 

Thread Starter

specs365

Joined Mar 14, 2019
45
Yes, I am currently reading the datasheet, I can flash an LED using a software delay and also kind of use a timer to flash an LED. My main problem is I don't really understand the input/output capture registers and which ones depend on which ones. What I do understand is the ARR register and how to enable the counter to start counting and things like that. But that's where I get stuck...
By Kind of I mean I make the timer count to say 30000 and if the CNT value is less than 15000 I set a GPIO pin low and if it's more than 15000 I set it high, just to clarify that.
 

MrChips

Joined Oct 2, 2009
34,829
What I meant by asking the question was, ARM chips and their peripherals are not as straight forward as with other simpler MCUs.

Thus, you need to know how to set up the system clocks, peripheral clocks and GPIO devices.
You need to know how to write to peripheral device registers. Presumably, you will end up using some library functions within CubeIDE.

If you already know how to set a TIMER module running then I will show you how to get PWM running on a GPIO output pin.

Show us the full code you are currently running.
 

Thread Starter

specs365

Joined Mar 14, 2019
45
Ok, It is not very neat right now I apologise. Can you maybe just remind me how to add code here properly?
 

Thread Starter

specs365

Joined Mar 14, 2019
45
hi spec,
Please use Code Tags. Mod.

C:
/**
******************************************************************************
* @file           : main.c
* @author         : Auto-generated by STM32CubeIDE
* @brief          : Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*                        opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/

#include <stdint.h>
#include <stdio.h>

#if !defined(__SOFT_FP__) && defined(__ARM_FP)
  #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif

int main(void)
{

    uint32_t *Periheral_Clock_EN = (uint32_t*)(0x40023830); //For GPIO clock enables
    uint32_t *GPIO_C_Mode = (uint32_t*)(0x40020800);        //GPIO C mode reg
    uint32_t *GPIO_C_OUT = (uint32_t*)(0x40020814);

    uint32_t *GPIO_B_Mode = (uint32_t*)(0x40020400);



    //GPIO C output data register
    uint32_t *RCC_APB1_CLK_EN = (uint32_t*)(0x40023840); // For timer clock enables
    uint32_t *TIM4_CTRL_REG = (uint32_t*)(0x40000800); // Timer 4 Control register
    uint32_t *TIM4_COUNT_VAL = (uint32_t*)(0x40000824);
    uint32_t *TIM4_RELOAD_VAL = (uint32_t*)(0x4000082C);
    uint32_t *TIM4_PSC = (uint32_t*)(0x40000828);


    uint32_t *TIM4_CCMR1 = (uint32_t*)(0x40000818);
    uint32_t *TIM4_CCR1 = (uint32_t*)(0x40000834);



    uint32_t Timer_count = *TIM4_COUNT_VAL;


    *Periheral_Clock_EN |= (1<<2);     //Enable PORT C Clock
    *Periheral_Clock_EN |= (1<<1);
    *GPIO_B_Mode |= (1<<13);
    *RCC_APB1_CLK_EN |= (1<<2);        //Enable Timer 4 Clock
    *GPIO_C_Mode &= ~(3<<7);        //Clear PC3 mode pin
    *GPIO_C_Mode |= (1<<6);             //Set PC3 to general output
    *TIM4_RELOAD_VAL = 10000;        //Timer counts up to this number
    *TIM4_CCR1 = 5000;
    *TIM4_PSC = 2250;
    *TIM4_CCMR1|= (6<<4);

    uint32_t Relaod_val = *TIM4_RELOAD_VAL;

    *TIM4_CTRL_REG |= 1;    //Counter starts
    while(1){
    printf("%ld\n", (int32_t)(*TIM4_COUNT_VAL));
    if(*TIM4_COUNT_VAL <= 10000/2) *GPIO_C_OUT |= (1<<3);
    if(*TIM4_COUNT_VAL > 10000/2) *GPIO_C_OUT &= ~(1<<3);
    }


    /*while(1){
        *GPIO_C_OUT |= (1<<3);                    //Set PC3 HIGH
        for(uint32_t i = 0; i<100000; i++);
        *GPIO_C_OUT &= ~(1<<3);                    //SET PC3 LOW
        for(uint32_t i = 0; i<=1000000; i++);
    }*/




}
 

Thread Starter

specs365

Joined Mar 14, 2019
45
Please note, that the printf function is made possible by a change I made in the syscalls.c file, which I found in a Udemy course.
 
Top