目前共有1篇帖子。 內容轉換:不轉換▼
 
點擊 回復
338 0
今天晚上写的串口控制的RTC时钟程序
一派護法 十九級
1樓 發表于:2017-3-22 22:49
#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);
}

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:338 回複數:0
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2017-3-22 22:49
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。