注意 STM32的中断函数的名字在startup_stm32f10x_md.s中去找不可以随便取名字
重点 NVIC
1 , NVIC是什么
2, NVIC如何配置
3,定时器中断如何写
一, NVIC
NVIC 他是一种中断控制器,NVIC控制着处理器上的硬件中断,包括外部硬件设备、定时器、内部事件等发出的中断。它能够接收多个中断源的中断信号,并根据优先级进行排序,在需要时将中断请求提交给处理器
NVIC用于管理中断并协调处理器与外部设备之间的交互
应为32的中断相比于51多太多了所以专门搞个组件进行中断信号的处理
他的库函数在misc里面
流程就是
现在我需要用用定时器触发中断->>>>
定时时间到了 ,好现在发出一个中断请求给到NVIC 他跟据一个先来后的和优先级进行安排
到你这个中断请求的时候他向CPU请求中断 然后进入中断执行你要的动作
0.NVIC分组 1 声明NVIC结构体 2 初始话NVIC结构体 3 使能NVIC结构体
0, 代码如下 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
这行代码将NVIC的中断优先级组设置为4位。这意味着当有多个中断同时触发时,NVIC会根据这4位优先级来决定哪个中断会被优先处理。
1.NVIC_InitTypeDef NVIC_InitStructure; (结构体的类型) (结构体变量);
2,3 重点 TIM初始化配置
TIM_TimInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上还是向下计数
TIM_TimInitStructure.TIM_Period = 10000-1;//周期预设值
TIM_TimInitStructure.TIM_Prescaler =7200-1;//预分屏 72M/7200=10M
TIM_TimInitStructure.TIM_RepetitionCounter = 0; // 计数器初值
TIM_ClearFlag(TIM2,TIM_FLAG_Update);//当定时器的值更新时TIM_FLAG_Update会被置一通过这个函数清除做过标志位
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出配置
TIM_TimeBaseInit(TIM2 , &TIM_TimInitStructure); //把定时器的配置结构体加载到指定定时器的寄存器
定时器使能需要配置NVIC 后开启 TIM_Cmd(TIM2,ENABLE); //定时器使能还是失能
定时器的时间如何计算
用1除以频率 如果我是10M 就是 1/10000000 = 0.0000001 = 0.1微秒 = 100纳秒
那么计数器记一个数就是 100纳秒,那么定时器的时钟周期就是100ns
然后看你的计数溢出值是多大 0-65536
我这是9999
得到定时器进入触发一次中断的时间为 (9999+1) * 100ns = (9999+1) * 0.0000001s =
1000000 ns= 1000us = 1ms
可以化简 10000(溢出值)/10M(定时器频率) * 1S = 0.01S = 1MS;
重点 TIM中断的读取和标志位的清除
if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) //判读是不是由定时器跟新中断触发的定时器中断
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
//清除定时器更新中断标志位
}
源码
#include "TIME.h" // Device header
extern uint16_t Num;
void Timer_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);
TIM_TimInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimInitStructure.TIM_Period = 10000-1;//周期预设值
TIM_TimInitStructure.TIM_Prescaler =7200-1;//预分屏 72M/7200=10M
TIM_TimInitStructure.TIM_RepetitionCounter = 0;
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出配置 选择定时器 选择要配置那个中断输出 使能还是失能
TIM_TimeBaseInit(TIM2 , &TIM_TimInitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2,ENABLE);
// TIM_ARRPreloadConfig();
// TIM_TimeBaseInit();//时基单元初始化 选择那个定时器 时间单元配置参数(一个结构体)
// TIM_TimeBaseStructInit();//把结构体变量赋一个默认值
// TIM_Cmd();//使能定时器 选择定时器 使能还是失能
}
//TIM2 中断函数
void TIM2_IRQHandler()
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
{
Num++;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}