STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试

关于几个影子寄存器的说明请参考博文:https://blog.csdn.net/huangtonggao/article/details/6458522

因为项目中马上要用到伺服电机的控制,昨天又看了一下定时器部分,看的过程中发现影子寄存器这块之前都没有仔细测试过,这次把小手动起来,好好理解下。目的主要如标题所说,看看这个ARPE位对预装载寄存器的的影响是什么样,详见下述:

测试分析如下:

ARPE=0

情况①

代码:

 int main(void)
 {
 int i=0;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
  LED_Init();      //LED端口初始化
TIM3_Int_Init(1999,7199);
LED0=0;
LED1=0;
 while(1)
{
printf("\r\n %d计数=%d \r\n ",++i,TIM3->CNT);
if(i==40)
{
TIM_ARRPreloadConfig(TIM3,DISABLE);
TIM3->ARR=3999;
// TIM_GenerateEvent(TIM3,TIM_EventSource_Update);
while(1)printf("\r\n %d \r\n ",TIM3->CNT);
}
}
 }

输出1:

   STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第1张图片          STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第2张图片

结论1:ARPE不使能并对ARR=3999赋值,CNT计数继续,并立即实现预装载进入影子寄存器(进入中断前的CNT=3997>1999)。

情况②:

代码2:

 int main(void)
 {
int i=0;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
  LED_Init();      //LED端口初始化
TIM3_Int_Init(1999,7199);
LED0=0;
LED1=0;
while(1)
{
printf("\r\n %d计数=%d \r\n ",++i,TIM3->CNT);
if(i==40)
{
TIM_ARRPreloadConfig(TIM3,DISABLE);
TIM3->ARR=499;
// TIM_GenerateEvent(TIM3,TIM_EventSource_Update);
while(1)printf("\r\n %d \r\n ",TIM3->CNT);
}
}

 }

输出2:        

STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第3张图片                                STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第4张图片

结论2:ARPE不使能并对ARR=499赋值后(此时设置的新ARR<当前CNT值),CNT继续计数,当到达CNT=1999时B并未进入中断,直到16位计数器CNT计数溢出后(CNT>65535)新的ARR=499才进入影子寄存器,并以ARR=499进行定时计数。


附加测试:将代②中的TIM_GenerateEvent(TIM3,TIM_EventSource_Update); 一句的注释取消后发现新的ARR=499立即写入了影子寄存器,并清空CNT=0,定时器以ARR=499进行定时。

输出如下图:

STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第5张图片    STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第6张图片

测试过程中出现了程序跑飞的情况,建议看客们不要这么来配置,程序员是要严谨的哈!



ARPE=1

情况③:写入ARR后立即软件产生更新事件

代码3:

 int main(void)
 {
 int i=0;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
  LED_Init();      //LED端口初始化
TIM3_Int_Init(1999,7199);
LED0=0;
LED1=0;
 while(1)
{
printf("\r\n %d计数=%d \r\n ",++i,TIM3->CNT);
if(i==40)
{
TIM_ARRPreloadConfig(TIM3,ENABLE);
TIM3->ARR=3999;
TIM_GenerateEvent(TIM3,TIM_EventSource_Update);
while(1)printf("\r\n %d \r\n ",TIM3->CNT);
}
}
 }

输出3:

STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第7张图片     STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第8张图片

结论3:ARPE使能并对ARR赋值后立即对EGR寄存器的UG=1产生更新事件,实现预装载值立即进入影子寄存器


情况④:写入ARR后不产生更新事件

代码4:

 int main(void)
 {
 int i=0;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
  LED_Init();      //LED端口初始化
TIM3_Int_Init(1999,7199);
 while(1)
{
printf("\r\n %d计数=%d \r\n ",++i,TIM3->CNT);
if(i==40)
{
TIM_ARRPreloadConfig(TIM3,ENABLE);
TIM3->ARR=3999;
// TIM_GenerateEvent(TIM3,TIM_EventSource_Update);
while(1)printf("\r\n %d \r\n ",TIM3->CNT);
}
}

 }

输出4:

STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第9张图片       STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第10张图片       STM32F1定时器关于ARPE位控制的影子寄存器(预装载寄存器ARR)写入测试_第11张图片

结论4:ARPE使能并对ARR赋值后EGR寄存器的UG=0不立即产生更新事件,从上述输出可发现,定时器会继续计数,当到达第一次设置的ARR=1999溢出后更新事件发生,ARR=3999到达影子寄存器并继续工作



你可能感兴趣的:(STM32)