定时器中断实现灯的亮灭

定时器中断功能

什么是中断事件

结合生活实际 讲解中断概念

例子:你在上班 ,突然来了个电话  妈妈说有急事 老板也突然叫你去出差
 不管怎么样 最后你就继续回公司上班了。
事件:你在上班
触发中断事件:电话
中断事件 :去妈妈那里解决好急事
中断事件 :去出差
其实中断事件 就是 你在做一个事件 然后突然跑去做新的事件 
这时的事件 就可以叫做 中断事件  
触发中断事件 :原来事件到新事件产生过程的条件

定时器简介

通用定时器的简单了解

定时器是一个通过可编程的16位自动装载计数器构成的。
大多用于测量输入捕获或者输出比较和pwm的周期时间 。

定时器的功能包括
1向上计数模式 向下计数模式 *对齐计数模式
定时器中断实现灯的亮灭

向上计数模式 :计数器 从0 开始 增加 到ARR(自动加载值) 最后重新从0开始计数  并且会产生一个溢出时间  
 也就是说  增加到了ARR 的值 后 会马上清零 清零的同时 会产生一个新的事件发生。
 向下计数模式 :和向下计数模式相反
 *对齐模式
 计数器从0开始计数到ARR==-1 产生一个新的周期事件,然后向下计数到1同时产生一个计数器溢出事件,最后再从0开始计数
 

结构体介绍

用到的定时器中断部分结构体

typedef struct
{
  uint16_t TIM_Prescaler;     //预分频系数                                 
  uint16_t TIM_CounterMode;     //计数模式                                     
  uint16_t TIM_Period;       //自动重装载值
  uint16_t TIM_ClockDivision;     // 定时器中断事件配置
 }
TIM_TimeBaseInitTypeDef;  

硬件展示

定时器中断实现灯的亮灭
定时器中断实现灯的亮灭

定时器中断实现灯的亮灭

软件设计

1)接线
32的 PA10(RX) ----- —ttl转use 的tx
32的PA9 (tx) -----------ttl转 use的rx
32的GND----------------GND
VCC(3.3或者5)----VCC(3.3或者5)
2)下载配置
定时器中断实现灯的亮灭

因为ttl转 use 是一个串口 下载器 要生成hex
3)对应软件
定时器中断实现灯的亮灭

特别注意 如果没有选完红色框框的内容 就可能会出错

中断事件的补充讲解

上面讲了产生中断的条件 发生的中断事件的大概过程 但是这里有一个问题 
如果是 产生了两个中断事件 这时你必须只能选择 做完 一件 
再去做第二件中断事件 这时就延伸出了中断 优先级的概念

中断优先级

优先级图表
定时器中断实现灯的亮灭

32 中 一共有 5个优先级组  
一个优先级 组 分为 父优先级 和子优先级
优先级大小 0-15  0最大 依次减少等级

优先级组结构体配置

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

优先级对应的定时器结构体配置

   NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;

父优先级结构体配置

 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;

子优先级结构体配置

 NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;

定时器的计算

/* 
Tout= (¨ARR(自动装载值)*psc(预分频系数))/频率
Tout= (¨TIM_Period*TIM_Prescaler£)/36 000 000 
Tout是算出定时器中断溢出的的周期持续时间
因为 TIM2 是在 APB1总线上的  所以对应的 频率是 36000000=36兆的
*/

代码

tim.c 定时器函数

#include "stm32f10x.h"
#include "tim.h"
/* 
Tout=£¨TIM_Period*TIM_Prescaler£©/36 000 000 
*/


void tim_init(void)
{
	
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;

RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE);

TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_IT_Update;//定时器中断
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;// 向上计数模式
TIM_TimeBaseInitStruct.TIM_Period=5000-1;// 自动装载值
TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;// 预分频系数
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);//初始化
TIM_Cmd(TIM2,ENABLE);//使能
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//  允许更新中断源
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 优先级组2
NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;// 对应的定时器2优先级
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;// 父优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;// 子优先级
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;// 使能
NVIC_Init(&NVIC_InitStruct);// 初始化
}

main.c+定时器中断函数

#include "stm32f10x.h"
#include "main.h"
#include "tim.h"
#include "rxt.h"
#include "LED.h"

void  main(void)
{

	tim_init();
	rxt_init();
	LED_init();
   GPIO_SetBits(GPIOC, GPIO_Pin_13);//初始化灯为灭的状态
   while(11); 
}


void TIM2_IRQHandler(void)
{
	 static unsigned  int temp; //静态变量 防止重复使用

	if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
	 
 {
	 
	 if(temp++%2==1)//产生一个周期 就亮
	 { 
		 GPIO_ResetBits(GPIOC, GPIO_Pin_13); 
	 }
	 
	 else//产生下一个周期事件就 灭 
	 {
	   GPIO_SetBits(GPIOC, GPIO_Pin_13 );
	 }
		 	 
 }

 TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //每执行完一次
                                          // 就清除中断标志位
 

}

最后你们

可以去试试 
上一篇:我 搞了一个 尺规作图 不能 实现 三等分角 的 证明


下一篇:Mininet