I know its been a while, but I wanted to put this here for others to use, and maybe get some feedback.
this is my first try at writing anything in c, I'm very much a beginner, that's probably why it's taken so long.
anyway, here's main.c from my project.
It might look janky, but it works. and other than some calibration I'll need to do when I'm home with a multimeter, it reports temps.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "usbd_cdc_if.h"
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
// Steinhart-Hart coefficients
#define A_COEFF 0.001125308852122
#define B_COEFF 0.000234711863267
#define C_COEFF 8.76711446883e-08
#define REFERENCE_RESISTANCE 20000.0 // 20 kΩ used for the temperature calculation
// Define the number of characters and segments
#define char_count 4
#define seg_count 7
// Define enumerations for segment and character names
typedef enum {
seg_a = 0,
seg_b,
seg_c,
seg_d,
seg_e,
seg_f,
seg_g,
} seg_name_t;
typedef enum {
char_1 = 0,
char_2,
char_3,
char_4,
} char_name_t;
// 2D array to hold segment data for each character
typedef struct {
const uint8_t reg; // LCD RAM register to write data to
const uint16_t mask; // Bit mask for the specific segment within the register
} seg_data_t;
seg_data_t seg_data[char_count][seg_count] = {
[char_1] = {
[seg_a] = { LCD_RAM_REGISTER0, 13 }, //0
[seg_b] = { LCD_RAM_REGISTER0, 14 }, //1
[seg_c] = { LCD_RAM_REGISTER4, 14 }, //2
[seg_d] = { LCD_RAM_REGISTER6, 13 }, //3
[seg_e] = { LCD_RAM_REGISTER4, 13 }, //4
[seg_f] = { LCD_RAM_REGISTER2, 13 }, //5
[seg_g] = { LCD_RAM_REGISTER2, 14 }, //6
},
[char_2] = {
[seg_a] = { LCD_RAM_REGISTER0, 11 },
[seg_b] = { LCD_RAM_REGISTER0, 12 },
[seg_c] = { LCD_RAM_REGISTER4, 12 },
[seg_d] = { LCD_RAM_REGISTER6, 11 },
[seg_e] = { LCD_RAM_REGISTER4, 11 },
[seg_f] = { LCD_RAM_REGISTER2, 11 },
[seg_g] = { LCD_RAM_REGISTER2, 12 },
},
[char_3] = {
[seg_a] = { LCD_RAM_REGISTER0, 6 },
[seg_b] = { LCD_RAM_REGISTER0, 10 },
[seg_c] = { LCD_RAM_REGISTER4, 10 },
[seg_d] = { LCD_RAM_REGISTER6, 6 },
[seg_e] = { LCD_RAM_REGISTER4, 6 },
[seg_f] = { LCD_RAM_REGISTER2, 6 },
[seg_g] = { LCD_RAM_REGISTER2, 10 },
},
[char_4] = {
[seg_a] = { LCD_RAM_REGISTER0, 1 },
[seg_b] = { LCD_RAM_REGISTER0, 5 },
[seg_c] = { LCD_RAM_REGISTER4, 5 },
[seg_d] = { LCD_RAM_REGISTER6, 1 },
[seg_e] = { LCD_RAM_REGISTER4, 1 },
[seg_f] = { LCD_RAM_REGISTER2, 1 },
[seg_g] = { LCD_RAM_REGISTER2, 5 },
},
};
const uint8_t SevenSegmentASCII[128] = {
0b00000000, /* 0 - */
0b00000000, /* 1 - */
0b00000000, /* 2 - */
0b00000000, /* 3 - */
0b00000000, /* 4 - */
0b00000000, /* 5 - */
0b00000000, /* 6 - */
0b00000000, /* 7 - */
0b00000000, /* 8 - */
0b00000000, /* 9 - */
0b00000000, /* 10 - */
0b00000000, /* 11 - */
0b00000000, /* 12 - */
0b00000000, /* 13 - */
0b00000000, /* 14 - */
0b00000000, /* 15 - */
0b00000000, /* 16 - */
0b00000000, /* 17 - */
0b00000000, /* 18 - */
0b00000000, /* 19 - */
0b00000000, /* 20 - */
0b00000000, /* 21 - */
0b00000000, /* 22 - */
0b00000000, /* 23 - */
0b00000000, /* 24 - */
0b00000000, /* 25 - */
0b00000000, /* 26 - */
0b00000000, /* 27 - */
0b00000000, /* 28 - */
0b00000000, /* 29 - */
0b00000000, /* 30 - */
0b00000000, /* 31 - */
0b00000000, /* 32 - space */
0b10000110, /* 33 - ! */
0b00100010, /* 34 - " */
0b01111110, /* 35 - # */
0b01101101, /* 36 - $ */
0b11010010, /* 37 - % */
0b01000110, /* 38 - & */
0b00100000, /* 39 - ' */
0b00101001, /* 40 - ( */
0b00001011, /* 41 - ) */
0b00100001, /* 42 - * */
0b01110000, /* 43 - + */
0b00010000, /* 44 - , */
0b01000000, /* 45 - - */
0b10000000, /* 46 - . */
0b01010010, /* 47 - / */
0b00111111, /* 48 - 0 */
0b00000110, /* 49 - 1 */
0b01011011, /* 50 - 2 */
0b01001111, /* 51 - 3 */
0b01100110, /* 52 - 4 */
0b01101101, /* 53 - 5 */
0b01111101, /* 54 - 6 */
0b00000111, /* 55 - 7 */
0b01111111, /* 56 - 8 */
0b01101111, /* 57 - 9 */
0b00001001, /* 58 - : */
0b00001101, /* 59 - ; */
0b01100001, /* 60 - < */
0b01001000, /* 61 - = */
0b01000011, /* 62 - > */
0b11010011, /* 63 - ? */
0b01011111, /* 64 - @ */
0b01110111, /* 65 - A */
0b01111100, /* 66 - B */
0b00111001, /* 67 - C */
0b01011110, /* 68 - D */
0b01111001, /* 69 - E */
0b01110001, /* 70 - F */
0b00111101, /* 71 - G */
0b01110110, /* 72 - H */
0b00110000, /* 73 - I */
0b00011110, /* 74 - J */
0b01110101, /* 75 - K */
0b00111000, /* 76 - L */
0b00010101, /* 77 - M */
0b00110111, /* 78 - N */
0b00111111, /* 79 - O */
0b01110011, /* 80 - P */
0b01101011, /* 81 - Q */
0b00110011, /* 82 - R */
0b01101101, /* 83 - S */
0b01111000, /* 84 - T */
0b00111110, /* 85 - U */
0b00111110, /* 86 - V */
0b00101010, /* 87 - W */
0b01110110, /* 88 - X */
0b01101110, /* 89 - Y */
0b01011011, /* 90 - Z */
0b00111001, /* 91 - [ */
0b01100100, /* 92 - \ */
0b00001111, /* 93 - ] */
0b00100011, /* 94 - ^ */
0b00001000, /* 95 - _ */
0b00000010, /* 96 - ` */
0b01011111, /* 97 - a */
0b01111100, /* 98 - b */
0b01011000, /* 99 - c */
0b01011110, /* 100 - d */
0b01111011, /* 101 - e */
0b01110001, /* 102 - f */
0b01101111, /* 103 - g */
0b01110100, /* 104 - h */
0b00010000, /* 105 - i */
0b00001100, /* 106 - j */
0b01110101, /* 107 - k */
0b00110000, /* 108 - l */
0b00010100, /* 109 - m */
0b01010100, /* 110 - n */
0b01011100, /* 111 - o */
0b01110011, /* 112 - p */
0b01100111, /* 113 - q */
0b01010000, /* 114 - r */
0b01101101, /* 115 - s */
0b01111000, /* 116 - t */
0b00011100, /* 117 - u */
0b00011100, /* 118 - v */
0b00010100, /* 119 - w */
0b01110110, /* 120 - x */
0b01101110, /* 121 - y */
0b01011011, /* 122 - z */
0b01000110, /* 123 - { */
0b00110000, /* 124 - | */
0b01110000, /* 125 - } */
0b00000001, /* 126 - ~ */
0b11111111, /* 127 - del */
};
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc;
LCD_HandleTypeDef hlcd;
RTC_HandleTypeDef hrtc;
/* USER CODE BEGIN PV */
uint32_t adc_value;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_LCD_Init(void);
static void MX_ADC_Init(void);
static void MX_RTC_Init(void);
/* USER CODE BEGIN PFP */
// Main function
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_LCD_Init();
MX_ADC_Init();
MX_RTC_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
void init_display(){
//All segments display test
/* RAM REG 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 A
0 LowBatt 1b 1a 2b 2a 3b 3a 4b 4a RUN F B
2 Profile 1g 1f 2g 2f 3g 3f 4g 4f CROSS G
4 degC 1c 1e 2c 2e 3c 3e 4c 4e TICK E C
6 degF % 1d 2dp 2d 3dp 3d 4d DIAG D dp
1111110000000000
5432109876543210 */
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER0, 0xFC63, 0b1111110001100011);
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER2, 0xFC63, 0b1111110001100011);
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER4, 0xFC63, 0b1111110001100011);
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER6, 0xFC63, 0b0111110001000011);
HAL_LCD_UpdateDisplayRequest(&hlcd);
HAL_Delay(1000);
HAL_LCD_Clear(&hlcd);
HAL_Delay(100);
}
void init_sensors(){
//show 'Init' on display
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER0, 0xFC63, 0x20);
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER2, 0xFC63, 0x6400);
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER4, 0xFC63, 0x3460);
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER6, 0xFC43, 0x2000);
HAL_LCD_UpdateDisplayRequest(&hlcd);
//instead of Delay below, change this to calibrate the temp sensor, maybe also show the battery percentage?
HAL_Delay(5000);
HAL_LCD_Clear(&hlcd);
}
void DisplayNumber(float number, int unit){ //units not implemented yet
// TODO UNITS using LCD symbols, input sanistisation?
// Round the number to the desired decimal places
int decimalPlaces = 0;
if (number < -999.5){
number = -999;
decimalPlaces = 0;}
else if (-999.5 < number && number < -99.95){
decimalPlaces = 0;}
else if (-99.95 < number && number < -9.95){
decimalPlaces = 1;}
else if (-9.95 < number && number < 99.95){
decimalPlaces = 2;}
else if (99.95 < number && number < 999.95){
decimalPlaces = 1;}
else if (999.95 < number && number < 9999.5){
decimalPlaces = 0;}
else if (number > 9999.5){
number = 9999;
decimalPlaces = 0;}
else {number = 0;
decimalPlaces = 2;}
double roundedNumber = number * pow(10, decimalPlaces);
roundedNumber = round(roundedNumber);
double unroundedNumber = roundedNumber / pow(10, decimalPlaces);
HAL_LCD_Clear(&hlcd);
if (decimalPlaces == 2){
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER6, 1 << 10, 1 << 10);
}
else if (decimalPlaces == 1){
HAL_LCD_Write(&hlcd, LCD_RAM_REGISTER6, 1 << 12, 1 << 12);
}
else;// (no decimal places)
for(int c=0; c < char_count; c++){ //For each Character:
int digit = (abs((int)(roundedNumber / pow(10, c)))) % 10; // Extract digit at position c
//char buffer[100]; // communicate on the USB serial as each digit is written
//int len = sprintf(buffer, "number: %f Input: %4.2f, dp: %d char %d, number: %d, ASCII: 0x%2X\r\n", number, unroundedNumber, decimalPlaces, c, digit, SevenSegmentASCII[digit + 48]);
//CDC_Transmit_FS((uint8_t *)buffer, len);
for(uint8_t s=0; s<seg_count; s++){ //each segment gets written
int bit = ((SevenSegmentASCII[digit + 48] >> s) & 1); //bitshift to the 's' segment and check if its a 1, (by ANDing segment with 1)
if (c == 3 && unroundedNumber < 0){ //is negative
bit = ((SevenSegmentASCII[45] >> s) & 1);
}
else if (c == 3 && 0 <= unroundedNumber && unroundedNumber < 10){//between 0 and 10
bit = ((SevenSegmentASCII[32] >> s) & 1);
}
HAL_LCD_Write(&hlcd, seg_data[c][s].reg, 0xFC63, bit << seg_data[c][s].mask); //unmask all bits, and write that segments position to the appropriate ram register.
}
}
HAL_LCD_UpdateDisplayRequest(&hlcd);
//HAL_Delay(1000);
}
void get_temp(){
//Trigger ADC conversion
HAL_ADC_Start(&hadc);
if (HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY) == HAL_OK) {
adc_value = HAL_ADC_GetValue(&hadc);
// Convert ADC value to temperature using Steinhart-Hart equation with calibration factor
float resistance = REFERENCE_RESISTANCE * ((float)adc_value / 4095.0); // Calibration factor
float temperature_kelvin = 1.0 / (A_COEFF + B_COEFF * log(resistance) + C_COEFF * pow(log(resistance), 3));
float temperature_celsius = temperature_kelvin - 273.15;
DisplayNumber(temperature_celsius,0);
// Prepare the data to be transmitted serial USB
char buffer[100];
int len = sprintf(buffer, "Raw ADC Value: %4lu - Temperature: %.2f\r\n", adc_value, temperature_celsius);
//Transmit data through USB
CDC_Transmit_FS((uint8_t *)buffer, len);
}
}
//Function to test the DisplayNumber Function with various 'testNumbers' values
/* void testFunctionNumbers(){
double testNumbers[] = {-999, -99.9, -9.99, -9.01, -1.234, 0, 5.678, 99.99, 999, 9999};
int numTests = sizeof(testNumbers) / sizeof(testNumbers[0]);
for (int i = 0; i < numTests; i++) {
// char buffer[100];
// int len = sprintf(buffer, "Input: %7.2f", testNumbers[i]);
// CDC_Transmit_FS((uint8_t *)buffer, len);
HAL_LCD_Clear(&hlcd);
DisplayNumber(testNumbers[i],0);
HAL_Delay(5000);
}
}
*/
/* //iterative test
void testFunctionIterate(){
for(double testValue=-1000.01; testValue < 10010; (testValue = testValue + 0.01)){
// char buffer[100];
// int len = sprintf(buffer, "Input: %7.2f\r\n", testValue);
// CDC_Transmit_FS((uint8_t *)buffer, len);
HAL_LCD_Clear(&hlcd);
DisplayNumber(testValue,0);
HAL_Delay(10);
}
}
*/
/* //Segment Test
void testFunctionCharacters(){ // this function doesn't rely on the Display numbers function, it interfaces directly with the display RAM.
// This tests the display displaying one digit one each character position.
for(int j=0; j < 10; j++){ // count to ten
HAL_LCD_Clear(&hlcd);
for(int i=0; i < char_count; i++){ //For each Character:
// char buffer[100]; // communicate on the USB serial as each digit is written
// int len = sprintf(buffer, "char %d, number: %d, ASCII: 0x%2X\r\n", i, j, SevenSegmentASCII[j + 48]);
// CDC_Transmit_FS((uint8_t *)buffer, len);
for(uint8_t k=0; k<seg_count; k++){ //each segment gets written
int data = ((SevenSegmentASCII[j + 48] >> k) & 1); //bitshift to the 'í' segment and check if its a 1, (by ANDing segment with 1)
HAL_LCD_Write(&hlcd, seg_data[i][k].reg, 1 << seg_data[i][k].mask, data << seg_data[i][k].mask); //unmask all bits, and write that segments position to the appropriate ram register.
}
HAL_LCD_UpdateDisplayRequest(&hlcd);
HAL_Delay(1000);
}
}
}
*/
//init_display();
//init_sensors(); // not implemented yet
//testFunctionCharacters();
//testFunctionNumbers();
//testFunctionIterate();
get_temp();
HAL_Delay(500);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI
|RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USB;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief ADC Initialization Function
* @param None
* @retval None
*/
static void MX_ADC_Init(void)
{
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC_Init 1 */
/* USER CODE END ADC_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC_Init 2 */
/* USER CODE END ADC_Init 2 */
}
/**
* @brief LCD Initialization Function
* @param None
* @retval None
*/
static void MX_LCD_Init(void)
{
/* USER CODE BEGIN LCD_Init 0 */
/* USER CODE END LCD_Init 0 */
/* USER CODE BEGIN LCD_Init 1 */
/* USER CODE END LCD_Init 1 */
hlcd.Instance = LCD;
hlcd.Init.Prescaler = LCD_PRESCALER_1;
hlcd.Init.Divider = LCD_DIVIDER_16;
hlcd.Init.Duty = LCD_DUTY_1_4;
hlcd.Init.Bias = LCD_BIAS_1_4;
hlcd.Init.VoltageSource = LCD_VOLTAGESOURCE_INTERNAL;
hlcd.Init.Contrast = LCD_CONTRASTLEVEL_3;
hlcd.Init.DeadTime = LCD_DEADTIME_0;
hlcd.Init.PulseOnDuration = LCD_PULSEONDURATION_4;
hlcd.Init.HighDrive = LCD_HIGHDRIVE_0;
hlcd.Init.BlinkMode = LCD_BLINKMODE_OFF;
hlcd.Init.BlinkFrequency = LCD_BLINKFREQUENCY_DIV8;
hlcd.Init.MuxSegment = LCD_MUXSEGMENT_DISABLE;
if (HAL_LCD_Init(&hlcd) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN LCD_Init 2 */
/* USER CODE END LCD_Init 2 */
}
/**
* @brief RTC Initialization Function
* @param None
* @retval None
*/
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 21;
sTime.Minutes = 35;
sTime.Seconds = 0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 29;
sDate.Year = 0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
/*Configure GPIO pin : PH0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/*Configure GPIO pin : PA3 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */