2024-08-01 11:20 AM
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.
Solved! Go to Solution.
2024-08-01 12:13 PM - edited 2024-08-01 12:14 PM
@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
}
2024-08-01 11:51 AM - edited 2024-08-01 12:06 PM
See:
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.
2024-08-01 11:53 AM
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 ??
2024-08-01 12:06 PM
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.
2024-08-01 12:13 PM - edited 2024-08-01 12:14 PM
@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
}
2024-08-01 12:32 PM
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!