cancel
Showing results for 
Search instead for 
Did you mean: 

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

DRicc.2
Associate III

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);
  }

}

 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
Andrew Neil
Evangelist III

@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...

 


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
}

 

 

 

View solution in original post

5 REPLIES 5
Andrew Neil
Evangelist III

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.

 

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".
Andrew Neil
Evangelist III

@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...

 


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
}

 

 

 

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!