Не удается заставить RTC работать

Я пытаюсь создать простую программу, которая считывает значение часов RTC и выводит его на серийный монитор. USART работает нормально, но я не могу понять, что неправильно с RTC. Это дает мне все то же значение, которое было установлено в setuRTC(). Также второе прерывание не работает. Изменить: я использую панель разработки STM32f1, такую ​​же, как this

Вот моя настройка 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>
******* text[] = {"\nSTM32 USART test ä ö \n"};
******* textlse[] = {"LSE ready\n"};
******* textconf[] = {"Configuration complete\n"};
char str[32]; // buffer for text
******* RxBuffer[1024];
int rxcount = 0;
// Private function prototypes
void sendstr(******* * str);
void sendChar(******* ch);
void sendTime(******** 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;
 ******** 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(******* ch){
 while(!(USART1->SR & USART_SR_TXE));
 USART1->DR = ch;
}
void sendTime(******** ch){
 while(!(USART1->SR & USART_SR_TXE));
 USART1->DR = ch;
}
void sendstr(******* * 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++] = (*******)(USART1->DR & (*******)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;
}
</stdio.h>
1 ответ

Майби слишком поздно, но проблема в том, что вы не устанавливаете источник синхронизации в 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 без синхронизации.

licensed under cc by-sa 3.0 with attribution.