c++ - Can't get the RTC to work -
i trying create simple program reads rtc clock value , prints serial monitor. usart working fine, can't figure out what's wrong rtc. giving me time same value set in seturtc(). second interrupt not working either. edit: using stm32f1 development board, same this
here rtc setup:
void setuprtc(void){ rcc->apb1enr |= (rcc_apb1enr_pwren | rcc_apb1enr_bkpen); //enable power , backup interface clocks setting pwren , bkpen bitsin rcc_apb1enr register pwr->cr |= pwr_cr_dbp; //enable access backup registers , rtc. rcc->bdcr |= rcc_bdcr_lseon; //external low speed oscillator enable while((rcc->bdcr & rcc_bdcr_lserdy) == 0); //wait until external oscillisator stabilised rcc->bdcr |= rcc_bdcr_rtcsel_lse; sendstr(textlse); rcc->bdcr |= rcc_bdcr_rtcsel_lse; //select source (lse oscillator clock used rtc clock ) rcc->bdcr &= ~((1 << 8) | (1 << 9)); //unusable clock source, here prevent warnings, turn off clock sources 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 rsf bit in rtc_crl set hardware while((rtc->crl & rtc_crl_rtoff) == 0); //wait rtoff not possible write rtc_cr register while peripheral completing previous write operation rtc->crl |= rtc_crl_cnf; //set cnf bit 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 rtoff sendstr(textconf); }
here whole program:
#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 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 power , backup interface clocks setting pwren , bkpen bitsin rcc_apb1enr register pwr->cr |= pwr_cr_dbp; //enable access backup registers , rtc. rcc->bdcr |= rcc_bdcr_lseon; //external low speed oscillator enable while((rcc->bdcr & rcc_bdcr_lserdy) == 0); //wait until external oscillisator stabilised rcc->bdcr |= rcc_bdcr_rtcsel_lse; sendstr(textlse); rcc->bdcr |= rcc_bdcr_rtcsel_lse; //select source (lse oscillator clock used rtc clock ) rcc->bdcr &= ~((1 << 8) | (1 << 9)); //unusable clock source, here prevent warnings, turn off clock sources 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 rsf bit in rtc_crl set hardware while((rtc->crl & rtc_crl_rtoff) == 0); //wait rtoff not possible write rtc_cr register while peripheral completing previous write operation rtc->crl |= rtc_crl_cnf; //set cnf bit 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 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) , tx(pa9) pins gpioa->crh |= 0x000008a0; //in ttl communication, tx pin must conficured 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 pc pins gpioc->crl &= 0x00ffffff; //setup pc6 , 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 shift register transferred 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; }
mayby late problem not set clock source rtc.
the following lines need swapped, from:
rcc->bdcr |= rcc_bdcr_rtcsel_lse; rcc->bdcr &= ~((1 << 8) | (1 << 9));
to:
rcc->bdcr &= ~((1 << 8) | (1 << 9)); rcc->bdcr |= rcc_bdcr_rtcsel_lse;
the way before first set correctly clock source, , cleared again bits, leaving rtc without clocking.
Comments
Post a Comment