STM32定时器中断
先看个图:
上图说明了,STM32中相关模块的总线结构,而这里用于测试的TIM3是接在了APB1上,APB1最大频率是36MHz,是算个低速的总线。
当APB1 的预分频系数为1 时,这个倍频器不起作用,定时器的时钟频率等于APB1 的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8 或16)时,这个倍频器起作用,定时器的时钟频率等于APB1 的频率两倍。
也就是,当APB1不分频,TIM3的时钟速度为36MHz,当2分频是,APB1变成18MHz,但是TIM又会倍频,即TIM时钟等于18*2=36MHz。
好了,参考编程一般步骤:
1.系统初始化,主要初始化时钟等。
2.GPIO初始化,用于LED,有了灯就便于观察了。
3.TIM3的配置。
4.NVIC的配置。
5.编写中断服务函数。
首先,系统初始化直接使用SystemInit()函数即可,但是分析汇编启动代码,发现已经做了初始化了!所以就不去瞎凑热闹了。可以省去。
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
当然别忘记了先把GPIO和TIM模块的时钟给使能了!TIM3在APB1上,GPIO在APB2上。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
第二步就是编写GPIO了,参考前面的点灯文章就明白了。代码如下:
/**led**/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);
第三步,编写TIM3的配置。这里说一下定时频率的计算方法:Frequency=(SYSCLK/(Prescaler+1)) /(Period+1);
SYSCLK即为系统时钟,这里使用72MHz,Prescaler为时钟预分频数,Period即为计数器值。
所以要得到1S的定时,即1Hz的频率,Period=1999,Prescaler= 35999,计算得出正好是1Hz,当然这里的配置关系不是随便来的。
/**tim3**/
TIM_DeInit(TIM3);
TIM_TimeBaseStructure.TIM_Period=1999; //自动重装载寄存器的值
TIM_TimeBaseStructure.TIM_Prescaler= 35999; //时钟预分频数
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_div1; //采样分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update); //清除溢出中断标志
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3, ENABLE); //开启时钟
第四步,配置NVIC。
/*nvic*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //通道TIM2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
最后呢编写个终端服务函数,每一次中断就变换一次LED的电平,也就是亮灭,这里用软件仿真一下看看LED端口波形即可。
void TIM3_IRQHandler(void)
{
static u8 sign = 1;
if ( TIM_GetITStatus(TIM3 , TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);
if(sign)
{
sign = 0;
GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_RESET);
}
else
{
sign = 1;
GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);
}
}
}
实际,仿真波形如下:
顶顶顶顶顶顶顶顶顶顶顶顶
顶顶顶顶顶顶顶顶顶顶顶顶
顶,学习中,希望能迎头赶上!
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
1. #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
2. #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
3. #define PERIPH_BASE ((uint32_t)0x40000000)
学习学习
学习学习
顶一个,,,,,,,,,,,,,,,,,,,,,,,,
支持~~~~~~~~~~~~~~~~~~~~~~~~
看看,看看,看看上。