打开主菜单

谷雨文档中心 β

更改

NBDK-L4:基础实验教程

添加14,728字节2019年2月19日 (二) 13:10
STM32L476 定时器简介
</syntaxhighlight>
== 实验17-定时器中断 ==
定时器中断实验,这个实验大家可以和之前的红外接收实验对照查看,使用的手段是类似的,都是利用定时器的计时功能,不同点在于红外接收用的是捕获,而此实验则是触发中断。 === STM32L476 定时器简介 定时器中断简介 === ''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''以下部分为TIM2 / TIM3 / TIM4 / TIM5这四个定时器的介绍。 1.通用定时器简介: 通用定时器由一个由可编程预分频器驱动的16位或32位自动重载计数器组成。它们可用于各种目的,包括测量输入信号的脉冲长度(输入捕获)或生成输出波形(输出比较和PWM)。 使用定时器预分频器和RCC时钟控制器预分频器,可以将脉冲长度和波形周期从几微秒调制到几毫秒。定时器完全独立,不共享任何资源。 2.通用定时器功能 •16位(TIM3,TIM4)或32位(TIM2和TIM5)上,下,上/下自动重载计数器。 •16位可编程预分频器,用于分频(也“在运行中”)计数器时钟 频率由1到65535之间的任何因子组成。 •最多4个独立频道: - 输入捕获 - 输出比较 - PWM生成(边缘和中心对齐模式) - 单脉冲模式输出 •同步电路,用外部信号控制定时器并互连 几个计时器。 •以下事件的中断/ DMA生成: - 更新:计数器溢出/下溢,计数器初始化(通过软件或 内部/外部触发器) - 触发事件(计数器启动,停止,初始化或通过内部/外部触发计数) - 输入捕获 - 输出比较 •支持增量(正交)编码器和霍尔传感器电路进行定位 目的 •外部时钟或逐周期电流管理的触发输入 3.通用定时器中断触发的条件 配置定时器自动装载值,以及分频系数,使能定时器的中断。当计数值向上或者向下溢出时,定时器中断触发。 计算公式为:Tout=(ARR+1)(PSC+1)/TIMxCLK (us)
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 硬件设计 ===
选择STM32L4内部RTC实时时钟。选择STM32L4内部TIM2定时器,展示使用的是开发板上的LED指示灯D3。[[文件:NBDK-SCH-LED.png|边框|居中|无框|386x386像素]]
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 实验准备 ===
# 使用miniUSB线及10pin排线,通过Jlink仿真器连接PC端和开发板。
# 使用miniUSB线,连接PC与开发板USB接口。
# 使用Keil打开基础实验的实验16使用Keil打开基础实验的实验17-RTC实时时钟定时器中断。
# 下载程序,并完成功能测试。
=== 实验验证 ===
下载完成后,可以看到TFT屏幕上打印当前的实时时间、日期以及星期,且10s后会触发闹钟(表现为TFT打印"Alarm"、蜂鸣器哔一声)。下载完成后,可以看到LED周期闪烁(1s周期,也就是点亮1s,熄灭1s)。
=== 源码详解 ===
此文件位于“实验16-RTC实时时钟\Inc”路径中,主要用途是选择使能此例程使用到的库文件。
此例程我们主要给大家展示STM32L4的实时时钟功能,所以我们宏定义中打开RTC相关的。此例程我们主要给大家展示STM32L4的定时器的中断功能,所以我们宏定义中打开TIM相关的。<syntaxhighlight lang="c" line="1" start="103">
// 使能的宏
#define HAL_MODULE_ENABLED // 芯片
#define HAL_UART_MODULE_ENABLED // UART
#define HAL_SPI_MODULE_ENABLED // SPI
#define HAL_RTC_MODULE_ENABLED HAL_TIM_MODULE_ENABLED // RTC实时时钟TIM定时器
</syntaxhighlight>
main函数,我们的例程由此处开始执行,首先调用HAL_Init()函数初始化我们的模块,接着调用SystemClock_Config()函数初始化此例程用到的时钟,具体有哪些时钟被初始化,在gyu_util.c部分有详细说明。
接下来我们初始化TFT彩屏相关的SPI控制接口,以及GUI图形界面初始化。并且格式化打印一些内容,字体显示为红色的部分。接下来我们分别初始化了LED及TIM2定时器。
最后我们初始化RTC时钟,并且调用实现好的有关RTC的函数,去配置当前的时钟、日期、星期、以及闹钟。 在while()循环当中,持续获取当前的时钟、日期等相关信息,并且打印到TFT彩屏上显示。 当检测到闹钟信息,则在TFT彩屏上打印"Alarm"字样指示闹钟,停止蜂鸣器工作,并且让闹钟标识置为0。 <syntaxhighlight lang="c++" line="1" start="4432">
int main(void)
{
HAL_StatusTypeDef status;/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ RTC_TimeTypeDef sTime; RTC_DateTypeDef sDate; // 重置所有外设、flash界面以及系统时钟
HAL_Init();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
// 重置所有外设、flash界面以及系统时钟
// 配置系统时钟(包含振荡器、系统时钟、总线时钟等等)
SystemClock_Config();
// 初始化LED引脚
LED_Init();
// LCD SPI初始化初始化tim2定时器 LCD_GPIO_Init MX_TIM2_Init(); // LCD IO控制引脚(例如背光) MX_SPI1_Init(); // LCD SPI控制引脚
// 图形界面初始化 GUI_Init(); // GUI界面初始化 GUI_Clear(); // 清屏 GUI_SetColor(GUI_Crimson); // 红色字体 GUI_SetBkColor(GUI_Gold); // 金色背景 // 格式化打印如下的内容 GUI_DispStringAt("Time: : :",24,24); GUI_DispStringAt("Date: 20 / /",24,72); GUI_DispStringAt("Week: ",24,120); // 初始化蜂鸣器 Buzzer_Init(); // RTC初始化 MX_RTC_Init(); RTC_TIME_Set(16,12,30); // 设置当前时间 时,分,秒 RTC_DATE_Set(2,18,12,25); // 设置当前日期 星期,年,月,日 RTC_AlarmA_Set(16,12,40,2); // 设置闹钟 时,分,秒,星期 // while(1)
{
GUI_SetColor(GUI_Aqua);
// 获取时分秒,并且打印到TFT屏
status = HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
if(status == HAL_OK)
{
GUI_DispDecAt(sTime.Hours,96,24,2);
GUI_DispDecAt(sTime.Minutes,132,24,2);
GUI_DispDecAt(sTime.Seconds,168,24,2);
}
// 获取年月日、星期,并且打印到TFT屏
status = HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
if(status == HAL_OK)
{
GUI_DispDecAt(sDate.Year,120,72,2);
GUI_DispDecAt(sDate.Month,156,72,2);
GUI_DispDecAt(sDate.Date,192,72,2);
GUI_DispDecAt(sDate.WeekDay,96,120,2);
}
status = HAL_ERROR;
if(rtcAlarm)
{
rtcAlarm = 0;
Buzzer_SET(GPIO_PIN_RESET); // 关闭蜂鸣器
GUI_DispStringAt("AlarmA",24,168); // 显示屏打印闹钟A标志
}
}
}
基础实验中的其他例程,大部分都是使用的相同的时钟配置函数,有特殊的时钟使用,将会在对应例程的源码详解中做针对性说明。
==== gyu_rtcgyu_tim2it.c ====RTC时钟初始化函数,我们配置为24小时模式,禁止RTC输出,并且初始化RTC时钟。TIM2定时器初始化函数,我们配置TIM2时钟不分频(也就是系统时钟80MHZ),设置TIM2预分频为10000-1(也就是TIM2时钟为80M/10000 = 8000Hz),设置自动装载值为8000(也就是说一次装载满的时间为8000*(1/8000Hz) = 1s)。 这边有总结好的公式:Tout=(ARR+1)(PSC+1)/TIMxCLK (us)。ARR代表预分频,PSC代表自动装载值。
<syntaxhighlight lang="c++" line="1" start="5047">void MX_RTC_InitMX_TIM2_Init(void)
{
hrtchtim2.Instance = RTCTIM2; // 配置为RTC 配置为TIM2 hrtchtim2.Init.HourFormat Prescaler = RTC_HOURFORMAT_2410000-1; // 24小时模式ARR+1 = 10000 hrtchtim2.Init.AsynchPrediv CounterMode = 127TIM_COUNTERMODE_UP; // 异步预分频器,固定127(0x7F)向上计数 hrtchtim2.Init.SynchPrediv Period = 2558000-1; // 同步预分频器,固定255(0xFF)PSC+1 = 8000 hrtchtim2.Init.OutPut ClockDivision = RTC_OUTPUT_DISABLETIM_CLOCKDIVISION_DIV1; // 禁止RTC输出不分频,80MHz
// 初始化RTC时钟初始化TIM2,出错则进入错误处理函数 if (HAL_RTC_InitHAL_TIM_Base_Init(&hrtchtim2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_TIM_Base_Start_IT(&htim2); // 开启TIM2,并且使能中断
}
</syntaxhighlight>RTC初始化函数,使能RTC时钟。TIM2初始化函数,使能定时器TIM2时钟,并且使能中断。<syntaxhighlight lang="c++" line="1" start="7372">void HAL_RTC_MspInitHAL_TIM_Base_MspInit(RTC_HandleTypeDefTIM_HandleTypeDef * hrtchtim){ if(hrtchtim->Instance==RTCTIM2)
{
__HAL_RCC_RTC_ENABLE__HAL_RCC_TIM2_CLK_ENABLE(); // 使能RTC时钟使能定时器TIM2 HAL_NVIC_SetPriority(TIM2_IRQn, 10, 0); //设置中断优先级10,子优先级0 HAL_NVIC_EnableIRQ(TIM2_IRQn); //使能ITM3中断
}
}
</syntaxhighlight>设置RTC时钟的函数,用于设置当前的时间(分别设置时分秒)。定时器中断回调函数,当计数值溢出时,触发此回调,我们判断是否是TIM2触发,如果是,则翻转LED的状态。 在此实验中的表现是,LED灯1s改变一次状态(闪烁)。<syntaxhighlight lang="c++" line="1" start="9190">void RTC_TIME_SetHAL_TIM_PeriodElapsedCallback(uint8_t hour, uint8_t min, uint8_t secTIM_HandleTypeDef *htim)
{
RTC_TimeTypeDef sTime; // RTC时间结构体 sTime.Hours if(htim = hour; // 时 sTime.Minutes = min; // 分 sTime.Seconds = sec; // 秒 sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; // 不定义AM和PM,因为24小时模式 sTime.StoreOperation = RTC_STOREOPERATION_RESET; // // 设置时钟 if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BINhtim2) != HAL_OK)
{
_Error_HandlerLED_TOGGLE(__FILE__, __LINE__); // 翻转LED状态,1s翻转一次
}
}
</syntaxhighlight>设置RTC日期、星期的函数,用于设置当前的年月日、以及星期。== 实验18-独立看门狗 ==独立看门狗实验,这个实验大家可以配合窗口看门狗实验一起使用。 === STM32L476 定时器中断简介 === ''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''以下部分为TIM2 / TIM3 / TIM4 / TIM5这四个定时器的介绍。 1.通用定时器简介: 通用定时器由一个由可编程预分频器驱动的16位或32位自动重载计数器组成。它们可用于各种目的,包括测量输入信号的脉冲长度(输入捕获)或生成输出波形(输出比较和PWM)。 使用定时器预分频器和RCC时钟控制器预分频器,可以将脉冲长度和波形周期从几微秒调制到几毫秒。定时器完全独立,不共享任何资源。 2.通用定时器功能 •16位(TIM3,TIM4)或32位(TIM2和TIM5)上,下,上/下自动重载计数器。 •16位可编程预分频器,用于分频(也“在运行中”)计数器时钟 频率由1到65535之间的任何因子组成。 •最多4个独立频道: - 输入捕获 - 输出比较 - PWM生成(边缘和中心对齐模式) - 单脉冲模式输出 •同步电路,用外部信号控制定时器并互连 几个计时器。 •以下事件的中断/ DMA生成: - 更新:计数器溢出/下溢,计数器初始化(通过软件或 内部/外部触发器) - 触发事件(计数器启动,停止,初始化或通过内部/外部触发计数) - 输入捕获 - 输出比较 •支持增量(正交)编码器和霍尔传感器电路进行定位 目的 •外部时钟或逐周期电流管理的触发输入 3.通用定时器中断触发的条件 配置定时器自动装载值,以及分频系数,使能定时器的中断。当计数值向上或者向下溢出时,定时器中断触发。 计算公式为:Tout=(ARR+1)(PSC+1)/TIMxCLK (us) ''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''=== 硬件设计 ===选择STM32L4内部TIM2定时器,展示使用的是开发板上的LED指示灯D3。[[文件:NBDK-SCH-LED.png|边框|居中|无框|386x386像素]]''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''=== 实验准备 ===# 使用miniUSB线及10pin排线,通过Jlink仿真器连接PC端和开发板。# 使用miniUSB线,连接PC与开发板USB接口。# 使用Keil打开基础实验的实验17-定时器中断。# 下载程序,并完成功能测试。 === 实验验证 ===下载完成后,可以看到LED周期闪烁(1s周期,也就是点亮1s,熄灭1s)。 === 源码详解 ===本节中的源码说明,仅针对此例程中的重要功能,详细的源码介绍请大家参照代码后的注释。 ==== stm32l4xx_hal_conf.h ====此文件位于“实验16-RTC实时时钟\Inc”路径中,主要用途是选择使能此例程使用到的库文件。 此例程我们主要给大家展示STM32L4的定时器的中断功能,所以我们宏定义中打开TIM相关的。<syntaxhighlight lang="c" line="1" start="103">// 使能的宏#define HAL_MODULE_ENABLED // 芯片#define HAL_FLASH_MODULE_ENABLED // Flash#define HAL_PWR_MODULE_ENABLED // 电源#define HAL_RCC_MODULE_ENABLED // 时钟#define HAL_CORTEX_MODULE_ENABLED // NVIC #define HAL_GPIO_MODULE_ENABLED // GPIO#define HAL_DMA_MODULE_ENABLED // DMA#define HAL_UART_MODULE_ENABLED // UART#define HAL_SPI_MODULE_ENABLED // SPI#define HAL_TIM_MODULE_ENABLED // TIM定时器</syntaxhighlight> ==== main.c ====main函数,我们的例程由此处开始执行,首先调用HAL_Init()函数初始化我们的模块,接着调用SystemClock_Config()函数初始化此例程用到的时钟,具体有哪些时钟被初始化,在gyu_util.c部分有详细说明。 接下来我们分别初始化了LED及TIM2定时器。 <syntaxhighlight lang="c++" line="1" start="11932">int main(void RTC_DATE_Set(uint8_t week, uint8_t year, uint8_t monty, uint8_t date)
{
RTC_DateTypeDef sDate; /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ // RTC日期结构体重置所有外设、flash界面以及系统时钟 HAL_Init();  // 配置系统时钟(包含振荡器、系统时钟、总线时钟等等) sDate.WeekDay = weekSystemClock_Config(); // 星期 初始化LED引脚 LED_Init();
sDate.Year = year; // 初始化tim2定时器 sDate.Month = monty MX_TIM2_Init(); // 月 sDate.Date = date; // 日
// 设置日期 if while (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK1)
{
_Error_Handler(__FILE__, __LINE__);
}
}
</syntaxhighlight>闹钟时间设置的函数,用于设置闹钟触发的时分秒。==== gyu_util.c ====请参照实验01中的介绍。 基础实验中的其他例程,大部分都是使用的相同的时钟配置函数,有特殊的时钟使用,将会在对应例程的源码详解中做针对性说明。==== gyu_tim2it.c ====TIM2定时器初始化函数,我们配置TIM2时钟不分频(也就是系统时钟80MHZ),设置TIM2预分频为10000-1(也就是TIM2时钟为80M/10000 = 8000Hz),设置自动装载值为8000(也就是说一次装载满的时间为8000*(1/8000Hz) = 1s)。 这边有总结好的公式:Tout=(ARR+1)(PSC+1)/TIMxCLK (us)。ARR代表预分频,PSC代表自动装载值。 <syntaxhighlight lang="c++" line="1" start="14747">void RTC_AlarmA_SetMX_TIM2_Init(uint8_t hour, uint8_t min, uint8_t sec, uint8_t weekvoid)
{
RTC_AlarmTypeDef sAlarmhtim2.Instance = TIM2; // RTC闹钟A结构体 配置为TIM2 sAlarmhtim2.AlarmTimeInit.Hours Prescaler = hour10000-1; // ARR+1 = 10000 sAlarmhtim2.AlarmTimeInit.Minutes CounterMode = minTIM_COUNTERMODE_UP; // 向上计数 sAlarmhtim2.AlarmTimeInit.Seconds Period = sec8000-1; // PSC+1 = 8000 sAlarmhtim2.AlarmTimeInit.SubSeconds ClockDivision = 0TIM_CLOCKDIVISION_DIV1; // 亚秒(这边没有作比较,任意设置)不分频,80MHz
sAlarm.AlarmMask = RTC_ALARMMASK_NONE; // 精确到时分秒、日期或者星期 sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; // 亚秒不作比较 sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY; // 比较星期(设置星期或者日期) sAlarm.AlarmDateWeekDay = week; // 星期 sAlarm.Alarm = RTC_ALARM_A; // 闹钟A // 开启闹钟中断初始化TIM2,出错则进入错误处理函数 if (HAL_RTC_SetAlarm_ITHAL_TIM_Base_Init(&hrtc, &sAlarm, RTC_FORMAT_BINhtim2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_TIM_Base_Start_IT(&htim2); // 开启TIM2,并且使能中断}</syntaxhighlight>TIM2初始化函数,使能定时器TIM2时钟,并且使能中断。<syntaxhighlight lang="c++" line="1" start="72">void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim){ if(htim->Instance == TIM2) { __HAL_RCC_TIM2_CLK_ENABLE(); //使能定时器TIM2 HAL_NVIC_SetPriority(RTC_Alarm_IRQnTIM2_IRQn, 10, 0); // 抢占优先级10,子优先级0设置中断优先级10,子优先级0 HAL_NVIC_EnableIRQ(RTC_Alarm_IRQnTIM2_IRQn); // 使能中断 使能ITM3中断 }
}
</syntaxhighlight>闹钟回调函数,当RTC实时时钟计时到达设置的闹钟时间,就会触发此回调,我们在回调中打开蜂鸣器,并且置位闹钟的标识。定时器中断回调函数,当计数值溢出时,触发此回调,我们判断是否是TIM2触发,如果是,则翻转LED的状态。 在此实验中的表现是,LED灯1s改变一次状态(闪烁)。<syntaxhighlight lang="c++" line="1" start="18190">void HAL_RTC_AlarmAEventCallbackHAL_TIM_PeriodElapsedCallback(RTC_HandleTypeDef TIM_HandleTypeDef *hrtchtim)
{
Buzzer_SETif(htim == (&htim2)) { LED_TOGGLE(GPIO_PIN_SET); // 蜂鸣器哔一声翻转LED状态,1s翻转一次 rtcAlarm = 1;}
}
</syntaxhighlight>
510
个编辑