2013-05-09 34 views
3

我想創建一個簡單的程序,讀取RTC時鐘值並將其打印到串行監視器。 USART工作正常,但我無法弄清楚RTC有什麼問題。它一直給我setuRTC()中設置的相同值。第二個中斷也不起作用。編輯:我使用STM32f1開發板,一樣this不能讓RTC工作

這裏是我的RTC設置:

void setupRTC(void){ 
    RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); //Enable the power and backup interface clocks by setting the PWREN and BKPEN bitsin the RCC_APB1ENR register 
    PWR->CR |= PWR_CR_DBP;      //Enable access to the backup registers and the RTC. 
    RCC->BDCR |= RCC_BDCR_LSEON;    //External Low Speed oscillator enable 
    while((RCC->BDCR & RCC_BDCR_LSERDY) == 0); //Wait until external oscillisator is stabilised 
    RCC->BDCR |= RCC_BDCR_RTCSEL_LSE; 
    sendstr(textlse); 
    RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;   //Select Source (LSE oscillator clock used as RTC clock) 
    RCC->BDCR &= ~((1 << 8) | (1 << 9));  //Unusable clock source, here to prevent warnings, turn off clock sources to RTC. 
    RCC->BDCR = RCC_BDCR_RTCEN;    //RTC clock enable 
    RTC->CRL &= ~RTC_CRL_RSF;     //Clear registers Synchronized Flag 
    while(!(RTC->CRL & RTC_CRL_RSF));   //Wait for the RSF bit in RTC_CRL to be set by hardware 

    while((RTC->CRL & RTC_CRL_RTOFF) == 0); //Wait for RTOFF It is not possible to write to the RTC_CR register while the peripheral is completing a previous write operation 
    RTC->CRL |= RTC_CRL_CNF;     //Set the CNF bit to enter configuration mode 


    /* Set RTC COUNTER MSB word */ 
    RTC->CNTH = (12*3600 + 40*60 + 00) >> 16; //Random time 
    /* Set RTC COUNTER LSB word */ 
    RTC->CNTL = ((12*3600 + 40*60 + 00)& 0x0000FFFF); 
    RTC->CRH |= RTC_CRH_SECIE;     //Second Interrupt Enable 
    RTC->CRL &= ~RTC_CRL_CNF;     //Exit configuration mode 
    while((RTC->CRL & RTC_CRL_RTOFF) == 0); //Wait for RTOFF 
    sendstr(textconf); 
} 

這裏是整個程序:

#include "stm32f10x.h" 
#include <stdio.h> 

uint8_t text[] = {"\nSTM32 USART test ä ö \n"}; 
uint8_t textlse[] = {"LSE ready\n"}; 
uint8_t textconf[] = {"Configuration complete\n"}; 
char str[32]; // buffer for text 

uint8_t RxBuffer[1024]; 
int rxcount = 0; 
// Private function prototypes 
void sendstr(uint8_t * str); 
void sendChar(uint8_t ch); 
void sendTime(uint32_t ch); 
void setupRTC(void); 
void setupUSART(void); 
u32 rtc_get_counter_val(void); 



void setupRTC(void){ 
    RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); //Enable the power and backup interface clocks by setting the PWREN and BKPEN bitsin the RCC_APB1ENR register 
    PWR->CR |= PWR_CR_DBP;      //Enable access to the backup registers and the RTC. 
    RCC->BDCR |= RCC_BDCR_LSEON;    //External Low Speed oscillator enable 
    while((RCC->BDCR & RCC_BDCR_LSERDY) == 0); //Wait until external oscillisator is stabilised 
    RCC->BDCR |= RCC_BDCR_RTCSEL_LSE; 
    sendstr(textlse); 
    RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;   //Select Source (LSE oscillator clock used as RTC clock) 
    RCC->BDCR &= ~((1 << 8) | (1 << 9));  //Unusable clock source, here to prevent warnings, turn off clock sources to RTC. 
    RCC->BDCR = RCC_BDCR_RTCEN;    //RTC clock enable 
    RTC->CRL &= ~RTC_CRL_RSF;     //Clear registers Synchronized Flag 
    while(!(RTC->CRL & RTC_CRL_RSF));   //Wait for the RSF bit in RTC_CRL to be set by hardware 

    while((RTC->CRL & RTC_CRL_RTOFF) == 0); //Wait for RTOFF It is not possible to write to the RTC_CR register while the peripheral is completing a previous write operation 
    RTC->CRL |= RTC_CRL_CNF;     //Set the CNF bit to enter configuration mode 


    /* Set RTC COUNTER MSB word */ 
    RTC->CNTH = (12*3600 + 40*60 + 00) >> 16; //Random time 
    /* Set RTC COUNTER LSB word */ 
    RTC->CNTL = ((12*3600 + 40*60 + 00)& 0x0000FFFF); 
    RTC->CRH |= RTC_CRH_SECIE;     //Second Interrupt Enable 
    RTC->CRL &= ~RTC_CRL_CNF;     //Exit configuration mode 
    while((RTC->CRL & RTC_CRL_RTOFF) == 0); //Wait for RTOFF 
    sendstr(textconf); 
} 

void setupUSART(void){ 
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN; 
    USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; 
    USART1->BRR = (SystemCoreClock/115200); 
    GPIOA->CRH &= 0xFFFFF00F;         //Set RX(PA10) and TX(PA9) pins 
    GPIOA->CRH |= 0x000008A0;         //In TTL communication, TX pin must be conficured as pushpull 
    NVIC_EnableIRQ(USART1_IRQn); 
    USART1->CR1 |= USART_CR1_RXNEIE;       //Enable USART interrupt 
} 

int main(void) 
{ 
    vu32 dly; 
    uint32_t time; 
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;      //Enable clock for PC pins 
    GPIOC->CRL &= 0x00FFFFFF;         //Setup PC6 and PC6 leds 
    GPIOC->CRL |= 0x33000000; 
    setupUSART(); 
    setupRTC(); 
    sendstr(text); 


    while (1) 
    { 
     time = rtc_get_counter_val(); 
     sprintf(str, "%10d\n", time); 
     sendstr(str); 
     for(dly = 0; dly < 1000000; dly++); 
    } 
} 

void sendChar(uint8_t ch){ 
    while(!(USART1->SR & USART_SR_TXE)); 
     USART1->DR = ch; 

} 

void sendTime(uint32_t ch){ 
    while(!(USART1->SR & USART_SR_TXE)); 
     USART1->DR = ch; 

} 


void sendstr(uint8_t * str){ 
    while(*str != 0){ 
     sendChar(*str); 
     str++; 
    } 
} 


void USART1_IRQHandler(void){ 
    if(USART1->SR & 0x0020){ //content of the shift register is transferred to the RDR RXNE bit. 
     GPIOC->BSRR = (1 << 7); 
     RxBuffer[rxcount++] = (uint8_t)(USART1->DR & (uint8_t)USART_DR_DR); 
     USART1->SR = (uint16_t)~0x0020; 
     sendstr(RxBuffer); 
    } 
} 


void RTC_IRQHandler(void){ 
    if(RTC->CRL & RTC_CRL_SECF){ 
     GPIOC->BSRR = (1 << 7); 
     RTC->CRL &= ~RTC_CRL_SECF; 
    } 
} 



u32 rtc_get_counter_val(void) 
{ 
    return (RTC->CNTH << 16) | RTC->CNTL; 
} 
+0

有類似的問題,我的系統時鐘是HSI,當開始LSE時,它停留在無限循環,我等待LSE啓動。在你的情況下,它可能是AsynchPrediv和SynchPrediv的問題,你是否分別將它們設置爲0x7f和0xff。 – Ishmeet 2013-09-02 09:20:45

+0

我和STM32F103RE上的Ishmeet有同樣的問題。我懷疑RTC未啓用。 – 2015-03-07 14:22:18

回答

3

Mayby爲時已晚,但問題是,您不會將任何時鐘源設置給RTC。

下面的線需要被交換,從:

RCC->BDCR |= RCC_BDCR_RTCSEL_LSE; 
RCC->BDCR &= ~((1 << 8) | (1 << 9)); 

到:

RCC->BDCR &= ~((1 << 8) | (1 << 9)); 
RCC->BDCR |= RCC_BDCR_RTCSEL_LSE; 

這是您第一次設置之前正確的時鐘源,然後清除再次位的方式,不用計時就離開RTC。

+0

謝謝。我再也沒有這個代碼,但很久以前就開始工作了。這可能是這樣的。 – user1888162 2016-01-05 20:49:37

+0

這將是最好的回答你自己的問題... – 2016-01-07 00:10:49