大容量的STM32F101xx、STM32F103xx系列和互联型产品中包括了两个根本守时器,TIM6和TIM7。这两个守时器功用十分简略,根本上和SysTick守时器适当。
可是我在运用的时分确是费了一番曲折才调试经过,所以仍是应该将这两个守时器的运用方法好好的写一写。
根本守时器TIM6和TIM7各包括一个16位主动装载计数器,由各自的可编程预分频器驱动。简略的说两个守时器是从0计数到N(由主动装载计数器来确认N的详细值),然后复位回0从头计数。每次复位到0的时分能够发生对应的中止信号,或许发生DMA恳求,还能够触发DAC同步电路。不过这次笔记不评论触发DAC的问题,等写到DAC的运用时在解说如何用这两守时器驱动DAC。
根本守时器TIM6和TIM7挂载在APB1总线上,在运用之前需求先使能对应的时钟信号。对应的查办如下:
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE);
APB1总线上的时钟信号在进入守时器之后第一件工作是被预分频器TIMx_PSC分频。程序中随时都能够更改TIMx_PSC的值,可是TIMx_PSC是有缓冲的,只要发生了更新事情时新的预分频值才会收效。
别的有一点必需求特别注意:假如咱们想对CK_PSC时钟信号N分频的话,TIMx_PSC中应该写入M-1,而不是M。
对应的查办如下:
- TIMx->PSC=M-1;
假如咱们期望马上更新预分频器也是有方法的,那便是软件触发一次更新事情。TIM6和TIM7有个事情发生寄存器(TIMx_EGR)便是起这个效果的。TIMx_EGR只要最低位有用,称之为UG位,向这一位写入1则发生更新事情,守时器的计数器被归零。
对应的查办如下:
- TIMx->EGR=0x0001;
主动重装载寄存器TIMx_ARR决议了CNT计数器最高记到多少就会归零。主动重装载寄存器也是带缓存的。假如TIMx_CR1寄存器中的主动重装载预加载使能位(ARPE)为0,则写入主动重装载寄存器的值当即起效果。假如ARPE=1,则要比及发生了更新事情后才会起效果。举例来说,当时主动重装载寄存器的值为20000,CNT计数器的值为1000,ARPE=1,这时咱们向主动重装载寄存器写个5000,CNT计数器记到5000时并不会归零,它还要继续直到记到20000然后归零,在归零的一起发生计数器溢出事情,计数器溢出事情能够发生更新事情,之后主动重装载寄存器的值才真的变为5000了。
这儿呈现了两个事情:计数器溢出事情和更新事情。这两个实践是不同的。每次当计数器溢出时都会发生计数器溢出事情,可是不一定发生更新事情。
TIM6和TIM7操控寄存器1(TIMx_CR1)有一位UDIS:制止更新(Updatedisable)位。
假如这位被设置为1,则计数器溢出事情不会发生更新事情。不发生更新事情则预分频器的系数不能被更新,主动重装载寄存器的值也或许不能更新(ARPE=1)。
仅仅发生更新事情是没有用的,咱们终究需求的是发生中止或DMA恳求。这儿先说中止的发生。
TIM6和TIM7DMA/中止使能寄存器(TIMx_DIER)有一位为UIE。只要这一位为1时才干发生更新中止。
对应的查办如下:
- TIMx->DIER|=0x0001;
TIM6和TIM7状况寄存器(TIMx_SR)中也只要一位是有用的,坐落这个寄存器的最低位,称之为UIF位。这一位为1标志着发生了更新中止。什么时分这一位才干为1呢?简略的说便是发生更新事情这一位会被置位为1,不过也有特殊状况,咱们知道有两种状况会发生更新事情:计数器溢出事情和UG=1。假如TIMx_CR1的URS位被设为了1,则UG=1发生的更新事情不会将UIF方位位1。
一般来说咱们都不期望UG=1时发生中止,所以大都时刻咱们会设置URS位为1。
对应的查办如下:
- TIMx->CR1|=0x0004;
下面是一个比如程序,运用TIM6,发生一个5Hz的守时中止。时钟频率为72MHz。
- voidTIM6_Init(void)
- {
- NVIC_InitTypeDefNVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel=TIM6_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
- TIM6->PSC=7200-1;//分频之后的时钟频率为10KHz
- TIM6->ARR=2000-1;//5Hz守时频率
- TIM6->CR1=0x0004+0x0001;//URS=1CEN=1
- TIM6->DIER=0x0001;//使能更新中止
- }
- voidTIM6_IRQHandler(void)
- {
- LED_Flash(GPIO_LED2);
- TIM6->SR=0x0000;//清标志位
- }
还能够彻底用STM32F10xStandardPeripheralsFirmwareLibrary来写这个程序。下面用TIM7完成相似的功用。
- voidTIM7_Init(void)
- {
- TIM_TimeBaseInitTypeDefTIM7_TimeBaseStructure;
- NVIC_InitTypeDefNVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel=TIM7_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
- NVIC_Init(&NVIC_InitStructure);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE);//RCC_APB1Periph_TIM7
- TIM_TimeBaseStructInit(&TIM7_TimeBaseStructure);
- TIM7_TimeBaseStructure.TIM_Prescaler=36000-1;//分频之后的时钟频率为2KHz
- TIM7_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
- TIM7_TimeBaseStructure.TIM_Period=400-1;//5Hz守时频率
- TIM7_TimeBaseStructure.TIM_ClockDivision=0;
- TIM_TimeBaseInit(TIM7,&TIM7_TimeBaseStructure);
- TIM_UpdateRequestConfig(TIM7,TIM_UpdateSource_Regular);
- TIM_Cmd(TIM7,ENABLE);
- TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);
- }
- voidTIM7_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM7,TIM_IT_Update)==SET)
- {
- LED_Flash(GPIO_LED3);
- TIM_ClearITPendingBit(TIM7,TIM_FLAG_Update);
- }
- }
程序写完了,这儿说几点注意事项。
(1)在对TIMx 进行设置之前一定要翻开APB1总线上对应的时钟,不然一切的设置都不起效果。
(2)一定要设置NV%&&&&&%,由于默许状况下这些外设的中止都是被禁用的。