一派掌門 二十級              | 
          
            
            
             
              #include <stdio.h> #include <string.h> #include <stm32f10x.h>
  #define BIT(reg, bit) (((reg) & (bit)) != 0)
  struct fifo {     uint8_t buf[127];     uint8_t front;     uint8_t rear; } usartbuf;
  void fifo_init(struct fifo *f) {     f->front = f->rear = 0; }
  uint8_t fifo_full(struct fifo *f) {     return f->front == (f->rear + 1) % sizeof(f->buf); }
  uint8_t fifo_empty(struct fifo *f) {     return f->front == f->rear; }
  uint8_t fifo_in(struct fifo *f, uint8_t data) {     if (fifo_full(f))         return 0;     f->buf[f->rear] = data;     f->rear = (f->rear + 1) % sizeof(f->buf);     return 1; }
  uint8_t fifo_out(struct fifo *f, uint8_t *data) {     if (fifo_empty(f))         return 0;     *data = f->buf[f->front];     f->front = (f->front + 1) % sizeof(f->buf);     return 1; }
  int fputc(int ch, FILE *fp) {     if (fp == &__stdout)     {         if (ch == '\n')         {             USART1->DR = '\r';             while ((USART1->SR & USART_SR_TXE) == 0);         }         USART1->DR = ch;         while ((USART1->SR & USART_SR_TXE) == 0);     }     return ch; }
  int fgetc(FILE *fp) {     uint8_t value;     if (fp == &__stdin)     {         while (!fifo_out(&usartbuf, &value));         return value;     }     return 0; }
  int main(void) {     char str[21];     uint32_t value;     RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;     PWR->CR = PWR_CR_DBP;          RCC->BDCR = RCC_BDCR_BDRST; // Backup Domain必須要復位後才能重設RTC時鐘          // HSE/128: 外部大晶振128分頻     //RCC->BDCR = RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL;          // LSE: 外部小晶振     //RCC->BDCR = RCC_BDCR_LSEON;     //while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0);     //RCC->BDCR |= RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0;          // LSI: 內部小晶振     RCC->CSR = RCC_CSR_LSION;     while ((RCC->CSR & RCC_CSR_LSIRDY) == 0);     RCC->BDCR = RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1;          fifo_init(&usartbuf);     RCC->APB2ENR = RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;     GPIOA->CRH = 0x4b0;     USART1->BRR = 0x271;     USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;     NVIC_EnableIRQ(USART1_IRQn);     printf("PWR->CR=0x%x, RCC->BDCR=0x%x, RCC->CSR=0x%x\n", PWR->CR, RCC->BDCR, RCC->CSR);          NVIC_EnableIRQ(RTC_IRQn);     while (1)     {         scanf("%20s", str);         if (strcmp(str, "test") == 0)             printf("Hello World!\n");         else if (strcmp(str, "fifopos") == 0)             printf("pos=%d\n", usartbuf.front);         else if (strcmp(str, "get") == 0)         {             scanf("%20s", str);             if (strcmp(str, "RTC_CRH") == 0)                 printf("OWIE=%d ALRIE=%d SECIE=%d\n", BIT(RTC->CRH, RTC_CRH_OWIE), BIT(RTC->CRH, RTC_CRH_ALRIE), BIT(RTC->CRH, RTC_CRH_SECIE));             else if (strcmp(str, "RTC_CRL") == 0)                 printf("RTOFF=%d CNF=%d RSF=%d OWF=%d ALRF=%d SECF=%d\n", BIT(RTC->CRL, RTC_CRL_RTOFF), BIT(RTC->CRL, RTC_CRL_CNF), BIT(RTC->CRL, RTC_CRL_RSF), BIT(RTC->CRL, RTC_CRL_OWF), BIT(RTC->CRL, RTC_CRL_ALRF), BIT(RTC->CRL, RTC_CRL_SECF));             else if (strcmp(str, "RTC_DIV") == 0)                 printf("%d\n", (RTC->DIVH << 16) | RTC->DIVL);             else if (strcmp(str, "RTC_CNT") == 0)                 printf("%d\n", (RTC->CNTH << 16) | RTC->CNTL);             else                 printf("Unknown register: %s!\n", str);         }         else if (strcmp(str, "set") == 0)         {             scanf("%20s", str);             while ((RTC->CRL & RTC_CRL_RTOFF) == 0);             if (strcmp(str, "RTC_CRH") == 0)             {                 scanf("%x", &value);                 RTC->CRH = value & 7;             }             else if (strcmp(str, "RTC_CRL") == 0)             {                 scanf("%x", &value);                 RTC->CRL = value & 0x1f;             }             else if (strcmp(str, "RTC_PRL") == 0)             {                 scanf("%d", &value);                 RTC->PRLL = value & 0xffff;                 RTC->PRLH = (value >> 16) & 0x0f;             }             else if (strcmp(str, "RTC_CNT") == 0)             {                 scanf("%d", &value);                 RTC->CNTL = value & 0xffff;                 RTC->CNTH = (value >> 16) & 0xffff;             }             else if (strcmp(str, "RTC_ALR") == 0)             {                 scanf("%d", &value);                 RTC->ALRL = value & 0xffff;                 RTC->ALRH = (value >> 16) & 0xffff;             }             else                 printf("Unknown register: %s!\n", str);         }         else if (str[0] != ';')             printf("Unknown command: %s!\n", str);     } }
  void USART1_IRQHandler(void) {     if (USART1->SR & USART_SR_RXNE)         fifo_in(&usartbuf, USART1->DR); }
  void RTC_IRQHandler(void) {     uint8_t data = RTC->CRL;     RTC->CRL &= ~RTC->CRH;     printf("Interrupt triggered: RTC_CRL=0x%x\n", data); }              
                       |