MAX7219数码管+RTC时钟——stm32
rtc.c文件如下:具体请查看原子哥正点原子RTC实时时钟例程,发现BUG , 求解决。-OpenEdv-开源电子网
#include "sys.h"
#include "delay.h"
#include "rtc.h"
#include "stdio.h"
_calendar_obj calendar;//时钟结构体
//static void RTC_NVIC_Config(void)
//{
// NVIC_InitTypeDef NVIC_InitStructure;
// NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC全局中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级1位,从优先级3位
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //先占优先级0位,从优先级4位
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该通道中断
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//}
//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
//BKP->DR1用于保存是否第一次配置的设置
//返回0:正常
//其他:错误代码
u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
u8 temp=0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A2) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
BKP_DeInit(); //复位备份区域
RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&temp<250) //检查指定的RCC标志位设置与否,等待低速晶振就绪
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;//初始化时钟失败,晶振有问题
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_WaitForSynchro(); //等待RTC寄存器同步
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_EnterConfigMode();/// 允许配置
RTC_SetPrescaler(32767); //设置RTC预分频的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(2022,4,26,10,30,55); //设置时间
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0XA5A5); //向指定的后备寄存器中写入用户程序数据
}
else//系统继续计时
{
RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
//RTC_NVIC_Config();//RCT中断分组设置
RTC_Get();//更新时间
return 0; //ok
}
//RTC时钟中断
//每秒触发一次
//extern u16 tcnt;
//void RTC_IRQHandler(void)
//{
// if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒钟中断
// {
// RTC_Get();//更新时间
// }
// if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//闹钟中断
// {
// RTC_ClearITPendingBit(RTC_IT_ALR); //清闹钟中断
// RTC_Get(); //更新时间
// printf("Alarm Time:%d-%d-%d %d:%d:%d\n",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);//输出闹铃时间
// }
// RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //清闹钟中断
// RTC_WaitForLastTask();
//}
//判断是否是闰年函数
//月份 1 2 3 4 5 6 7 8 9 10 11 12
//闰年 31 29 31 30 31 30 31 31 30 31 30 31
//非闰年 31 28 31 30 31 30 31 31 30 31 30 31
//输入:年份
//输出:该年份是不是闰年.1,是.0,不是
u8 Is_Leap_Year(u16 year)
{
if(year%4==0) //必须能被4整除
{
if(year%100==0)
{
if(year%400==0)return 1;//如果以00结尾,还要能被400整除
else return 0;
} else return 1;
} else return 0;
}
//设置时钟
//把输入的时钟转换为秒钟
//以1970年1月1日为基准
//1970~2099年为合法年份
//返回值:0,成功;其他:错误代码.
//月份数据表
u8 const table_week[12]= {0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
//平年的月份日期表
const u8 mon_table[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{
u16 t;
u32 seccount=0;
if(syear<1970||syear>2099)return 1;
for(t=1970; t<syear; t++) //把所有年份的秒钟相加
{
if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数
else seccount+=31536000; //平年的秒钟数
}
smon-=1;
for(t=0; t<smon; t++) //把前面月份的秒钟数相加
{
seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加
if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//闰年2月份增加一天的秒钟数
}
seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加
seccount+=(u32)hour*3600;//小时秒钟数
seccount+=(u32)min*60; //分钟秒钟数
seccount+=sec;//最后的秒钟加上去
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问
RTC_SetCounter(seccount); //设置RTC计数器的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
return 0;
}
//初始化闹钟
//以1970年1月1日为基准
//1970~2099年为合法年份
//syear,smon,sday,hour,min,sec:闹钟的年月日时分秒
//返回值:0,成功;其他:错误代码.
u8 RTC_Alarm_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{
u16 t;
u32 seccount=0;
if(syear<1970||syear>2099)return 1;
for(t=1970; t<syear; t++) //把所有年份的秒钟相加
{
if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数
else seccount+=31536000; //平年的秒钟数
}
smon-=1;
for(t=0; t<smon; t++) //把前面月份的秒钟数相加
{
seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加
if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//闰年2月份增加一天的秒钟数
}
seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加
seccount+=(u32)hour*3600;//小时秒钟数
seccount+=(u32)min*60; //分钟秒钟数
seccount+=sec;//最后的秒钟加上去
//设置时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
//上面三步是必须的!
RTC_SetAlarm(seccount);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
return 0;
}
//得到当前的时间
//返回值:0,成功;其他:错误代码.
u8 RTC_Get(void)
{
static u16 daycnt=0;
u32 timecount=0;
u32 temp=0;
u16 temp1=0;
timecount=RTC->CNTH;//得到计数器中的值(秒钟数)
timecount<<=16;
timecount+=RTC->CNTL;
temp=timecount/86400; //得到天数(秒钟数对应的)
if(daycnt!=temp)//超过一天了
{
daycnt=temp;
temp1=1970; //从1970年开始
while(temp>=365)
{
if(Is_Leap_Year(temp1))//是闰年
{
if(temp>=366)temp-=366;//闰年的秒钟数
else break;
}
else temp-=365; //平年
temp1++;
}
calendar.w_year=temp1;//得到年份
temp1=0;
while(temp>=28)//超过了一个月
{
if(Is_Leap_Year(calendar.w_year)&&temp1==1)//当年是不是闰年/2月份
{
if(temp>=29)temp-=29;//闰年的秒钟数
else break;
}
else
{
if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年
else break;
}
temp1++;
}
calendar.w_month=temp1+1; //得到月份
calendar.w_date=temp+1; //得到日期
}
temp=timecount%86400; //得到秒钟数
calendar.hour=temp/3600; //小时
calendar.min=(temp%3600)/60; //分钟
calendar.sec=(temp%3600)%60; //秒钟
calendar.week=RTC_Get_Week(calendar.w_year,calendar.w_month,calendar.w_date);//获取星期
return 0;
}
//获得现在是星期几
//功能描述:输入公历日期得到星期(只允许1901-2099年)
//输入参数:公历年月日
//返回值:星期号
u8 RTC_Get_Week(u16 year,u8 month,u8 day)
{
u16 temp2;
u8 yearH,yearL;
yearH=year/100;
yearL=year%100;
// 如果为21世纪,年份数加100
if (yearH>19)yearL+=100;
// 所过闰年数只算1900年之后的
temp2=yearL+yearL/4;
temp2=temp2%7;
temp2=temp2+day+table_week[month-1];
if (yearL%4==0&&month<3)temp2--;
return(temp2%7);
}
main.c文件如下:MAX7219请查看上一次发布或者请查看原子哥:
stm32f103rct6利用max7219驱动数码管显示-OpenEdv-开源电子网
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"
#include "MAX7219.h"
#include "rtc.h"
int main(void)
{
SysTick_Init(72);//延时初始化
GPIOA_Init(); //GPIA初始化
RTC_Init();
delay_ms(50);
Init_MAX7219();
delay_ms(2000);
RTC_Set(2022,4,26,15,30,55);
while(1)
{
RTC_Get();
Write_Max7219(1,calendar.sec%10);
Write_Max7219(2,calendar.sec/10);
Write_Max7219(3,10);
Write_Max7219(4,calendar.min%10);
Write_Max7219(5,calendar.min/10);
Write_Max7219(6,10);
Write_Max7219(7,calendar.hour%10);
Write_Max7219(8,calendar.hour/10);
delay_s(2);
Write_Max7219(1,calendar.w_date%10);
Write_Max7219(2,calendar.w_date/10);
Write_Max7219(3,10);
Write_Max7219(4,calendar.w_month%10);
Write_Max7219(5,calendar.w_month/10);
Write_Max7219(6,10);
Write_Max7219(7,(calendar.w_year%100)%10);
Write_Max7219(8,(calendar.w_year%100)/10);
delay_s(1);
}
}
MAX7219数码管+RTC时钟——stm32相关推荐
- STM32读取RTC时钟
STM32读取RTC时钟 一.RTC 1. 简介 2. 特征 3. 组成 二.项目创建 三.代码修改 四.总结 参考 一.RTC 1. 简介 RTC-real time clock,实时时钟,主要包含 ...
- STM32物联网项目-RTC时钟
RTC时钟 RTC简介 实时时钟是一个独立的定时器.RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能.修改计数器的值可以重新设置系统当前的时间和日期. RTC模块和时钟配置系 ...
- 纠结的STM32 RTC时钟源LSE
一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题.直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题. 这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻 ...
- esp32 rtc 时钟设置不对_STM32入门系列-STM32时钟系统,STM32时钟树
时钟对于单片机来说是非常重要的,它为单片机工作提供一个稳定的机器周期从而使系统能够正常运行.时钟系统犹如人的心脏,一旦有问题整个系统就崩溃.我们知道STM32属于高级单片机,其内部有很多的外设,但不是 ...
- 什么是RCT实时时钟?(STM32中RTC时钟源)
什么是RCT(Real Time Clock,实时时钟)? 一.RTC时钟简介 RTC(Real Time Clock,实时时钟)是指安装在电子设备或实现其功能的IC(集成电路)上的时钟,一般会是集成 ...
- STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例)
STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例) 目录 STM32CubeMX | STM32 F1系列HAL库低功耗 ...
- STM32 RTC时钟源LSE
一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题.直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题. 这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻 ...
- STM32之RTC时钟
前言 了解实时时钟RTC的原理.STM32芯片自带RTC,因此不须像其他MCU需外接RTC模块.请编程实现STM32的日历读取.设置和输出.要求: 1)读取RTC初始时间,验证是否为 1970年1月1 ...
- STM32 RTC时钟读取时间
文章目录 一.RTC简介 1.1 RTC 1.2 RTC特征 1.3 RTC原理框图 1.4 RTC工作流程 1.5 RTC时钟选择 1.6 RTC复位过程 1.7 RTC中断 二.CubeMX配置 ...
最新文章
- 计算机视觉开源库OpenCV之利用开操作(Opening Operation)修复受损照片方法
- Mysql8.0注意url变更写法
- 注册表编辑器厘米爱你找不到mysql,win7系统中安装mysql后找不到服务或出现找不到指定文件的解决方法...
- error: conversion from ‘const char [ ]‘ to non-scalar type
- P3702-[SDOI2017]序列计数【矩阵乘法】
- 当执行游戏0xc000007b错误的解决方法
- linux_shell_根据网站来源分桶
- C++获取多维数组维数
- android for opencv (2) byte[] ,Bitmap 与 Mat 类型转换,Bitmap保存照片
- PHP substr(),mb_substr(),mb_strcut()比较
- 【操作系统】-- 时间片轮转调度算法、优先级调度算法、多级反馈队列调度算法
- MySQL 误删数据恢复
- 《UnityAPI.Transform变换》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+Transform+eulerAngles+LookAt+立钻哥哥++OK++)
- 【HCIE备考】笔试题库P1-10
- eclipse使用install报No compiler is provided in this environment. Perhaps you are running on a JRE rathe
- gcc与cuda的关系
- 美团配送和亚马逊AWS的异曲同工
- 等保测评师-等保测评工程师-发展路线(不喜勿喷)
- Java 学习 - 全文索引 - Lucene
- 360云盘关闭:一个360系列粉的吐槽
热门文章
- 一种基于卷积神经网络的数据驱动故障诊断方法
- 通往真理的最短路径 - 【复数】科普/详解
- Python实现照片里添加文字
- UART(Universal Asynchronous Receiver/Transmitter,异步收发传输器)
- ## IDEA创建maven项目没有src目录问题解决
- SwiftUI:属性装饰器的理解@State,@Binding,@ObservedObject,@Published,@Environment,@EnvironmentObject
- 杨可桢机械设计基础第6版笔记和课后答案
- winfrom下载服务器图片到本地,用C#打开Windows自带的图片传真查看器
- 茗创:脑电数据处理业务
- error: invalid application of 'sizeof' to an incomplete type 'JNINativeMethod []'