一、 实验简介(实验目的)
本实验将利用 TIM3 的定时器中断来控制 DS1 的翻转,在主函数用 DS0 的翻转来提示程序正在运行。
二、 实验设备(实验设备及用到的模块)
1.电脑:window10及以上
2.开发板名称:正点原子战舰V3 STM32F103开发板
3.模块名称:KEY模块、LED模块、TIMER模块
4.数据通信方式及设备
三、 实验原理(软硬件全面阐述)
1. 芯片该部分工作原理
(1).LED部分对应芯片引脚
本定时器实验需要控制LED0和LED1,首先就是要在MCU里定位到LED0和LED1连接的引脚。
如上图所示,LED0连接的引脚是PB5,LED1连接的引脚是PE5。所以在led.h文件中通过引脚宏定义LED0和LED1,具体如下:
#define LED0 PBout(5)
#define LED1 PEout(5)
(2).KEY部分对应芯片引脚
在战舰 STM32 开发板上的按键 KEY0 连接在引脚PE4 上、KEY1 连接在引脚PE3 上、KEY2 连接在引脚PE2 上、WK_UP 连接在引脚PA0 上。所以在key.h文件中通过引脚宏定义LED0和LED1,具体如下:
2.模块工作原理、电路图等
(1).LED的STM32连接原理图
通过位带来操作引脚输出高低电平,以LED0为例:
LED0=1; //通过位带操作控制 LED0 的引脚 PB5 输出高电平
LED0=0; //通过位带操作控制 LED0 的引脚 PB5 输出低电平
通过LED电路图分析可知:当引脚PB5输出低电压时,即LED0=0时灯亮;当引脚PB5输出高电压时,即LED0=1时灯灭。LED1同理。
(2).KEY的STM32连接原理图
如上图电路图所示,KEY0、KEY1 和 KEY2 都接地都是是低电平有效,而 WK_UP接的是VCC3.3所以是高电平有效,并且外部都没有上下拉电阻,所以需要在 STM32 内部设置上下拉。
3. 用到的库函数阐述
(1)、计数器当前值寄存器CNT
(2)、预分频寄存器TIMx_PSC
(3)、自动重装载寄存器(TIMx_ARR)
(4)、控制寄存器1(TIMx_CR1)
(5)、DMA中断使能寄存器(TIMx_DIER)
(6)、定时器参数初始化:
VoidTIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct);
(7)、定时器使能函数:
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
(8)、定时器中断使能函数:
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
(9)、状态标志位获取和清除
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
4. 关键程序分析
在main.c文件中对 TIM3 进行初始化之后,进入死循环等待TIM3 溢出中断,当TIM3_CNT 的值等于TIM3_ARR 的值的时候,就会产生TIM3 的更新中断,然后在中断里面取反LED1,TIM3_CNT 再从0 开始计数。
int main(void)
{
delay_init();
//延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);/设置vIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200);//率口初始化知15200
LED_Init();
/LED端口初始化
TI3_Int_Init(4999,7199);//10khz的计数颜率,计数5000为500ms
while(1)
{
LEDe=!LED0;
delay_ms(200);
}
}
四、 程序分析(程序总体介绍,模块设计)
1.程序总体概述
① 使能定时器时钟:RCC_APB1PeriphClockCmd();
② 初始化定时器,配置ARR,PSC:TIM_TimeBaseInit();
③ 开启定时器中断,配置NVIC:
void TIM_ITConfig();
NVIC_Init();
④ 使能定时器:TIM_Cmd();
⑤ 编写中断服务函数:TIMx_IRQHandler();
2. 各个模块阐述
(1).LED模块:小灯初始化并使能时钟
(2).KEY模块:按键初始化,设置响应优先级
(3).TIMER模块:实现定时器中断
3.程序分析总结
1)TIM3 时钟使能。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
2)初始化定时器参数,设置自动重装值,分频系数,计数方式等。
typedef struct
{
uint16_tTIM_Prescaler;
uint16_tTIM_CounterMode;
uint16_tTIM_Period;
uint16_tTIM_ClockDivision;
uint8_tTIM_RepetitionCounter;
}TIM_TimeBaseInitTypeDef,
3)设置
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
4)TIM3 中断优先级设置。
用NVIC_Init 函数实现中断优先级的设置
5)允许TIM3工作,也就是使能TIM3
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
6)编写终端服务函数
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)
-
分析需要配置的寄存器:RCC_APB2ENR外设时钟使能寄存器、GPIOx_CRL端口配置低寄存器、ODR端口输出寄存器、BSRR端口位设置/清除寄存器、BRR端口位清除寄存器。
-
对寄存器操作(以RCC为例):在led.c中鼠标放在RCC->APB2ENR|上右键选择“Go to definition of …”跳转到stm32f10x.h文件相应位置可以看到RCC本身就是个指针格式,指针类型为“RCC_TypeDef *”类型,对该指针进行再次跳转,可以查看stm32f10x.h文件中的结构体RCC_TypeDef的成员。