/**
******************************************************************************
* @file : main.c
* @author : Auto-generated by STM32CubeIDE
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
#include <stdint.h>
#include "stm32f103xb.h"
#define CAT0_PIN 9
#define CAT1_PIN 10
void display(int num, int dig);
void delay_ms(uint16_t t);
int main(void)
{
// Enable GPIOA clock
RCC->APB2ENR |= 1UL << 2;
// Set PA0-PA6 as 2MHz push-pull output
GPIOA->CRL = 0x02222222;
GPIOA->CRH = 0x00000220; // MODEn = 10 (2MHz Output)
GPIOA->ODR |= 0x0000007F;
GPIOA->ODR &= ~(1 << CAT0_PIN | 1 << CAT1_PIN); // PA<10:9> = 0
// Enable GPIOC clock
RCC->APB2ENR |= 1UL << 4;
// Set PC13 as 2MHz push-pull output
GPIOC->CRH &= ~(0x0FUL << 20); // MODE13=00, CNF13=00
GPIOC->CRH |= 1UL << 21; // MODE13 = 10 (2MHz output)
// Loop
int units = 0, dec = 0, tick = 0;
while ( 1 )
{
// Seven segment multiplexing
display(units,0);
delay_ms(1000); // It should be 1ms in real-time
display(dec,1);
delay_ms(1000); // It should be 1ms in real-time
// Update counters each second
++units;
if(units == 10)
{
units = 0;
dec++;
if(dec==10)
{
dec=0;
}
}
}
}
void display(int num, int dig)
{
// Cathode control (Digit selection)
GPIOA->ODR &= ~((1 << CAT0_PIN) | (1 << CAT1_PIN));
if(dig == 0) GPIOA->ODR |= (1 << CAT0_PIN);
else GPIOA->ODR |= (1 << CAT1_PIN);
// Display value
GPIOA->ODR &= ~0x0000007F;
switch(num)
{
case 0: GPIOA->ODR |= (0b1000000); break;
case 1: GPIOA->ODR |= (0b1111001); break;
case 2: GPIOA->ODR |= (0b0100100); break;
case 3: GPIOA->ODR |= (0b0110000); break;
case 4: GPIOA->ODR |= (0b0011001); break;
case 5: GPIOA->ODR |= (0b0010010); break;
case 6: GPIOA->ODR |= (0b0000010); break;
case 7: GPIOA->ODR |= (0b1111000); break;
case 8: GPIOA->ODR |= (0b0000000); break;
case 9: GPIOA->ODR |= (0b0010000); break;
default: GPIOA->ODR |= (0b1111111); break; // All turn off
}
}
void delay_ms(uint16_t t) {
volatile unsigned long l = 0;
for(uint16_t i = 0; i < t; i++)
{
for(l = 0; l < 800; l++);
}
}