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);
}
}
频率输出:
这里建议计数器计数次数不要太少,中断服务程序里程序不宜太多,否则会造成中断服务程序未执行完,又来一个中断,造成程序执行不正确。