这里会显示出您选择的修订版和当前版本之间的差别。
后一修订版 | 前一修订版 | ||
icore3_arm_hal_13 [2020/07/31 16:39] fmj 创建 |
icore3_arm_hal_13 [2022/03/18 15:06] (当前版本) sean |
||
---|---|---|---|
行 2: | 行 2: | ||
|技术支持电话|**0379-69926675-801**||| | |技术支持电话|**0379-69926675-801**||| | ||
|技术支持邮件|Gingko@vip.163.com||| | |技术支持邮件|Gingko@vip.163.com||| | ||
- | |技术论坛|http://www.eeschool.org||| | ||
^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ||
- | | V1.0 | 2020-07-04 | gingko | 初次建立 | | + | | V1.0 | 2020-07-31 | gingko | 初次建立 | |
- | ===== 实验十:RTC实时时钟实验——显示日期和时间 ===== | + | ===== 实验十三:RTC实时时钟实验——显示日期和时间 ===== |
==== 一、 实验目的与意义 ==== | ==== 一、 实验目的与意义 ==== | ||
行 17: | 行 16: | ||
==== 二、 实验设备及平台 ==== | ==== 二、 实验设备及平台 ==== | ||
- | - iCore4 双核心板[[https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22598974120.15.5923532fsFrHiE&id=551864196684|点击购买]]。 | + | - iCore3 双核心板。[[https://item.taobao.com/item.htm?spm=a1z10.1-c.w4024-251734887.3.5923532fXD2RIN&id=524229438677&scene=taobao_shop|点击购买]] |
- JLINK(或相同功能)仿真器[[https://item.taobao.com/item.htm?id=554869837940|点击购买]]。 | - JLINK(或相同功能)仿真器[[https://item.taobao.com/item.htm?id=554869837940|点击购买]]。 | ||
- Micro USB线缆。 | - Micro USB线缆。 | ||
行 25: | 行 24: | ||
==== 三、 实验原理 ==== | ==== 三、 实验原理 ==== | ||
- | === 1、STM32F767 RTC时钟简介 === | + | === 1、STM32F407 RTC时钟简介 === |
- | * STM32F767的实时时钟(RTC)相对于STM32F1来说,改进了不少,带了日历功能了,STM32F767的RTC,是一个独立的BCD定时器/计数器。RTC提供一个日历时钟(包含年月日时分秒信息)、两个可编程闹钟(ALARMA和ALARMB)中断,以及一个具有中断功能的周期性可编程唤醒标志。RTC还包含用于管理低功耗模式的自动唤醒单元。 | + | * STM32F407的实时时钟(RTC)相对于STM32F1来说,改进了不少,带了日历功能了,STM32F767的RTC,是一个独立的BCD定时器/计数器。RTC提供一个日历时钟(包含年月日时分秒信息)、两个可编程闹钟(ALARMA和ALARMB)中断,以及一个具有中断功能的周期性可编程唤醒标志。RTC还包含用于管理低功耗模式的自动唤醒单元。 |
* 两个32位寄存器(TR和DR)包含二进码十进数格式(BCD)的秒、分钟、小时(12或24小时制)、星期、日期、月份和年份。此外,还可提供二进制格式的亚秒值。 | * 两个32位寄存器(TR和DR)包含二进码十进数格式(BCD)的秒、分钟、小时(12或24小时制)、星期、日期、月份和年份。此外,还可提供二进制格式的亚秒值。 | ||
- | * STM32F767的RTC可以自动将月份的天数补偿为28、29(闰年)、30和31天。并且还可以进行夏令时补偿。 | + | * STM32F407的RTC可以自动将月份的天数补偿为28、29(闰年)、30和31天。并且还可以进行夏令时补偿。 |
* RTC模块和时钟配置是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变,只要后备区域供电正常,那么RTC将可以一直运行。但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前,先要取消备份区域(BKP)写保护。 | * RTC模块和时钟配置是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变,只要后备区域供电正常,那么RTC将可以一直运行。但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前,先要取消备份区域(BKP)写保护。 | ||
=== 2、RTC主要特性 === | === 2、RTC主要特性 === | ||
行 51: | 行 50: | ||
=== 3、RTC框图 === | === 3、RTC框图 === | ||
- | {{ :icore4:icore4_arm_hal_10_1.png?direct |}} | + | {{ :icore3:icore3_arm_hal_13_1.png?direct |}} |
=== 4、时钟和分频 === | === 4、时钟和分频 === | ||
- | * 首先,我们看STM32F767的RTC时钟分频。STM32F767的RTC时钟(RTCCLK)通过时钟控制器,可以从LSE时钟、LSI时钟以及HSE时钟三者中选择(通过RCC_BDCR寄存器选择)。一般我们选择LSE,即外部32.768Khz晶振作为时钟源(RTCCLK),而RTC时钟核心,要求提供1Hz的时钟,所以,我们要设置RTC的可编程预分配器。STM32F767的可编程预分配器(RTC_PRER)分为2个部分: | + | * 首先,我们看STM32F407的RTC时钟分频。STM32F407的RTC时钟(RTCCLK)通过时钟控制器,可以从LSE时钟、LSI时钟以及HSE时钟三者中选择(通过RCC_BDCR寄存器选择)。一般我们选择LSE,即外部32.768Khz晶振作为时钟源(RTCCLK),而RTC时钟核心,要求提供1Hz的时钟,所以,我们要设置RTC的可编程预分配器。STM32F407的可编程预分配器(RTC_PRER)分为2个部分: |
* (1)一个通过RTC_PRER寄存器的PREDIV_A位配置的7位异步预分频器。 | * (1)一个通过RTC_PRER寄存器的PREDIV_A位配置的7位异步预分频器。 | ||
* (2)一个通过RTC_PRER寄存器的PREDIV_S位配置的15位同步预分频器。 | * (2)一个通过RTC_PRER寄存器的PREDIV_S位配置的15位同步预分频器。 | ||
行 63: | 行 62: | ||
=== 5、日历时间(RTC_TR)和日期(RTC_DR)寄存器 === | === 5、日历时间(RTC_TR)和日期(RTC_DR)寄存器 === | ||
- | * STM32F767的RTC日历时间(RTC_TR)和日期(RTC_DR)寄存器,用于存储时间和日期(也可以用于设置时间和日期),可以通过与PCLK1(APB1时钟)同步的影子寄存器来访问,这些时间和日期寄存器也可以直接访问,这样可避免等待同步的持续时间。 | + | * STM32F407的RTC日历时间(RTC_TR)和日期(RTC_DR)寄存器,用于存储时间和日期(也可以用于设置时间和日期),可以通过与PCLK1(APB1时钟)同步的影子寄存器来访问,这些时间和日期寄存器也可以直接访问,这样可避免等待同步的持续时间。 |
* 每隔2个RTCCLK周期,当前日历值便会复制到影子寄存器,并置位RTC_ISR寄存器的RSF位。我们可以读取RTC_TR和RTC_DR来得到当前时间和日期信息,不过需要注意的是:时间和日期都是以BCD码的格式存储的,读出来要转换一下,才可以得到十进制的数据。 | * 每隔2个RTCCLK周期,当前日历值便会复制到影子寄存器,并置位RTC_ISR寄存器的RSF位。我们可以读取RTC_TR和RTC_DR来得到当前时间和日期信息,不过需要注意的是:时间和日期都是以BCD码的格式存储的,读出来要转换一下,才可以得到十进制的数据。 | ||
=== 6、可编程闹钟 === | === 6、可编程闹钟 === | ||
- | * STM32F767提供两个可编程闹钟:闹钟A(ALARM_A)和闹钟B(ALARM_B)。通过RTC_CR寄存器的ALRAE和ALRBE位置1来使能闹钟。当日历的亚秒、秒、分、小时、日期分别与闹钟寄存器RTC_ALRMASSR/RTC_ALRMAR和RTC_ALRMBSSR/RTC_ALRMBR中的值匹配时,则可以产生闹钟(需要适当配置)。本章我们将利用闹钟A产生闹铃,即设置RTC_ALRMASSR和RTC_ALRMAR即可。 | + | * STM32F407提供两个可编程闹钟:闹钟A(ALARM_A)和闹钟B(ALARM_B)。通过RTC_CR寄存器的ALRAE和ALRBE位置1来使能闹钟。当日历的亚秒、秒、分、小时、日期分别与闹钟寄存器RTC_ALRMASSR/RTC_ALRMAR和RTC_ALRMBSSR/RTC_ALRMBR中的值匹配时,则可以产生闹钟(需要适当配置)。本章我们将利用闹钟A产生闹铃,即设置RTC_ALRMASSR和RTC_ALRMAR即可。 |
=== 7、周期性自动唤醒 === | === 7、周期性自动唤醒 === | ||
- | * STM32F767的RTC不带秒钟中断,但是多了一个周期性自动唤醒功能。周期性唤醒功能,由一个16位可编程自动重载递减计数器(RTC_WUTR)生成,可用于周期性中断/唤醒。 | + | * STM32F407的RTC不带秒钟中断,但是多了一个周期性自动唤醒功能。周期性唤醒功能,由一个16位可编程自动重载递减计数器(RTC_WUTR)生成,可用于周期性中断/唤醒。 |
* 我们可以通过RTC_CR寄存器中的WUTE位设置使能此唤醒功能。唤醒定时器的时钟输入可以是:2、4、8或16分频的RTC时钟(RTCCLK),也可以是ck_spre时钟(一般为1Hz)。 | * 我们可以通过RTC_CR寄存器中的WUTE位设置使能此唤醒功能。唤醒定时器的时钟输入可以是:2、4、8或16分频的RTC时钟(RTCCLK),也可以是ck_spre时钟(一般为1Hz)。 | ||
* 本实验中,通过软件对RTC计数器进行相关的配置,可以提供时钟功能,通过修改计时器的值可以调整时钟。最终通过串口在终端显示时间。 | * 本实验中,通过软件对RTC计数器进行相关的配置,可以提供时钟功能,通过修改计时器的值可以调整时钟。最终通过串口在终端显示时间。 | ||
行 76: | 行 75: | ||
=== 1、主函数 === | === 1、主函数 === | ||
<code c> | <code c> | ||
- | int main(void) | + | int main(void) |
- | { | + | { |
- | RTC_TimeTypeDef sTime; | + | RTC_TimeTypeDef sTime; |
- | RTC_DateTypeDef sDate; | + | RTC_DateTypeDef sDate; |
+ | int second_bak = 0; | ||
- | int second_bak = 0; | + | HAL_Init(); |
- | /* MCU 配置 */ | + | SystemClock_Config(); //配置系统时钟 |
- | /* 重置所有外围设备,初始化Flash接口和Systick. */ | + | MX_GPIO_Init(); //初始化所有已配置的外围设备 |
- | HAL_Init(); | + | MX_RTC_Init(); |
- | /* 配置系统时钟 */ | + | MX_UART4_Init(); |
- | SystemClock_Config(); | + | |
- | /* 初始化所有已配置的外围设备*/ | + | uart4.printf("\x0c"); //清屏 |
- | MX_GPIO_Init(); | + | uart4.printf("\033[1;32;40m");//字体终端设置为绿色 |
- | MX_RTC_Init(); | + | uart4.printf("\r\n\r\nhello! I am iCore3!\r\n\r\n\r\n"); |
- | MX_USART6_UART_Init(); | + | //在串口终端打印“Hello! I am iCore3” |
- | usart6.initialize(115200); //串口波特设置 | + | LED_GREEN_ON; //绿灯亮 |
- | usart6.printf("\x0c"); //清屏 | + | while (1) |
- | usart6.printf("\033[1;32;40m"); //设置终端字体为绿色 | + | { |
- | usart6.printf(" Hello, I am iCore4!\r\n"); //串口信息输出 | + | HAL_Delay (100); |
- | LED_GREEN_ON; | + | HAL_RTC_GetTime (&hrtc,&sTime,RTC_FORMAT_BIN); //读取RTC日期和时间 |
- | //设置RTC日期和时间 | + | HAL_RTC_GetDate (&hrtc,&sDate,RTC_FORMAT_BIN); |
- | my_rtc.set_date(17,8,11,5); | + | if(second_bak != sTime.Seconds){ |
- | my_rtc.set_time(17,43,20); | + | //当秒数据与备份不一致时,像终端打印时间/日期 |
- | /* 无限循环 */ | + | uart4.printf(" %02d:%02d:%02d",sTime.Hours,sTime.Minutes,sTime.Seconds); |
- | while (1) | + | uart4.printf("20%02d-%02d-%02d\r",sDate.Year,sDate.Month,sDate.Date); |
- | { | + | second_bak = sTime.Seconds; //秒数据备份 |
- | HAL_Delay(100); | + | } |
- | //读取RTC日期和时间 | + | |
- | HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); | + | |
- | HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN); | + | |
- | if(second_bak != sTime.Seconds){ | + | |
- | usart6.printf(" %02d:%02d:%02d ",sTime.Hours,sTime.Minutes,sTime.Seconds); | + | |
- | usart6.printf("20%02d-%02d-%02d \r",sDate.Year,sDate.Month,sDate.Date); | + | |
- | second_bak = sTime.Seconds; | + | |
- | } | + | |
- | } | + | |
} | } | ||
- | + | } | |
</code> | </code> | ||
=== 2、RTC初始化 === | === 2、RTC初始化 === | ||
行 119: | 行 111: | ||
void MX_RTC_Init(void) | void MX_RTC_Init(void) | ||
{ | { | ||
- | RTC_TimeTypeDef sTime; | + | RTC_TimeTypeDef sTime = {0}; |
- | RTC_DateTypeDef sDate; | + | RTC_DateTypeDef sDate = {0}; |
- | /**仅初始化RTC */ | + | |
hrtc.Instance = RTC; | hrtc.Instance = RTC; | ||
- | hrtc.Init.HourFormat = RTC_HOURFORMAT_24;// RTC设置为24小时格式 | + | hrtc.Init.HourFormat = RTC_HOURFORMAT_24; |
- | hrtc.Init.AsynchPrediv = 127; //RTC 异步分频系数 | + | hrtc.Init.AsynchPrediv = 127;//RTC异步分频系数 |
- | hrtc.Init.SynchPrediv = 255; //RTC 同步分频系数 | + | hrtc.Init.SynchPrediv = 255; //RTC同步分频系数 |
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; | hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; | ||
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; //输出信号的极性 | hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; //输出信号的极性 | ||
- | hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;//RTC输出引脚模式 | + | hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; //RTC输出引脚模式 |
- | if (HAL_RTC_Init(&hrtc) != HAL_OK)//初始化RTC外设 | + | if (HAL_RTC_Init(&hrtc) != HAL_OK) //初始化RTC外设 |
{ | { | ||
- | _Error_Handler(__FILE__, __LINE__); | + | Error_Handler(); |
- | } | + | } //判断读到的备份寄存器的值与写入的值是否一致 |
- | /**初始化RTC并设置时间和日期 */ | + | if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){ //设置RTC初始日期和时间 |
- | if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){ | + | sTime.Hours = 0x17; //小时 |
- | sTime.Hours = 0x16;//小时 | + | sTime.Minutes = 0x30;//分钟 |
- | sTime.Minutes = 0x19;//分钟 | + | sTime.Seconds = 0x30;//秒 |
- | sTime.Seconds = 0x0;//秒 | + | sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; |
- | sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; | + | sTime.StoreOperation = RTC_STOREOPERATION_RESET; |
- | sTime.StoreOperation = RTC_STOREOPERATION_RESET; | + | if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) |
- | if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) | + | { |
- | { | + | Error_Handler(); |
- | _Error_Handler(__FILE__, __LINE__); | + | } |
- | } | + | sDate.WeekDay = RTC_WEEKDAY_THURSDAY; |
- | sDate.WeekDay = RTC_WEEKDAY_MONDAY; | + | sDate.Month = RTC_MONTH_JANUARY; |
- | sDate.Month = RTC_MONTH_AUGUST; | + | sDate.Date = 0x15; |
- | sDate.Date = 0x7; | + | sDate.Year = 0x20; |
- | sDate.Year = 0x0; | + | if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) |
- | if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) | + | { |
- | { | + | Error_Handler(); |
- | _Error_Handler(__FILE__, __LINE__); | + | }//向备份寄存器中写入数值 |
- | } | + | HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2); |
- | HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2); | + | } |
- | } | + | if (HAL_RTCEx_SetWakeUpTimer(&hrtc,0,RTC_WAKEUPCLOCK_RTCCLK_DIV16)!= HAL_OK) |
- | /**使能唤醒 */ | + | { |
- | if (HAL_RTCEx_SetWakeUpTimer(&hrtc, 0, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK) | + | Error_Handler(); |
- | { | + | } |
- | _Error_Handler(__FILE__, __LINE__); | + | |
- | } | + | |
} | } | ||
</code> | </code> | ||
* 该函数用来初始化RTC配置以及日期和时钟,这里设置时间和日期,分别是通过 HAL_RTC_SetTime函数和 HAL_RTC_SetDate函数来实现。 | * 该函数用来初始化RTC配置以及日期和时钟,这里设置时间和日期,分别是通过 HAL_RTC_SetTime函数和 HAL_RTC_SetDate函数来实现。 | ||
- | === 3、设置时间和日期 === | + | === 3、获取时间 === |
- | + | ||
- | * 主函数中调用设置时间和日期的自定义函数rtc_set_time和rtc_set_date来设置初始时间日期,这两个函数实际就是调用库函数里面的HAL_RTC_SetTime函数和HAL_RTC_SetDate函数来实现的,它们的定义如下: | + | |
<code c> | <code c> | ||
- | static int rtc_set_time(unsigned char hour,unsigned char min,unsigned char sec) | + | HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc,RTC_TimeTypeDef *sTime, uint32_t Format) |
{ | { | ||
- | RTC_TimeTypeDef sTime; | + | uint32_t tmpreg = 0U; |
- | sTime.Hours = hour;//小时 | + | /* 检查参数 */ |
- | sTime.Minutes = min; //分钟 | + | |
- | sTime.Seconds = sec; //秒 | + | |
- | sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; | + | |
- | sTime.StoreOperation = RTC_STOREOPERATION_RESET; | + | |
- | if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) | + | |
- | { | + | |
- | while(1); | + | |
- | } | + | |
- | return 0; | + | |
- | } | + | |
- | static int rtc_set_date(unsigned char year,unsigned char month,unsigned char date,unsigned char week) | + | |
- | { | + | |
- | RTC_DateTypeDef sDate; | + | |
- | sDate.WeekDay = week; //星期 | + | |
- | sDate.Month = month; //月 | + | |
- | sDate.Date = date; //日 | + | |
- | sDate.Year = year; //年 | + | |
- | if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK) | + | |
- | { | + | |
- | while(1); | + | |
- | } | + | |
- | return 0; | + | |
- | } | + | |
- | + | ||
- | </code> | + | |
- | === 4、获取时间和日期 === | + | |
- | <code c> | + | |
- | /*获取RTC当前时间*/ | + | |
- | HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format) | + | |
- | { | + | |
- | uint32_t tmpreg = 0; | + | |
- | /* 检查参数*/ | + | |
assert_param(IS_RTC_FORMAT(Format)); | assert_param(IS_RTC_FORMAT(Format)); | ||
- | /* 从对应的寄存器中获取亚秒值*/ | + | /* 从对应的寄存器中获取亚秒值 */ |
sTime->SubSeconds = (uint32_t)(hrtc->Instance->SSR); | sTime->SubSeconds = (uint32_t)(hrtc->Instance->SSR); | ||
- | /* 从相应的寄存器字段中获取SecondFraction结构字段/ | + | /*从相应的寄存器字段中获取SecondFraction 结构字段*/ |
sTime->SecondFraction = (uint32_t)(hrtc->Instance->PRER & RTC_PRER_PREDIV_S); | sTime->SecondFraction = (uint32_t)(hrtc->Instance->PRER & RTC_PRER_PREDIV_S); | ||
/* 获取TR寄存器 */ | /* 获取TR寄存器 */ | ||
- | tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK); | + | tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK); |
- | /*用读取的参数填充结构字段 */ | + | /* 用读取的参数填充结构字段 */ |
- | sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); | + | sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16U); |
- | sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); | + | sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >> 8U); |
sTime->Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); | sTime->Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); | ||
- | sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); | + | sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16U); |
/* 检查输入参数格式 */ | /* 检查输入参数格式 */ | ||
if(Format == RTC_FORMAT_BIN) | if(Format == RTC_FORMAT_BIN) | ||
{ | { | ||
- | /*将时间结构参数转换为二进制格式*/ | + | /* 将时间结构参数转换为二进制格式 */ |
sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours); | sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours); | ||
sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes); | sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes); | ||
- | sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds); | + | sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds); |
} | } | ||
return HAL_OK; | return HAL_OK; | ||
} | } | ||
- | /*获取RTC当前日期*/ | + | |
- | HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format) | + | |
- | { | + | |
- | uint32_t datetmpreg = 0; | + | |
- | /* 检查参数 */ | + | |
- | assert_param(IS_RTC_FORMAT(Format)); | + | |
- | /* 获取DR寄存器 */ | + | |
- | datetmpreg = (uint32_t)(hrtc->Instance->DR & RTC_DR_RESERVED_MASK); | + | |
- | /* 用读取的参数填充结构字段 */ | + | |
- | sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); | + | |
- | sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); | + | |
- | sDate->Date = (uint8_t)(datetmpreg & (RTC_DR_DT | RTC_DR_DU)); | + | |
- | sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> 13); | + | |
- | /* 检查输入参数格式 */ | + | |
- | if(Format == RTC_FORMAT_BIN) | + | |
- | { | + | |
- | /* 将日期结构参数转换为二进制格式 */ | + | |
- | sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year); | + | |
- | sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month); | + | |
- | sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date); | + | |
- | } | + | |
- | return HAL_OK; | + | |
- | } | + | |
- | + | ||
</code> | </code> | ||
+ | |||
==== 五、 实验步骤 ==== | ==== 五、 实验步骤 ==== | ||
- | - 把仿真器与iCore4的SWD调试口相连(直接相连或者通过转接器相连); | + | * 1.把仿真器与iCore3的SWD调试口相连(直接相连或者通过转接器相连); |
- | - 把iCore4通过Micro USB线与计算机相连,为iCore4供电; | + | * 2.把iCore3通过Micro USB线与计算机相连,为iCore3供电; |
- | - 打开Keil MDK 开发环境,并打开本实验工程; | + | * 3.打开putty软件,从设备管理器内查看端口号,设置波特率为115200; |
- | - 烧写程序到iCore4上; | + | {{ :icore3:icore3_arm_hal_13_2.png?direct |}} |
- | - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 | + | * 4.点击Open; |
+ | * 5.打开Keil MDK 开发环境,并打开本实验工程; | ||
+ | * 6.烧写程序到iCore3上; | ||
+ | * 7.也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 | ||
==== 六、 实验现象 ==== | ==== 六、 实验现象 ==== | ||
* 在终端屏幕上可以看到显示的时间和日期。如图所示。 | * 在终端屏幕上可以看到显示的时间和日期。如图所示。 | ||
- | {{ :icore4:icore4_arm_hal_10_2.png?direct |}} | + | {{ :icore3:icore3_arm_hal_13_3.png?direct |}} |