1、STM32 IO中断方式测试频率有要求,频率不能过快,目前测试2M没问题,频率过高中断触发就处理不过来。
2、过快的频率得先降频,用D触发器对频率进行降频,如下图所示,2、4、8、16分频,此例用2M时钟进行测试,对2M时钟进行2、4、8、16分频
3、设置一个定时器,用于计时,可用于测试一段函数使用的时间
1 void times_on(void) 2 { 3 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 4 5 RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE); 6 7 /* Time base configuration */ 8 TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; 9 TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 2) / 1000000) - 1; //TIM2 clocked by 1MHz 10 TIM_TimeBaseStructure.TIM_ClockDivision = 0; 11 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 12 13 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 14 TIM_ARRPreloadConfig(TIM2, ENABLE); 15 16 /* TIM Interrupts disable */ 17 TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, DISABLE); 18 19 /* TIM2 enable counter */ 20 TIM_Cmd(TIM2, ENABLE); 21 22 } 23 void times_off(void) 24 { 25 TIM_Cmd(TIM2, DISABLE); 26 27 } 28 29 uint32_t get_cur_times() 30 { 31 return TIM2->CNT; 32 }
4、利用IO上升沿中断方式触发,在中断里计数,比如计数10000次,也就是10000个时钟周期
IO配置:
void gpio_config(void) { //PA0外部中断触发 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); }
中断配置:
void EXTI_Config(void) { EXTI_InitTypeDef EXTI_InitStructure; //PA0作为外部中断,得相连接 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0;//通道 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿 EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能 EXTI_Init(&EXTI_InitStructure); } void NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //由于使用的是PA0,对应的是EXTI0通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //中断使能 NVIC_Init(&NVIC_InitStructure); }
stm32f4xx_it.c 中断函数:
#define EXIT_CNT 10000 //测试10000个时钟周期计数 float T = 0.0; float Fre = 0.0; uint32_t exit_cnt = 0; uint8_t exit_flg = 0; __IO uint32_t time_1 = 0; __IO uint32_t time_2 = 0; void EXTI0_IRQHandler() { if(0 == exit_cnt) { time_1 = get_cur_timestamp(); //首次触发进入中断,获取当前值 } EXTI_ClearITPendingBit(EXTI_Line0); exit_cnt ++; if(EXIT_CNT == exit_cnt) { time_2 = get_cur_timestamp();//计数达到设定值后,获取当前值 exit_cnt = 0; T = (time_2 - time_1)*1.0/EXIT_CNT; //前后获取的值做差值,算出一个时钟周期时间 Fre = 1/T * 1000*1000; //换算出频率 exit_flg = 1; } }
主函数:
int main(void)
{
gpio_config();
Debug_USART_Config(); timestamp_on(); //开启定时器 EXTI_Config(); NVIC_Config(); while(1) { if(1 == exit_flg) { exit_flg = 0; printf("------------------------------------------\r\n"); printf("T = %lf(us)\r\n", T); printf("Fre = %lf(Hz)\r\n", Fre); printf("------------------------------------------\r\n"); } Delay_ms(850); }
}
测试2M源时钟、4分频、8分频、16分频结果如下:
原文:https://www.cnblogs.com/wen2376/p/13346479.html