#include <stm32f10x.h>
#define _BV(n) (1 << (n))
uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
uint8_t num = 0;
void delay(void)
{
uint32_t i;
for (i = 0; i < 20000; i++);
}
void SerIn(uint8_t data)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
GPIOC->BRR = _BV(15);
if (data & 0x80)
GPIOC->BSRR = _BV(13);
else
GPIOC->BRR = _BV(13);
GPIOC->BSRR = _BV(15);
data <<= 1;
}
}
void ParOut(void)
{
GPIOC->BRR = _BV(14);
GPIOC->BSRR = _BV(14);
}
int main(void)
{
// CNF=00: push-pull, MODE=11: 50MHz
RCC->APB2ENR = 0x810; // 开启PC和TIM1时钟
GPIOC->CRH = 0x33300000; // PC13~15设为输出
// 显示E
SerIn(0x86);
SerIn(_BV(7));
ParOut();
TIM1->ARR = 0xffff; // 计数量 (auto-reload register, 16位)
TIM1->PSC = 3; // 4分频 (prescaler, 16位)
TIM1->RCR = 255; // 定时器溢出指定次数后才触发中断 (repetition counter register, 8位)
TIM1->DIER = 0x01; // 允许定时器1中断产生 (DMA/interrupt enable register, UIE: Update interrupt enable = 1)
NVIC->ISER[0] = _BV(25); // 允许执行定时器1中断服务函数, 编号为25
TIM1->CR1 = 0x01; // 开启定时器1 (control register 1, CEN: Counter enable = 1)
while (1)
{
SerIn(seg8[num % 10]);
SerIn(_BV(0));
ParOut();
delay();
SerIn(seg8[num % 100 / 10]);
SerIn(_BV(1));
ParOut();
delay();
}
}
// 定时器中断函数
void TIM1_UP_IRQHandler(void)
{
TIM1->SR &= ~_BV(0); // Status register (UIF: Update interrupt flag = 0)
num++;
if (num >= 100)
num = 0;
}