關於幾個影子寄存器的說明請參考博文: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:
結論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:
結論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進行定時。
輸出如下圖:
測試過程中出現了程序跑飛的情況,建議看客們不要這麼來配置,程序員是要嚴謹的哈!
情況③:寫入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:
結論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:
結論4:ARPE使能並對ARR賦值後EGR寄存器的UG=0不立即產生更新事件,從上述輸出可發現,定時器會繼續計數,當到達第一次設置的ARR=1999溢出後更新事件發生,ARR=3999到達影子寄存器並繼續工作。