How do I declare a UART Function in a separate C file?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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
}
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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.
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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 ??
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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
}
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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!
