1.將主時鐘切換到HSE;(外部晶振爲8MkHz)
2.將主時鐘時鐘頻率8分頻,即計數器時鐘週期爲1us;
3.設置定時器250us中斷一次;
4.在中斷程序裏判斷中斷次數是否到2次;
5.到2次翻轉引腳電平。(邏輯分析儀檢測頻率)
寄存器版:
unsigned char i=255;
PE_DDR_DDR5=1;//配置PD0爲輸出模式
PE_CR1_C15=1;//配置PD0爲推輓模式
PE_CR2_C25=0;//配置PD0輸出最大爲10Mhz
if(CLK_CMSR==0xE1) {//如果HSI爲主時鐘源(復位值),切換到HSE
CLK_SWCR_SWIEN=1;//時鐘切換中斷使能
CLK_SWR=0xB4;//HSE爲主時鐘源
asm("rim");//開啓全局中斷
}
while(CLK_SWCR_SWBSY)//等待忙標誌復位
{
i--;
if(i==0) {
CLK_SWCR_SWBSY=0;//如果時鐘切換沒有成功,清除標誌位SWBSY以復位當前的切換操作
break;
}
}
TIM4_CNTR=0; //初始化計數器值
TIM4_ARR=0xFA; //自動重裝寄存器值250,250us
TIM4_PSCR_PSC=0x03; //預分頻係數爲8,8M/8=1M->1us
TIM4_EGR_UG=1; //手動產生一個更新事件,立即更新預分頻器
TIM4_IER_UIE=1;//更新中斷使能
TIM4_CR1_CEN=1;//使能計數器
while(1);
}
#pragma vector=CLK_SWITCH_vector
__interrupt void CLK_IRQHandler(void){
CLK_SWCR_SWIF=0;//清除中斷標誌
CLK_SWCR_SWEN=1;//使能時鐘切換的執行
}
unsigned char t4=0;
#pragma vector=TIM4_OVR_UIF_vector
__interrupt void TIM4_IRQHandler(void){
t4++;
if(t4==2)
{
PE_ODR_ODR5=!PE_ODR_ODR5;//取反
t4=0;
}
TIM4_SR_UIF=0;
}
庫函數版:
CLK_DeInit();//重置時鐘相關寄存器到默認復位值
GPIO_Init(GPIOE, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST);
enableInterrupts();//使能全局中斷
ErrorStatus es;
es = CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL, CLK_SOURCE_HSE, ENABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
//手動切換;新的時鐘源:HSE;啓動切換中斷;保持原時鐘源開啓
if (es == SUCCESS) //切換是否成功,SUCCESS or ERROR
{
TIM4_TimeBaseInit(TIM4_PRESCALER_8, 0xFA);//初始化時基單元,8分頻,自動重載寄存器值爲250
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);//使能TIM4更新中斷
// TIM4_PrescalerConfig(TIM4_PRESCALER_8, TIM4_PSCRELOADMODE_UPDATE);
TIM4_GenerateEvent(TIM4_EVENTSOURCE_UPDATE);//手動產生更新事件
TIM4_Cmd(ENABLE);//啓動定時器
}
else{
CLK_SYSCLKEmergencyClear();//清除時鐘切換標誌
}
/* Infinite loop */
while (1)
中斷服務程序:
INTERRUPT_HANDLER(CLK_IRQHandler, 2)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
ITStatus flags_tatus;
flags_tatus = CLK_GetITStatus(CLK_IT_SWIF);//檢測時鐘切換中斷標誌
if (flags_tatus == SET) //如果時鐘切換中斷標誌SWIF是置位狀態,SET or RESET
{
CLK_ClearITPendingBit(CLK_IT_SWIF);//清除時鐘切換中斷標誌
CLK_ClockSwitchCmd(ENABLE);//啓動時鐘切換功能
};
}
unsigned char i=0;
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
i++;
TIM4_ClearFlag(TIM4_FLAG_UPDATE);
if(i==2){
i=0;
GPIO_WriteReverse(GPIOE, GPIO_PIN_5);
}
}
頻率輸出:
這裏建議計數器計數次數不要太少,中斷服務程序里程序不宜太多,否則會造成中斷服務程序未執行完,又來一箇中斷,造成程序執行不正確。