Не могу заставить RTC работать

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

Вот моя настройка 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;
}

3

Решение

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

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]