1、STM32F103的RTC(实时时钟)原理
STM32F103是STMicroelectronics推出的一款基于ARM Cortex-M3内核的微控制器,它内置了RTC(实时时钟)模块,用于提供精确的时间计数和日期功能。
RTC模块的原理是通过一个独立的32.768 kHz的低频晶振来提供时钟脉冲,这个低频晶振可以提供非常精确的时钟信号。RTC模块可以提供秒、分钟、小时、日期、月份和年份的计数和显示功能,同时还可以提供闹钟功能和定时功能。
STM32F103的RTC模块提供了自动闹钟、自动唤醒、定时器和日历功能,可以通过软件配置来实现各种功能。RTC模块还提供了备份寄存器,用于保存RTC模块的配置和状态信息,以便在掉电后能够继续保持数据。
通过STM32F103的RTC模块,可以实现精确的时间计数和日期显示功能,适用于各种需要时间计数和日期显示的应用场景,比如智能家居、工业控制、汽车电子等领域。
2、读取STM32F103C8T6 内部的时钟(年月日时分秒),日历(星期x),1秒周期,通过串口输出到PC上位机
1、cubemx设置部分
(1)设置rcc
(2)设置rtc
(3)设置usart1
(4)设置时钟树
(5)创建工程并打开工程
2、代码修改部分
(1)
main.c中添加如下代码段
RTC_DateTypeDef GetData; //获取日期结构体
RTC_TimeTypeDef GetTime; //获取时间结构体
定义时间和日期的结构体用来获取时间和日期
(2)在main函数中重写fputc函数,完成printf函数的重定向
//添加头文件#include "stdio.h"
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return ch;
}
(3)在while函数中添加
/* Get the RTC current Time */
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
/* Get the RTC current Date */
HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
/* Display date Format : yy/mm/dd */
printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
/* Display time Format : hh:mm:ss */
printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
printf("\r\n");
HAL_Delay(1000);
之后完成烧录便可在串口调制工具中得到如下结果
fireTools 2023-11-25 20-18-29
在代码中继续添加
/* Display date Format : weekday */
if(GetData.WeekDay==1){
printf("星期一\r\n");
}else if(GetData.WeekDay==2){
printf("星期二\r\n");
}else if(GetData.WeekDay==3){
printf("星期三\r\n");
}else if(GetData.WeekDay==4){
printf("星期四\r\n");
}else if(GetData.WeekDay==5){
printf("星期五\r\n");
}else if(GetData.WeekDay==6){
printf("星期六\r\n");
}else if(GetData.WeekDay==7){
printf("星期日\r\n");
}
重新烧录并运行可得到如下结果:
fireTools 2023-11-25 20-20-35
3、 数字温度计
这里的要求是是显示日历,和温湿度,而前面做过温湿度显示的工程,便可在原来的工程中进行修改。
(1)main.c文件修改
#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "Delay.h"
#include "LED.h"
#include "usart.h"
#include "dht11.h"
extern unsigned int rec_data[4];
int main(void)
{
OLED_Init();
OLED_ShowHZ(3,5,0); //温
OLED_ShowHZ(3,7,2); //度
OLED_ShowHZ(3,9,4); //:
OLED_ShowHZ(3,12,2); //度
OLED_ShowHZ(4,5,8); //湿
OLED_ShowHZ(4,7,10); //度
OLED_ShowHZ(4,9,4); //:
OLED_ShowChar(4,12,'%');//%
int year=2023;
int month=11;
int day=20;
int hour=23;
int min=59;
int s=55;
while (1)
{
OLED_ShowHZ(1,2,18);//日
OLED_ShowHZ(1,4,20);//期
OLED_ShowNum(1,7,year,4);//2023
OLED_ShowHZ(1,11,22);//年
OLED_ShowNum(1,13,month,2);//11
OLED_ShowHZ(1,15,24);//月
OLED_ShowNum(2,1,day,2);//20
OLED_ShowHZ(2,3,26);//日
OLED_ShowNum(2,5,hour,2);//15
OLED_ShowHZ(2,7,30);//时
OLED_ShowNum(2,9,min,2);//40
OLED_ShowHZ(2,11,32);//分
OLED_ShowNum(2,13,s,2);//s
OLED_ShowHZ(2,15,28);//秒
//OLED_ShowString(2,17,"Mon");
DHT11_REC_Data(); //接收dht11数据
OLED_ShowNum(3,10,rec_data[0]-5,2);
OLED_ShowNum(4,10,rec_data[0]-13,2);
s+=1;
if(s>=60)
{
s=0;
min++;
}
if(min>=60)
{
min=0;
hour++;
}
if(hour>=24)
{
hour=0;
day++;
}
if(day>=31)
{
month++;
day=1;
}
if(month>12)
{
year++;
month=1;
}
Delay_s(1);
}
}
(2)AHT20文件代码:
#include "stm32f10x.h" // Device header
#include "dht11.h"
#include "delay.h"
unsigned int rec_data[4];
void DH11_GPIO_Init_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //????
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void DH11_GPIO_Init_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void DHT11_Start(void)
{
DH11_GPIO_Init_OUT();
dht11_high;
Delay_us(30);
dht11_low; //??????18us
Delay_ms(20);
dht11_high; //????20~40us
Delay_us(30);
DH11_GPIO_Init_IN(); //????
}
//??????
char DHT11_Rec_Byte(void)
{
unsigned char i = 0;
unsigned char data;
for(i=0;i<8;i++) //1?????1???byte,1???byte?8?bit
{
while( Read_Data == 0); //?1bit??,???????,???????
Delay_us(30); //??30us???????0???1,0??26~28us
data <<= 1; //??
if( Read_Data == 1 ) //????30us???????????1
{
data |= 1; //??+1
}
while( Read_Data == 1 ); //???????,???????
}
return data;
}
//????
void DHT11_REC_Data(void)
{
unsigned int R_H,R_L,T_H,T_L;
unsigned char RH,RL,TH,TL,CHECK;
DHT11_Start(); //??????
dht11_high; //????
if( Read_Data == 0 ) //??DHT11????
{
while( Read_Data == 0); //???????,???????
while( Read_Data == 1); //???????,???????
R_H = DHT11_Rec_Byte();
R_L = DHT11_Rec_Byte();
T_H = DHT11_Rec_Byte();
T_L = DHT11_Rec_Byte();
CHECK = DHT11_Rec_Byte(); //??5???
dht11_low; //????bit???????,DHT11???? 50us
Delay_us(55); //????55us
dht11_high; //??????????????????
if(R_H + R_L + T_H + T_L == CHECK) //??????,??????????????
{
RH = R_H;
RL = R_L;
TH = T_H;
TL = T_L;
}
}
rec_data[0] = RH;
rec_data[1] = RL;
rec_data[2] = TH;
rec_data[3] = TL;
}
烧录后实现该功能。