Experiência de teste Pro, quando o RTC usa o relógio interno de baixa velocidade LSI, o processo de configuração do RTC

A seguir está o processo de configuração ao escrever o programa no início:

char RTCInit ()
{

contagem de caracteres = 0;

StartTime.year = 16;
StartTime.month = 3;
StartTime.day = 5;
StartTime.hour = 20;
StartTime.min = 41;
StartTime.sec = 0;
 
RCC_APB1PeriphClockCmd (RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, ENABLE);

PWR_BackupAccessCmd (ENABLE); // Ligue o domínio de backup, você pode acessar o registro de domínio de backup



// (Como os dados de configuração RTC estão no domínio de backup BKP, eles não serão perdidos, desde que Vbat ou VDD não sejam perdidos (mesmo se forem redefinidos), então você pode ler um valor de BKP para determinar se a energia é perdido e, em seguida, determina O RTC precisa inicializar a configuração)
if (BKP_ReadBackupRegister (BKP_DR1)! = 0xAA00) // Vbat e VDD desligados
{
BKP_DeInit (); // Reinicia a área de backup e limpa o registro BKP


/ (Parte de configuração do relógio)

// RCC_LSEConfig (RCC_LSE_ON); // Liga o oscilador de cristal externo de baixa velocidade LSE
RCC_LSICmd (ENABLE); // Liga o oscilador de cristal de baixa velocidade interno LSI

enquanto (RCC_GetFlagStatus (RCC_FLAG_LSIRDY) == 0 && contagem <11) 
// while (RCC_GetFlagStatus (RCC_FLAG_LSERDY) == 0 && count <11) // Aguarde o início do LSE e determine se a configuração foi bem-sucedida em 2S e retorne 0 se não tiver êxito
{
contagem ++;
delay_ms (200);
}

if (contagem == 10)
{
return 0; // LSI falhou ao iniciar a oscilação
}

RCC_RTCCLKConfig (RCC_RTCCLKSource_LSI);
// RCC_RTCCLKConfig (RCC_RTCCLKSource_LSE); // Use o oscilador de cristal externo de baixa velocidade LSE como fonte de relógio RTC

RCC_RTCCLKCmd (ENABLE); // Selecione para habilitar o relógio RTC


RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC (normalmente, desde que envolva a modificação do valor no RTC, esta função precisa ser adicionada após a modificação)
RTC_WaitForSynchro (); // Aguarde a sincronização com APB1 antes de ler o registro RTC


/ (Registrar parte de configuração)

RTC_EnterConfigMode (); // Permitir configuração RTC
RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC


RTC_SetPrescaler (40000); // 1HZ após divisão de frequência
// RTC_SetPrescaler (32767); // 1HZ após divisão de frequência
RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC

   // RTC_ClearITPendingBit (RTC_IT_ALR);
   // RTC_WaitForLastTask ();

RTC_ITConfig (RTC_IT_ALR, DISABLE); // Habilita a interrupção do alarme. Segunda interrupção RTC_IT_SEC

RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC


SetWriteTime (& StartTime); // Grava o calendário de início no RTC


RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC

RTC_ExitConfigMode (); // Saia do modo de configuração RTC


BKP_WriteBackupRegister (BKP_DR1, 0xAA00); // Grave os dados de julgamento de perda de potência desejados
GPIOInit (GPIOA, GPIO_Pin_2, GPIO_Mode_Out_PP); // LED PA2

}

else // foi inicializado uma vez e não desligado
{

RTC_WaitForSynchro (); // Aguarde a sincronização com APB1 antes de ler o registro RTC
RTC_EnterConfigMode (); // Permitir configuração RTC

RTC_ITConfig (RTC_IT_ALR, DISABLE); // Habilita a interrupção do alarme. Segunda interrupção RTC_IT_SEC

RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC

RTC_ExitConfigMode (); // Saia do modo de configuração RTC
RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC

GPIOInit (GPIOA, GPIO_Pin_6, GPIO_Mode_Out_PP); // LED PA6
}


return 1; // A configuração foi bem-sucedida
}


O resultado do experimento mostra que a luz LED do PA2 pode acender quando o MCU é ligado, mas quando o reset é pressionado, a luz LED do PA6 não funciona. Normalmente, o RTC só precisa ser configurado uma vez sem falha de energia Após pressionar reset, ele deve inserir a instrução else., E então acender o LED PA6, mas não está. Por meio da depuração online, constatou-se que o programa morreu na função de sincronização de RTC_WaitForSynchro () ;.

Através de várias depurações, o programa ainda está travado, então eu suspeito que seja causado pela instabilidade do relógio interno de baixa velocidade LSI? (O motivo específico ainda não está claro?), Mas quando copio a parte de configuração do relógio do RTC para a instrução else, um milagre aconteceu. Após a reinicialização, o LED do PA6 pode acender. Portanto, independentemente de ligar ou reiniciar, o relógio RST precisa ser reconfigurado. Portanto, há a seguinte função de configuração correta:


char RTCInit ()

{

contagem de caracteres = 0;


StartTime.year = 16;
StartTime.month = 3;
StartTime.day = 5;
StartTime.hour = 20;
StartTime.min = 41;
StartTime.sec = 0;
 
RCC_APB1PeriphClockCmd (RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, ENABLE);

PWR_BackupAccessCmd (ENABLE); // Ligue o domínio de backup, você pode acessar o registro de domínio de backup

// (Como os dados de configuração RTC estão no domínio de backup BKP, eles não serão perdidos, desde que Vbat ou VDD não sejam perdidos (mesmo se forem reiniciados), então você pode ler um valor de BKP para determinar se a potência é perdido e, em seguida, determina O RTC precisa inicializar a configuração)
if (BKP_ReadBackupRegister (BKP_DR1)! = 0xAA00) // Vbat e VDD desligados
{

BKP_DeInit (); // Reinicia a área de backup e limpa o registro BKP

/ (Parte de configuração do relógio)

RCC_LSICmd (ENABLE); // Liga o oscilador de cristal de baixa velocidade interno LSI

while (RCC_GetFlagStatus (RCC_FLAG_LSIRDY) == 0 && count <11) // Aguarde o início do LSI e determine se a configuração foi bem-sucedida em 2S e retorne 0 se não tiver êxito
{
contagem ++;
delay_ms (200);
}

if (contagem == 10)
{
return 0; // LSI falhou ao iniciar a oscilação
}

RCC_RTCCLKConfig (RCC_RTCCLKSource_LSI);

RCC_RTCCLKCmd (ENABLE); // Selecione para habilitar o relógio RTC


RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC (normalmente, desde que envolva a modificação do valor no RTC, esta função precisa ser adicionada após a modificação)
RTC_WaitForSynchro (); // Aguarde a sincronização com APB1 antes de ler o registro RTC


/ (Registrar parte de configuração)

RTC_EnterConfigMode (); // Permitir configuração RTC
RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC


RTC_SetPrescaler (40000); // 1HZ após divisão de frequência
// RTC_SetPrescaler (32767); // 1HZ após divisão de frequência
RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC


RTC_ITConfig (RTC_IT_ALR, DISABLE); // Habilita a interrupção do alarme. Segunda interrupção RTC_IT_SEC

RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC


SetWriteTime (& StartTime); // Grava o calendário de início no RTC


RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC

RTC_ExitConfigMode (); // Saia do modo de configuração RTC


BKP_WriteBackupRegister (BKP_DR1, 0xAA00); // Grave os dados de julgamento de perda de potência desejados
GPIOInit (GPIOA, GPIO_Pin_2, GPIO_Mode_Out_PP); // LED PA2

}

else // foi inicializado uma vez e não desligado
{
/ (Parte de configuração do relógio)
RCC_LSICmd (ENABLE); // Liga o oscilador de cristal de baixa velocidade interno LSI

enquanto (RCC_GetFlagStatus (RCC_FLAG_LSIRDY) == 0 && contagem <11) 
{
contagem ++;
delay_ms (200);
}

if (contagem == 10)
{
return 0; // LSI falhou ao iniciar a oscilação
}

RCC_RTCCLKConfig (RCC_RTCCLKSource_LSI);

RCC_RTCCLKCmd (ENABLE); // Selecione para habilitar o relógio RTC


RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC (normalmente, desde que envolva a modificação do valor no RTC, esta função precisa ser adicionada após a modificação)
RTC_WaitForSynchro (); // Aguarde a sincronização com APB1 antes de ler o registro RTC

/ (Registrar parte de configuração)

RTC_EnterConfigMode (); // Permitir configuração RTC

RTC_ITConfig (RTC_IT_ALR, DISABLE); // Habilita a interrupção do alarme. Segunda interrupção RTC_IT_SEC

RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC

RTC_ExitConfigMode (); // Saia do modo de configuração RTC
RTC_WaitForLastTask (); // Aguarde a conclusão da última tarefa de gravação RTC

GPIOInit (GPIOA, GPIO_Pin_6, GPIO_Mode_Out_PP); // LED PA6
}


return 1; // A configuração foi bem-sucedida
}

Acho que você gosta

Origin blog.csdn.net/ludaoyi88/article/details/50822348
Recomendado
Clasificación