2013-05-09 35 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