嵌入式系统原理与应用实验报告-定时器TIMx实验
文章目录
一、实验目的
1.1 TIMx的更新方式定时实验
- 掌握TIMx定时器更新定时中断方式进行准确定时的方法
- 掌握TIMx在更新方式下定时时间的设置,会计算定时时间并设置初值
- 熟悉TIMx定时器在更新方式下的中断初始化
- 掌握更新中断服务函数的设计方法
- 熟悉让LCD显示闪烁字符的方法
1.2 基于TIMx的比较方式定时
- 掌握TIMx定时器比较定时中断方式进行准确定时的方法
- 熟悉TIMx定时器在比较方式下的中断初始化
- 掌握TIMx在比较方式下根据定时时间的要求确定比较器初值的方法,熟悉用一个定时器通过4哥比较器进行多种定时的方法
- 掌握比较中断服务函数的设计方法
1.3 TIMx的PWM输出实验
- 掌握TIM4定时器的PWM输出功能以及输出占空比可调的脉冲序列的方法
- 掌握TIM4的PWM输出初始化程序设计
- 掌握PWM输出频率和占空比的计算方法
二、实验原理(硬件连接及软件流程、简单原理说明)
2.1 实验设备
- 硬件:PC一台、WEEEDK嵌入式实验开发平台一套
- 软件:操作系统Windows、MDK-ARM 集成开发环境
2.2 实验硬件连接图
2.3 实验简单原理
STM32F10x系列内部有8个16位通用定时计数器,TIM1和TIM8被称为高级控制定时器(连接在APB2快速外设总线上),TIM2-TIM7为普通定时器(连接在APB1相对慢速外设总线上),在普通定时器中把其中的TIM2-TIM5称为通用定时器,TIM6和TIM7称为基本定时器。
TIMx定时器除了可以进行更新、比较等定时外,还可以用于计数,定时器的内部结构及可编程相关寄存器在书P25-P32页。
TIMx定时时间
- 更新定时时间
T
=
(
1
+
A
R
R
)
×
(
1
+
P
S
C
)
/
F
T=(1+ARR)\times(1+PSC)/F
T
=
(
1
+
A
RR
)
×
(
1
+
PSC
)
/
F
A
R
R
=
T
×
F
/
(
1
+
P
S
C
)
−
1
ARR=T\times F/(1+PSC)-1
A
RR
=
T
×
F
/
(
1
+
PSC
)
−
1
- 比较定时时间
T
=
C
C
R
×
(
1
+
P
S
C
)
/
F
T=CCR\times(1+PSC)/F
T
=
CCR
×
(
1
+
PSC
)
/
F
C
R
R
=
T
×
F
/
(
1
+
P
S
C
)
CRR=T\times F/(1+PSC)
CRR
=
T
×
F
/
(
1
+
PSC
)
三、实验内容与实验步骤
3.1 TIMx的更新方式定时实验
3.1.1 实验内容
- TIM1用更新中断方式定时1000ms,在其对应的中断服务程序中,让LED1闪烁;
- TIM2用更新中断方式定时500ms,在其对应的中断服务程序中,让LED2闪烁;
- TIM3用更新中断方式定时200ms,在其对应的中断服务程序中,让LED3闪烁。
3.1.2 实验步骤
(1) 连接+5V电源到开发板,并打开电源开关,将ST-LINK 仿真器连接到WEEEDK嵌入式系统实验开发板的 JTAG插座上,USB 插头连接到PC的USB插口。如果没有驱动请安装ST-LNK 驱动,直到在设备管理器上看到STMicroelectronics STLink dongle为止。
(2)复制”TIMx更新中断”文件夹中的所有内容到D盘,双击 GPIO-LED跑马灯实验的\Project\Project.uvprojx 实验工程文件,打开实验工程,阅读 main()函数。
(3) 按F7 功能键编译并链接工程。
(4) 按Ctrl+F5键或单击调试按钮,进入集成调试环境。
(5) 按F5功能键全速运行,查询三个发光二极管闪烁情况,并观察LCD上的显示信息,观察定时器窗口,查看相关定时器寄存器的变化
实验现象:三个发光二级管分别以1000ms,500ms,200ms的周期进行闪烁,下面为寄存器的变化状态
当全速运行时,在TIM1窗口调整重复计数器RCR的值,输入1表示重新两次。输入9后曾表示重复10次,每次一秒,一共十秒。此时LED亮和灭为10s。(只有TIM1和TIM8高级定时器才具有重复计数器RCR)
如下图所示
(6) 进入调试模式,利用断点或执行到光标处等调试手段进行调试,在中断服务函数中添加让LCD在指定位置显示定时时间,按照实际时间闪烁
修改后的TIM1中断函数如下
void TIM1_UP_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) /*判断是否是更新中断*/
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update); /*清除中断标志*/
TP1++;
if(TP1%2==0)
{
Gui_StrCenter(0,130,WHITE,BLACK,"TIM1 更新定时 1000ms",16,0);//居中显示
}
else
{
Gui_StrCenter(0,130,WHITE,BLACK,"TIM1 更新定时 ms",16,0);//居中显示
}
if (TP1&1) GPIO_ResetBits(GPIOD,GPIO_Pin_2); /* PD2=0(LED1亮)*/
else GPIO_SetBits(GPIOD,GPIO_Pin_2); /* PD2=1(LED1灭)*/
}
}
(7)在LCD合适的位置显示自己的学号和姓名
在font.h中的typFNT_GB16 tfont16[]添加名字编码
"万",
0x00,0x00,0x00,0x00,0xFF,0xFE,0x04,0x00,0x04,0x00,0x04,0x00,0x07,0xF0,0x04,0x10,
0x04,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x10,0x10,0x20,0x10,0x40,0xA0,0x80,0x40,/*"万",10*/
"晔",
0x00,0x90,0x00,0x94,0x79,0x14,0x49,0x18,0x4B,0x10,0x4D,0x32,0x49,0x52,0x79,0x0E,
0x49,0x20,0x48,0x20,0x4B,0xFE,0x48,0x20,0x78,0x20,0x48,0x20,0x00,0x20,0x00,0x20,/*"晔",11*/
修改welcome()函数
void Welcome(void)
{
DrawTestPage("TIMx更新定时实验测试程序");
Gui_StrCenter(0,40,BRED,YELLOW,"南航 NUAA_CM3_107 KIT",16,0);//居中显示
//Gui_StrCenter(0,60,RED,BLUE,"嵌入式系统配套实验开发板",16,1);//居中显示
if (USE_HORIZONTAL==1) Show_Str(45,65,GREEN,BLACK,"嵌入式系统实验开发板",24,1);
else Show_Str(10,65,GREEN,BLACK,"嵌入式系统实验开发板",24,1);
//Gui_StrCenter(0,46,RED,BLUE,"嵌入式系统原理及应用配套实验板",16,1);//居中显示
Gui_StrCenter(0,100,YELLOW,BLACK,"TIMx更新定时实验测试程序",16,0);//居中显示
Gui_StrCenter(0,130,WHITE,BLACK,"TIM1 更新定时 1000ms",16,0);//居中显示
Gui_StrCenter(0,150,WHITE,BLACK,"TIM2 更新定时 500ms",16,0);//居中显示
Gui_StrCenter(0,170,WHITE,BLACK,"TIM3 更新定时 200ms",16,0);//居中显示
Gui_StrCenter(0,210,WHITE,BLACK,"161910110 万晔",16,0);//居中显示
//Gui_StrCenter(0,190,YELLOW,BLACK,"TIMx更新定时定时时间:",16,0);//居中显示
}
实验效果
3.2 基于TIMx比较中断定时实验
3.2.1 实验内容
- TIM3用CCR1比较中断方式定时1000ms,在其对应的中断服务程序中,让LED1闪烁;
- TIM3用CCR2比较中断方式定时500ms,在其对应的中断服务程序中,让LED2闪烁;
- TIM3用CCR3比较中断方式定时200ms,在其对应的中断服务程序中,让LED3闪烁
- TIM3用CCR4比较中断方式定时100ms,在其对应的中断服务程序中,让IED4闪烁。
3.2.2 实验步骤
(1) 连接+5V电源到开发板,并打开电源开关,将ST-LINK 仿真器连接到WEEEDK嵌入式系统实验开发板的 JTAG插座上,USB 插头连接到PC的USB插口。如果没有驱动请安装ST-LNK 驱动,直到在设备管理器上看到STMicroelectronics STLink dongle为止。
(2)复制”TIMx比较中断计时”文件夹中的所有内容到D盘,双击GPIO-LED跑马灯实验的\Project\Project.uvprojx 实验工程文件,打开实验工程,阅读 main()函数。
(3) 按F7 功能键编译并链接工程。
(4) 按Ctrl+F5键或单击调试按钮,进入集成调试环境。
(5)按F5功能键全速执行。查询4个发光二极管闪烁情况,并观察LCD上的显示信息以及TIM3定时器窗口相关寄存器的变化
中断函数如下
void TIM3_IRQHandler(void)
{
uint16_t capture = 0;
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); /*是比较中断,清除中断标志*/
GPIOD->ODR ^= 1<<2; /*LED1(PD2)*/
capture = TIM_GetCapture1(TIM3); /*取当前计数值*/
TIM_SetCompare1(TIM3, capture + CCR1_Val); /*写新比较值到比较寄存器*/
}
else if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
GPIOD->ODR ^= 1<<3; /*LED2(PD3)*/
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + CCR2_Val);
}
else if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
GPIOD->ODR ^= 1<<4; /*LED3(PD4)*/
capture = TIM_GetCapture3(TIM3);
TIM_SetCompare3(TIM3, capture + CCR3_Val);
}
else if (TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
GPIOD->ODR ^= 1<<7; /*LED4(PD7)*/
capture = TIM_GetCapture4(TIM3);
TIM_SetCompare4(TIM3, capture + CCR4_Val);
}
}
(6)在编译环境下修改程序,改变比较定时时间(试改比较器的值),编译下载运行后查看LED闪烁情况
在
time.c
里面进行修改
#include "stm32f10x.h"
u16 CCR1_Val = 10*2000; /*定时2000ms*/
u16 CCR2_Val = 10*500; /*定时500ms*/
u16 CCR3_Val = 10*200; /*定时200ms*/
u16 CCR4_Val = 10*100; /*定时100ms*/
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period =65535;
TIM_TimeBaseStructure.TIM_Prescaler =(SystemCoreClock/10000)-1;/*预分频*/
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Output Compare Timing Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; /*输出定时模式*/
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;/*输出禁止,这里仅比较,不输出*/
TIM_OCInitStructure.TIM_Pulse = CCR1_Val; /*比较脉冲个数*/
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
/* Output Compare Timing Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
/* Output Compare Timing Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
//TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
/* TIM Interrupts enable */
TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 |TIM_IT_CC4, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
这里修改CCR_Val的值即可,定时为2000ms,即两秒
(7)在LCD上合适的位置显示自己的学号和姓名
3.3 TIMx的PWM输出实验
3.3.1 实验内容
TIM4的通道3 (PB8)设置为PWM输出,产生频率为10KHz,占空比可调的PWM信号输出以控制板载直流电机,用于电机调速。通过KEY1和KEY2两个按键,改变占空比,从而改变直流电机运行速度。相关信息包括计数脉冲个数、占空比显示在LCD屏上。
自行改为1KHz看效果!
3.3.2 实验步骤
(1) 连接+5V电源到开发板,并打开电源开关,将ST-LINK 仿真器连接到WEEEDK嵌入式系统实验开发板的 JTAG插座上,USB 插头连接到PC的USB插口。如果没有驱动请安装ST-LNK 驱动,直到在设备管理器上看到STMicroelectronics STLink dongle为止。
(2)复制”TIMxd的PWM输出”文件夹中的所有内容到D盘,双击GPIO-LED跑马灯实验的\Project\Project.uvprojx 实验工程文件,打开实验工程,阅读 main()函数。
(3) 按F7 功能键编译并链接工程。
(4) 按Ctrl+F5键或单击调试按钮,进入集成调试环境。
(5)按F5功能键全速执行。观察LCD上的显示信息
(6)试着按下KEY1键,增加占空比,直到电机运转,然后不断按KEY1键,增加占空比,提升电机速度,观察LCD上的占空比及脉冲个数的变化,最后按KEY2键,减小占空比,降低电机速度。
(7)试着修改程序,改变PWM频率
在Timer.c文件中,修改预分频器的值及定时常数即可改变PWM周期
改为1KHz,根据公式
T
=
(
1
+
A
R
R
)
∗
(
1
+
P
S
C
)
/
F
T=(1+ARR)*(1+PSC)/F
T
=
(
1
+
A
RR
)
∗
(
1
+
PSC
)
/
F
要改为1KHz,则需要将预分频器的值改为
9
即可。
void Init_TIMER(void)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; //定义一个定时器结构体变量
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4,重要!!
TIM_DeInit(TIM4); //将IM2定时器初始化位复位值
TIM_InternalClockConfig(TIM4); //配置 TIM4 内部时
TIM_BaseInitStructure.TIM_Period = 7200-1; //设置自动重载寄存器值为最大值 0~65535之间 7200/72000000=1/10000s=0.1ms即10KHz
//TIM_Period(TIM1_ARR)=7200,计数器向上计数到7200后产生更新事件,
//计数值归零 也就是 1ms产生更新事件一次
TIM_BaseInitStructure.TIM_Prescaler = 9; //自定义预分频系数为0,即定时器的时钟频率为72M提供给定时器的时钟 0~65535之间
//设置预分频器分频系数0
TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分割为0
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
//TIM向上计数模式 从0开始向上计数,计数到1000后产生更新事件
TIM_TimeBaseInit(TIM4, &TIM_BaseInitStructure); //根据指定参数初始化TIM时间基数寄存器
TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIMx在 ARR 上的预装载寄存器
TIM_Cmd(TIM4, ENABLE); //使能TIM4
}
(8)在LCD上合适的位置显示自己的学号和姓名
四、实验结果分析及体会
4.1 TIMx更新中断定时实验
通过修改程序,成功在原来固定显示1000ms、500ms和200ms的位置,按照实际时间,闪烁显示这些时间参数(不包括“ms”字符)。即在中断服务函数中,添加代码,采用Gui_StrCenter()函数,判别奇数次定时到时,让LCD在指定位置显示时间,偶数定时到时,让LCD在指定位置显示空格。同时,在LCD适合的位置也显示了学号和姓名,达到了预期的实验效果。
实验结果图片:
4.2 TIMx比较中断定时实验
这次实验用比较中断方式定时时间来让发光二极管闪烁。通过改变比较定时时间(试改比较器的值),编译下载运行后发现LED1—4闪烁频率发生想要的改变,达到了预期的实验效果。
实验结果图片:
4.3 TIMx的PWM输出实验
相比输出频率在10KHZ,在同样的计数脉冲下,1KHZ的占空比更大。实验达到了预期的实验效果
实验结果图片:
4.4 实验体会
五、自我评价成绩(说明理由,等级为优、良、中、及格和不及格)