Skip to main content
Graduate
April 15, 2025
Solved

Use of .c or .h files

  • April 15, 2025
  • 7 replies
  • 1559 views

Hi, I am curious one thing when using the HAL libraries. Just as an basic exapmle i assign LED1 to PB12 pin of STM32F070CBT6 as an GPIO_output. And i want to use HAL_GPIO_WritePin(GPIOB, LED1, LED1_SET); instead of HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); . Do you think it is weird that i want to use my variables like that with HAL libraries? Second thing is (if it is not weir or inappropriate), should i define my definitions as "definitions.c" or "definitions.h"? When i make some search, .c file is not recommended. I am not sure if i do all these steps with my ST microcontroller and it works well.

    This topic has been closed for replies.
    Best answer by Andrew Neil

    @TDK wrote:

    Your usage mixes this with LED1_SET. But up to you.


    It can be a good thing to define your own LED_SET and LED_CLEAR (or whatever)  - this allows you to be independent of whether the LED is active-high or active-low.

    Probably better names would be LED_ON and LED_OFF - which directly indicate the intended function, rather than hiding between the rather ambiguous "set" and "reset"...

     

    7 replies

    Super User
    April 15, 2025

    > Do you think it is weird that i want to use my variables like that with HAL libraries?

    A bit. The intended usage is something like:

    HAL_GPIO_WritePin(LED1_PORT, LED1_PIN, GPIO_PIN_SET);

    Your usage mixes this with LED1_SET. But up to you.

    > should i define my definitions as "definitions.c" or "definitions.h"?

    They will need to be in a header file if you want to use them in multiple source files. If you're only using them within a single source file, you can put them in that source file. Up to you.

    Super User
    April 15, 2025

    @TDK wrote:

    Your usage mixes this with LED1_SET. But up to you.


    It can be a good thing to define your own LED_SET and LED_CLEAR (or whatever)  - this allows you to be independent of whether the LED is active-high or active-low.

    Probably better names would be LED_ON and LED_OFF - which directly indicate the intended function, rather than hiding between the rather ambiguous "set" and "reset"...

     

    Super User
    April 15, 2025

    @tensaisakuragi06 wrote:

    i want to use HAL_GPIO_WritePin(GPIOB, LED1, LED1_SET); instead of HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); . Do you think it is weird that i want to use my variables like that with HAL libraries? .


    Of course not!

    That is exactly what CubeMX does with its generated code, and what many ST BSPs (Board Support Packages) do, too.

    HAL_GPIO_WritePin is just a C function - its parameters work exactly the same as any other C function.

     

    BTW: note that it is usual practice for ALL CAPITALS names in C to be reserved for #defined names - not variables.

     


    @tensaisakuragi06 wrote:

    should i define my definitions as "definitions.c" or "definitions.h"? .


    You can name your source files however you like!

    But you need to understand the C rules of scope & visibility - this is standard C, and nothing specifically to do with STM32.

    When you say "definitions", are you talking about preprocessor definitions (using #define), or C functions & variables?

    With functions & variables, be sure to understand the difference between declarations and definitions:

    https://community.st.com/t5/stm32cubeide-mcus/adding-new-c-source-files-to-my-project-and-navigating-through/m-p/657455/highlight/true#M25847

     


    @tensaisakuragi06 wrote:

     When i make some search, .c file is not recommended.


    Please provide examples - you may be misunderstanding.

     


    @tensaisakuragi06 wrote:

    I am not sure if i do all these steps with my ST microcontroller and it works well.


    This is all standard C stuff - nothing specifically to do with ST or even microcontrollers.

    Here are some C learning & reference materials:

    https://blog.antronics.co.uk/2011/08/08/so-youre-thinking-of-starting-with-c/

    Graduate
    April 15, 2025

    Yeah, it stil confuses me sometimes, i am planing to use both #define 's and variable definitions like unsigned int16 ... ;

    According to your pointers, i should seperate them like "declarations for #define 's " and "definitions for unsigned int16 ... ; " like. I hope that i understand you correctly :) .

    Super User
    April 15, 2025

    @tensaisakuragi06 wrote:

    According to your pointers, i should seperate them like "declarations for #define 's " and "definitions for unsigned int16 ... ; " like. I hope that i understand you correctly :) .


    I'm afraid not.

    #define is used by the preprocessor; it is purely text substitution. It never gets seen by the compiler proper.

    Definitions for functions & variables are what actually create the objects (data or code) in memory. The C programming language requires that each functions & variable must have exactly one definition.

    Having more than one definition of a function or variable is an error - you will get an error message saying, "multiple definitions".

    Declarations for functions & variables do not cause any memory to be allocated, or code created - they simply give enough information for the function/variable to be used, on the assumption that it has been defined somewhere else.

     

    Again, this is all standard C stuff - nothing specific to ST or embedded or microcontrollers - so see general C programming tutorials, textbooks, etc for details.

    Graduate
    April 15, 2025

    I define them with header file format (.h). It works for now. Thank yu for your pointers.

    Super User
    April 15, 2025

    @tensaisakuragi06 wrote:

    I define them with header file format (.h).


    That doesn't really make sense - a header (.h) file has no "format" different from a .c file.

    The difference is in the way they are used - not their "format".

    Graduate
    April 15, 2025
    // Pin definitions
    #define LED1 GPIO_PIN_12
    #define LED2 GPIO_PIN_3
    #define ROLE1 GPIO_PIN_7
    #define ROLE2 GPIO_PIN_6
    #define BUTON1 GPIO_PIN_13
    #define BUTON2 GPIO_PIN_14
    #define BUTON3 GPIO_PIN_15
    
    
    // Macro definitions
    #define LED1_ON GPIO_PIN_SET
    #define LED1_OFF GPIO_PIN_RESET
    
    #define ROLE1_ON GPIO_PIN_SET
    #define ROLE1_OFF GPIO_PIN_RESET
    
    #define LED2_ON GPIO_PIN_SET
    #define LED2_OFF GPIO_PIN_RESET
    
    #define ROLE2_ON GPIO_PIN_SET
    #define ROLE2_OFF GPIO_PIN_RESET
    
    #define BUTON1_ON GPIO_PIN_SET
    #define BUTON1_OFF GPIO_PIN_RESET
    
    #define BUTON2_ON GPIO_PIN_SET
    #define BUTON2_OFF GPIO_PIN_RESET
    
    #define BUTON3_ON GPIO_PIN_SET
    #define BUTON3_OFF GPIO_PIN_RESET
    Graduate
    April 15, 2025

    I change my definitions like above and its looks good for me. If i can improve my logic, please do not hesitate to tell me.

    Super User
    April 15, 2025

    @tensaisakuragi06 wrote:

     If i can improve my logic, please do not hesitate to tell me.


    You have only got #defines for the pins - you should also have them for the ports!

    eg,

    #define LED1_PIN GPIO_PIN_12
    #define LED1_PORT GPIOB

    (Note that these are all "macros")

     

     Then you can write:

    HAL_GPIO_WritePin( LED1_PORT, LED1_PIN, LED1_ON );

     

    Graduate
    April 15, 2025

    Cruel programming world. Thank you for your reminders and tips.

    Graduate II
    April 15, 2025

    If you use STM32CubeIDE or STM32CubeMX, you can use Enter User Label to name the pin. In this case, PA5 is named LED_GREEN.

    KarlYamashita_0-1744744179992.png

     

    When you generate the code, it'll create the Port and pin defines in main.h

    /* Private defines -----------------------------------------------------------*/
    #define MCO_Pin GPIO_PIN_0
    #define MCO_GPIO_Port GPIOF
    #define LED_GREEN_Pin GPIO_PIN_5
    #define LED_GREEN_GPIO_Port GPIOA
    #define TMS_Pin GPIO_PIN_13
    #define TMS_GPIO_Port GPIOA
    #define TCK_Pin GPIO_PIN_14
    #define TCK_GPIO_Port GPIOA

     

     

    Graduate
    April 16, 2025

    I just do them in "definitions.h" header file, not under the Private Define. It still works. Thank you all for your help.