Что куда файлы заголовков и реализаций

Подскажите пожалуйста правильное наполнение .h и .c ну или хотя бы близкое к хорошему тону. т.к судя по интернету большинство наполняет как хочет, а более точного описания что действительно надо ( в заголовочном файле объявления, а в реализации их реализация) я не нашел…

правомерное такое наполнение или что-то лишнее

s_var.h



#ifndef INC_S_VAR_H_
#define INC_S_VAR_H_


#ifdef __cplusplus
 extern "C" {
#endif

 #include "main.h"


#define     COMMAND_ADDRESS                   0x8040
#define     ESD_CHECK_ADDRESS                 0x8041
#define     COMMAND_CHECK_ADDRESS             0x8046


typedef volatile struct {

	uint8_t start;
	uint16_t my_msec;
	uint8_t my_sec;
	uint8_t my_min;
	uint32_t start_time;

} my_time_t;

typedef volatile struct {

	uint16_t XX;
	uint16_t YY;
	uint16_t XXOLD;
	uint16_t YYOLD;
	uint8_t stat;
    uint8_t buff_alf;
} my_touch_t;

enum flags {
	_zero,
	_yes,
	_no,
	_cancel,
	_yesmax,
	_edit_mas,
	_input_mas,
	_select,
	_edit,
	_proces,
	_start,
	_stop,
	_select_sort,
	_select_button,
	_select_prof,
	_select_end,
	_show_cursor,
	_cursor_yes,
	_cursor_no,
};


extern volatile char xy_text[20];
extern volatile uint8_t TouchCount911;
extern volatile int my_mks;
extern volatile my_time_t  my_time;
extern volatile my_touch_t  my_touch;





extern void key_select(uint8_t ny,uint8_t sy,uint16_t colory);



#ifdef __cplusplus
}
#endif

#endif /* INC_S_VAR_H_ */

s_var.c



#include "s_var.h"



volatile int my_mks=0;



my_time_t  my_time;
my_touch_t  my_touch;





volatile char xy_text[20]={0};
volatile uint8_t TouchCount911 = 0;
extern uint16_t TFT_WIDTH;
extern uint16_t TFT_HEIGHT;





char alf[] = { "1234567890QWERTYUIOPASDFGHJKL*ZXCVBNM.-=   " };

void key_select(uint8_t ny, uint8_t sy, uint16_t colory) {
	if ((ny > 7) & (sy == 3))
	{
		if (ny == 9) ny = 8;
		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 134 + ((ny + 1) * 66),
				131 + (sy * 53), colory);
		LCD_DrawSqware(84 + (ny * 66), 161 + (sy * 53), 134 + ((ny + 1) * 66),
				166 + (sy * 53), colory);
		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 89 + (ny * 66),
				166 + (sy * 53), colory);
		LCD_DrawSqware(128 + ((ny + 1) * 66), 126 + (sy * 53),
				134 + ((ny + 1) * 66), 166 + (sy * 53), colory);

	} else if (((ny == 0) && (sy == 4)) || ((ny == 8) && (sy == 4)))
	{

		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 134 + ((ny + 1) * 66),
				131 + (sy * 53), colory);
		LCD_DrawSqware(84 + (ny * 66), 161 + (sy * 53), 134 + ((ny + 1) * 66),
				166 + (sy * 53), colory);

		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 89 + (ny * 66),
				166 + (sy * 53), colory);
		LCD_DrawSqware(128 + ((ny + 1) * 66), 126 + (sy * 53),
				134 + ((ny + 1) * 66), 166 + (sy * 53), colory);

	} else if ((ny == 2) & (sy == 4))
	{

		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 134 + ((ny + 5) * 66),
				131 + (sy * 53), colory);
		LCD_DrawSqware(84 + (ny * 66), 161 + (sy * 53), 134 + ((ny + 5) * 66),
				166 + (sy * 53), colory);

		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 89 + (ny * 66),
				166 + (sy * 53), colory);
		LCD_DrawSqware(128 + ((ny + 5) * 66), 126 + (sy * 53),
				134 + ((ny + 5) * 66), 166 + (sy * 53), colory);

	} else if ((sy < 4))
	{

		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 134 + (ny * 66),
				131 + (sy * 53), colory);
		LCD_DrawSqware(84 + (ny * 66), 161 + (sy * 53), 134 + (ny * 66),
				166 + (sy * 53), colory);

		LCD_DrawSqware(84 + (ny * 66), 126 + (sy * 53), 89 + (ny * 66),
				166 + (sy * 53), colory);
		LCD_DrawSqware(128 + (ny * 66), 126 + (sy * 53), 134 + (ny * 66),
				166 + (sy * 53), colory);

	}

}

P/S не обращайте внимание на то , что некоторые объявленные переменные не используются… в файле main пока только #include “s_var.h” и бесконечный цикл… поэтому не выкладываю … ошибок нет по компилятору … меня в данном случае интересует правильно ли я разместил или не там где надо. или может что-то лишнее…
переменные extern volatile использоваться будут в других файлах и в прерываниях…

Спасибо

Зачем в прототипе функции (строка 70 хидера) extern ?

Или я не догнал какую-то гениальную идею?

если функцию не сделать extern то при вызове ее из маин, выдавало ошибку как функция не определена … возможно я что-то не так делал

main.c

#include "main.h"
#include "fatfs.h"
#include "i2c.h"
#include "sdio.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "fsmc.h"


#include "s_var.h"


void SystemClock_Config(void);
int main(void)
{
  HAL_Init();

  SystemClock_Config();
  MX_GPIO_Init();
  MX_FSMC_Init();
  MX_SDIO_SD_Init();
  MX_FATFS_Init();
  MX_I2C1_Init();
  MX_SPI3_Init();
  MX_TIM7_Init();
  MX_USART1_UART_Init();
  MX_SPI1_Init();

	 while (1)
	  {
		 if ((my_touch.stat == 1)||(my_touch.stat == 3))select_xy();
	}
}
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 6;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

void EXTI4_IRQHandler(void)
{
// gt911
	TouchCount911 = GT911_ReadTouch(&GT911Touch[0]);
	EXTI->PR |= TOUCH_IRQ_Pin;
	NVIC_ClearPendingIRQ(EXTI4_IRQn);
	if ((my_touch.stat == 0) && (TouchCount911 > 0))
	{
		my_touch.XX = GT911Touch[0].XCoordinate;
		my_touch.YY = GT911Touch[0].YCoordinate;
		my_touch.stat = 1;
		NVIC_DisableIRQ(EXTI4_IRQn);
	} else if ((my_touch.stat == 2) && (TouchCount911 == 0))
	{
		my_touch.stat = 3;
		NVIC_DisableIRQ(EXTI4_IRQn);
	}
}

а код main где?
Надеюсь вы не забыли в мейн включить s_var.h

не забыл…

Хотя Вы правы … даже без extern функция работает… а вот переменные нет…

так я только про функцию и писал. Для переменных extern нужен

Всё что реально классически нужно от заголовков это “ограждающий #ifdef” чтобы тело заголовка не включалось два раза в текущий модуль при инклюдах любой степени вложенности. Всё остальное вторично.
В целях оптимизации процесса сборки потом еще появились вещи типа #pragma once, и это очень круто, но оно ложится сверху этой классики, а классику лучше соблюдать.
Определениям функций реально вменяется extern, а определениям переменных - нет, но ничего не сломается если явно указывать, главное чтобы правильно было указано.

Да, да. Никогда не включаю #ifndef #define! От заголовочного файла нужны только прототипы. И не нужно ничего тут выдумывать.