一派掌門 二十級 |
#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); }
|