完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大家好!
最近开始接触STM32F103ZE开发板,计划利用IO口外部中断的方法计算PWM波形的占空比和频率。出现了一些问题,还请大神们指点一二,万分感激!!!! EXti初始化设置如下: EXTI_InitTypeDef EXTI_InitStructure; void EXTI1_Config_Rising(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // Ecirc; sup1; Auml; Uuml; cedil; acute; Oacute; Atilde; sup1; brvbar; Auml; Uuml; Ecirc;± Ouml; Oacute; GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource1); EXTI_InitStructure.EXTI_Line=EXTI_Line1;//PC1,EXTI1 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; #if 1 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//双边沿触发 #else EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发 #endif EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init( EXTI_InitStructure); 首先,采用双边沿触发,进入中断之后判断引脚电平从而再次确定是哪种边沿触发。代码如下,但是一旦PWM波形的频率和占空比较低的话,此方法完全无效。 TIMER_CNT Count[2]={0};//Count[0] is sample value, Count[1] is return value. u16 TITimer=0; void EXTI1_IRQHandler(void) { //using EXTI_Trigger_Rising_Falling as EXTI source. if (EXTI_GetITStatus(EXTI_Line1) != RESET) { if (PCin(PWM_PIN))//rising edge { TITimer++; if(TITimer==1)//with interrupt { TIM_SetCounter(TIM2,0);//set count=0, and start count timer. } else if(TITimer==3) { Count[0].Cnt[1]=TIM_GetCounter(TIM2);//周期时间 Count[1]=Count[0]; TITimer=0; } } else //falling edge { if(TITimer==2) { Count[0].Cnt[0]=TIM_GetCounter(TIM2);//高电平持续时间 } } EXTI_ClearITPendingBit(EXTI_Line1); } //占空比=Count[0].Cnt[0]/Count[0].Cnt[1] 如果采用单边沿触发的方法,在中断处理函数里面转换触发边沿,断点测试出来是触发边沿转换无效,所以,测得的周期是实际的2倍,也不能检测到另一种边沿。下面代码: TIMER_CNT Count[2]={0};//Count[0] is sample value, Count[1] is return value. u8 EXTI1_STA = 0; void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line1) != RESET) { if(EXTI1_STA == 0)//1st risng edge interrupt { TIM_SetCounter(TIM2,0); EXTI1_STA =0x40; EXTI1_Config_Falling(); } else if(EXTI1_STA 0x40) //2ed falling edge,无法进入!!!!!! { Count[0].Cnt[0]=TIM_GetCounter(TIM2); EXTI1_STA =0x80; EXTI1_Config_Rising(); } else if(EXTI1_STA 0xC0)//3rd rising edge { Count[0].Cnt[1]=TIM_GetCounter(TIM2); Count[1]=Count[0]; EXTI1_STA=0; } //EXTI_Init( EXTI_InitStructure); EXTI_ClearITPendingBit(EXTI_Line1); } |
|
相关推荐
1个回答
|
|
首先,您已经正确地进行了EXTI初始化设置。接下来,您需要配置外部中断的优先级、嵌套向量和中断服务例程。以下是一些建议:
1. 配置NVIC(嵌套向量中断控制器)以设置中断优先级和嵌套向量: ```c NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; // 选择EXTI1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 中断优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 中断子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断 NVIC_Init(&NVIC_InitStructure); ``` 2. 在您的中断服务例程中,编写代码以计算PWM波形的占空比和频率。您需要定义两个全局变量来存储PWM的周期和占空比: ```c volatile uint32_t pwm_period = 0; volatile uint32_t pwm_duty_cycle = 0; ``` 3. 在EXTI1中断服务例程中,编写代码以更新这些变量。例如,您可以使用定时器中断来测量PWM波形的周期和高电平持续时间: ```c void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line1) != RESET) { EXTI_ClearITPendingBit(EXTI_Line1); // 检查上升沿还是下降沿 if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1) == Bit_SET) { // 记录上升沿的时间戳 uint32_t timestamp = ...; // 获取当前时间戳 pwm_period = timestamp - pwm_duty_cycle; pwm_duty_cycle = timestamp; } else { // 记录下降沿的时间戳 uint32_t timestamp = ...; // 获取当前时间戳 pwm_duty_cycle = timestamp; } } } ``` 4. 根据测量到的周期和占空比,计算PWM波形的频率和占空比: ```c float pwm_frequency = 1.0 / pwm_period; float pwm_duty_cycle_percentage = (pwm_duty_cycle / pwm_period) * 100.0; ``` |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1658 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1568 浏览 1 评论
996 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
695 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1616 浏览 2 评论
1876浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
660浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
528浏览 3评论
547浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
517浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 20:41 , Processed in 0.830418 second(s), Total 80, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号