#include "stm32c0xx_hal.h"
// Define pins for digits and segments
#define DIGIT_1_PIN GPIO_PIN_0
#define DIGIT_2_PIN GPIO_PIN_1
#define DIGIT_3_PIN GPIO_PIN_2
#define DIGIT_4_PIN GPIO_PIN_3
#define DIGIT_PORT GPIOD
#define SEG_A_PIN GPIO_PIN_0
#define SEG_B_PIN GPIO_PIN_1
#define SEG_C_PIN GPIO_PIN_2
#define SEG_D_PIN GPIO_PIN_3
#define SEG_E_PIN GPIO_PIN_4
#define SEG_F_PIN GPIO_PIN_5
#define SEG_G_PIN GPIO_PIN_6
#define SEG_DP_PIN GPIO_PIN_7
#define SEGMENT_PORT GPIOA
// Segment patterns for digits 0-9 (common anode - inverted logic)
const uint8_t digit_patterns[10] = {
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90 // 9
};
uint8_t display_buffer[4] = {0}; // Display buffer for each digit
uint8_t current_digit = 0; // Currently active digit
uint32_t last_display_update = 0;
void setup() {
// Enable GPIO clocks
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
// Configure digit pins as output
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DIGIT_1_PIN | DIGIT_2_PIN | DIGIT_3_PIN | DIGIT_4_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DIGIT_PORT, &GPIO_InitStruct);
// Configure segment pins as output
GPIO_InitStruct.Pin = SEG_A_PIN | SEG_B_PIN | SEG_C_PIN | SEG_D_PIN |
SEG_E_PIN | SEG_F_PIN | SEG_G_PIN | SEG_DP_PIN;
HAL_GPIO_Init(SEGMENT_PORT, &GPIO_InitStruct);
// Turn off all digits initially
HAL_GPIO_WritePin(DIGIT_PORT, DIGIT_1_PIN | DIGIT_2_PIN | DIGIT_3_PIN | DIGIT_4_PIN, GPIO_PIN_RESET);
// Set initial display value
display_buffer[0] = 1;
display_buffer[1] = 2;
display_buffer[2] = 3;
display_buffer[3] = 4;
}
void loop() {
uint32_t now = HAL_GetTick();
// Update display every 5ms
if (now - last_display_update >= 5) {
// Turn off all digits
HAL_GPIO_WritePin(DIGIT_PORT, DIGIT_1_PIN | DIGIT_2_PIN | DIGIT_3_PIN | DIGIT_4_PIN, GPIO_PIN_RESET);
// Set segments for current digit
uint8_t pattern = digit_patterns[display_buffer[current_digit]];
SEGMENT_PORT->ODR = (SEGMENT_PORT->ODR & 0xFF00) | pattern;
// Enable current digit
switch(current_digit) {
case 0: HAL_GPIO_WritePin(DIGIT_PORT, DIGIT_1_PIN, GPIO_PIN_SET); break;
case 1: HAL_GPIO_WritePin(DIGIT_PORT, DIGIT_2_PIN, GPIO_PIN_SET); break;
case 2: HAL_GPIO_WritePin(DIGIT_PORT, DIGIT_3_PIN, GPIO_PIN_SET); break;
case 3: HAL_GPIO_WritePin(DIGIT_PORT, DIGIT_4_PIN, GPIO_PIN_SET); break;
}
// Move to next digit
current_digit = (current_digit + 1) % 4;
last_display_update = now;
}
// For example, increment the display value every second
static uint32_t last_counter_update = 0;
static uint16_t counter = 0;
if (now - last_counter_update >= 1000) {
counter++;
if (counter > 9999) counter = 0;
// Update display buffer
display_buffer[0] = counter / 1000;
display_buffer[1] = (counter / 100) % 10;
display_buffer[2] = (counter / 10) % 10;
display_buffer[3] = counter % 10;
last_counter_update = now;
}
}
int main(void) {
HAL_Init();
setup();
while (1) {
loop();
}
}