cancel
Showing results for 
Search instead for 
Did you mean: 

How do I declare a UART Function in a separate C file?

DRicc.2
Senior

I have a program that displays the current temperature of a room on the UART terminal and I want to start getting into the habit of separating my functions into their own source and header files, however, I'm running into a couple of problems. 

Here is my main header file:

 

#include "main.h" //Main header file #include <stdio.h> //Standard header filer #include <string.h> //String header filer #include "uart.h" #define SI7021_ADDRESS_READ (0x40 << 1) | 0x01 #define SI7021_ADDRESS_WRITE (0x40 << 1) #define SI7021_MEASURE_HUM_NOHOLD 0xF5 #define SI7021_MEASURE_TEMP_NOHOLD 0xF3 char msg[50]; I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_USART2_UART_Init(void); static uint32_t si7021_measure_humidity(I2C_HandleTypeDef *hi2c) { uint8_t si7021_buf[4]; si7021_buf[0] = SI7021_MEASURE_HUM_NOHOLD; // Start measure int res = HAL_I2C_Master_Transmit(hi2c, SI7021_ADDRESS_WRITE, si7021_buf, 1, 100); if (res != HAL_OK) { return sprintf(msg,"ERROR - Could Not Transmit Humidity\r\n"); uart_send_str (msg); } HAL_Delay(30); // Read result res = HAL_I2C_Master_Receive(hi2c, SI7021_ADDRESS_READ, si7021_buf, 2, 100); if (res != HAL_OK) { return sprintf(msg,"ERROR - Could Not Receive Humidity\r\n"); uart_send_str (msg); } return (si7021_buf[0] << 8 | si7021_buf[1]) * 125 / 65536 - 6; } static int32_t si7021_measure_temperature(I2C_HandleTypeDef *hi2c) { uint8_t si7021_buf[4]; si7021_buf[0] = SI7021_MEASURE_TEMP_NOHOLD; // Start measure int res = HAL_I2C_Master_Transmit(hi2c, SI7021_ADDRESS_WRITE, si7021_buf, 1, 100); if (res != HAL_OK) { return sprintf(msg,"ERROR - Could Not Transmit Humidity\r\n"); uart_send_str (msg); } HAL_Delay(30); // Read result res = HAL_I2C_Master_Receive(hi2c, SI7021_ADDRESS_READ, si7021_buf, 2, 100); if (res != HAL_OK) { return sprintf(msg,"ERROR - Could Not Receive Humidity\r\n"); uart_send_str (msg); } int64_t temp_code = (si7021_buf[0] << 8 | si7021_buf[1]) * 100; int64_t temp = 17572 * temp_code / 6553500 - 4685; if (temp > 12500 || temp < -4000) { return sprintf(msg,"ERROR - Temperature could not be read properly!\r\n"); uart_send_str (msg); } return (int32_t)temp; } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); MX_USART2_UART_Init(); while (1) { uint32_t humidity = si7021_measure_humidity(&hi2c1); if (humidity == 0xFFFF){ } uint32_t temperature = si7021_measure_temperature(&hi2c1); float temp_C = temperature/100; sprintf(msg, "%2f C %lu RH\r\n", temp_C, humidity); uart_send_str (msg); HAL_Delay(500); } }
View more

 My Uart header file:

#ifndef uart_h #define uart_h void uart_send_str (const char* msg); #endif

My Uart C file:

#include <stdio.h> #include "uart.h" #include <stdint.h> void uart_send_str (const char* msg) { HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); }

 

I get the following errors:

'huart2' undeclared - first use of this function"

'HAL_MAX_DELAY' undeclared - first use of this function"

 

Along with an implicit declaration of HAL_UART_Transmit function as a warning.

I know you have to initialize the function before you declare it as typically seen in the main with the "static void MX_USART2_UART_Init(void);" function, but I don't know how to do this in a separate header file.

1 ACCEPTED SOLUTION

Accepted Solutions

@DRicc.2 wrote:

Here is my main header file:

 

#include "main.h" //Main header file #include <stdio.h> //Standard header filer #include <string.h> //String header filer #include "uart.h" #define SI7021_ADDRESS_READ (0x40 << 1) | 0x01 #define SI7021_ADDRESS_WRITE (0x40 << 1) #define SI7021_MEASURE_HUM_NOHOLD 0xF5 #define SI7021_MEASURE_TEMP_NOHOLD 0xF3 char msg[50]; I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_USART2_UART_Init(void); static uint32_t si7021_measure_humidity(I2C_HandleTypeDef *hi2c) { : : : etc...
View more

 


No, that's not a header file - that's a .c file.

In that .c you have some definitions that you want to share:

 

char msg[50]; I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2;

 

So you need to make a header with extern declaration for those - let's call it my_main_header.h:

 

extern char msg[50]; exterm I2C_HandleTypeDef hi2c1; extern UART_HandleTypeDef huart2;

 

Then you need to include that header in your Uart C file:

 

#include <stdio.h> #include "uart.h" #include <stdint.h> #include "my_main_header.h" // The declaration of huart2 is here void uart_send_str (const char* msg) { HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); // You are using huart2 here }

 

 

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

View solution in original post

5 REPLIES 5

See:

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

 

Sorry, ignore the rest of this post - I was misled by

 

@DRicc.2 wrote:

Here is my main header file:


It's not a header - it's a .c file!

 

 


@DRicc.2 wrote:

I get the following errors:

'huart2' undeclared - first use of this function"

'HAL_MAX_DELAY' undeclared - first use of this function"


 

 

That's because huart2 is declared in your "main header file", but you haven't included that in your Uart C file.

Your Uart C file should have:

 

 

 

#include <stdio.h> #include "uart.h" #include <stdint.h> #include "my_main_header_file.h" // You missed this. // This is where huart2 is declared. void uart_send_str (const char* msg) { HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); }

 

 

 

 

 

EDIT:

I can't see HAL_MAX_DELAY defined in anything you posted.

 

Also note that

 

 

char msg[50]; I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2;

 

 

should not be in a header.

 

They are definitions - the header should just have the extern declarations:

 

 

extern char msg[50]; extern I2C_HandleTypeDef hi2c1; extern UART_HandleTypeDef huart2;

 

 

 

 

and the definition should be in a .c file (or files) somewhere.

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

need

extern UART_HandleTypeDef huart2; // in main.h or as used in uart.c

 

As for HAL_MAX_DELAY, probably that you need to pull in the HAL include files, is main.h doing that currently, or main.c ??

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

If you're using CubeMX generated code, #including main.h should pull in everything you need. Put that at the top of your header file.

If you feel a post has answered your question, please click "Accept as Solution".

@DRicc.2 wrote:

Here is my main header file:

 

#include "main.h" //Main header file #include <stdio.h> //Standard header filer #include <string.h> //String header filer #include "uart.h" #define SI7021_ADDRESS_READ (0x40 << 1) | 0x01 #define SI7021_ADDRESS_WRITE (0x40 << 1) #define SI7021_MEASURE_HUM_NOHOLD 0xF5 #define SI7021_MEASURE_TEMP_NOHOLD 0xF3 char msg[50]; I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_USART2_UART_Init(void); static uint32_t si7021_measure_humidity(I2C_HandleTypeDef *hi2c) { : : : etc...
View more

 


No, that's not a header file - that's a .c file.

In that .c you have some definitions that you want to share:

 

char msg[50]; I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2;

 

So you need to make a header with extern declaration for those - let's call it my_main_header.h:

 

extern char msg[50]; exterm I2C_HandleTypeDef hi2c1; extern UART_HandleTypeDef huart2;

 

Then you need to include that header in your Uart C file:

 

#include <stdio.h> #include "uart.h" #include <stdint.h> #include "my_main_header.h" // The declaration of huart2 is here void uart_send_str (const char* msg) { HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); // You are using huart2 here }

 

 

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

I read the file wrong, yes it is the main.c and not main.h silly mistake...

Extern variables make a lot of sense, I knew there was a way to call the functions from the main in separate c files but didn't know how. Thank you very much!