用户工具

站点工具


icore3_arm_hal_13

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
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 *sTimeuint32_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 |}} 
  
icore3_arm_hal_13.1596184769.txt.gz · 最后更改: 2020/07/31 16:39 由 fmj