#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键按住不放(低电平), 则喂狗 } }
|