#include <stm32f10x.h>
uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
uint16_t num = 0;
void delay(void)
{
uint16_t i;
for (i = 0; i < 20000; i++);
}
void ser_in(uint8_t data)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
GPIOB->BRR = GPIO_BRR_BR9; // SCLK=PB9
if (data & 0x80)
GPIOB->BSRR = GPIO_BSRR_BS7; // DIO=PB7
else
GPIOB->BRR = GPIO_BRR_BR7;
data <<= 1;
GPIOB->BSRR = GPIO_BSRR_BS9;
}
}
void par_out(void)
{
GPIOB->BRR = GPIO_BRR_BR8; // RCLK=PB8
GPIOB->BSRR = GPIO_BSRR_BS8;
}
void seg_scan(void)
{
uint8_t i;
uint16_t numbuf = num;
for (i = 0; i <= 4; i++)
{
ser_in(seg8[numbuf % 10]);
ser_in(1 << i);
par_out();
delay();
numbuf /= 10;
}
}
int main(void)
{
uint8_t i;
RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
PWR->CR |= PWR_CR_DBP; // 允許寫入後備寄存器
// 上電復位: PORRSTF=PINRSTF=1
// 復位鍵復位: PINRSTF=1
if (RCC->CSR & RCC_CSR_PORRSTF)
num = 1970; // 通電時寫入初值
else
num = BKP->DR1; // 復位時讀取寄存器值
if (RCC->CSR & RCC_CSR_PINRSTF)
BKP->DR1 = num + 1; // 每次復位都把寄存器的值加1
if (RCC->CSR & RCC_CSR_IWDGRSTF)
BKP->DR1 = num - 1; // 如果是看門狗復位則減去1
RCC->CSR |= RCC_CSR_RMVF; // 清除復位標誌信息
/* 配置GPIO口*/
RCC->APB2ENR = RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
GPIOB->CRL = 0x30000000;
GPIOB->CRH = 0x00000033;
GPIOC->CRL = 0x00000080; // PC1設為帶電阻輸入
GPIOC->BSRR = GPIO_BSRR_BS1; // PC1帶上拉電阻輸入
IWDG->KR = 0x5555; // 開始配置
IWDG->PR = 3; // 32分頻, f=40kHz/32=1250Hz->0.8ms
IWDG->RLR = 1250; // 定時時間: 1250*0.8ms=1s, 1250=0x4e2
// 寫入後不需要等待PVU, RVU標誌位清零
IWDG->KR = 0xcccc; // 啟動看門狗
IWDG->KR = 0xaaaa; // 導入上述配置
while (1)
{
for (i = 0; i < 20; i++)
seg_scan();
if ((GPIOC->IDR & GPIO_IDR_IDR1) == 0)
IWDG->KR = 0xaaaa; // 如果PC1鍵按住不放(低電平), 則餵狗
}
}