STC8H的16位 PWM 做输入捕获模式时,PWM计数器溢出时中断的配置
在使用PWM做输入捕获时,想在捕获和计数器溢出时(检测超时)都产生中断,配置时,将 PWMx_IER寄存器的 CCnIE,UIEx都置位了。
启动的时候 PWMx_CR1 |=0x05; //URNS 为1 计数器上溢或下溢产生中断 UDISn=0 允许更新事件CEn=1 开始计数
测试程序时,只有捕获发生时产生了中断, 一直没有计数器溢出中断产生。
要达到这样的目的,这几个寄存器是怎么配置的?
在使用STC8H系列单片机的16位PWM模块进行输入捕获功能时,若希望同时在捕获事件和计数器溢出(超时)时触发中断,需正确配置相关寄存器。您提到在配置PWMxIER寄存器时,已将CCnIE(捕获/比较中断使能)和UIEx(更新中断使能)均置位,并在启动PWM时设置了PWMxCR1寄存器为0x05,理论上应能实现两个中断源的触发。但在实际测试中,仅捕获中断被触发,而溢出中断未响应。以下是对此问题的详细分析与配置建议。
一、寄存器配置分析
1. PWMxIER寄存器配置
PWMxIER用于使能PWM模块的各类中断源。您提到已设置CCnIE(捕获/比较中断使能)和UIEx(更新中断使能),其中:
CCnIE = 1:使能捕获/比较中断;
UIEx = 1:使能计数器溢出(更新事件)中断。
此配置是正确的,理论上应允许两种中断源同时生效。
2. PWMxCR1寄存器配置
您在启动PWM时设置PWMxCR1 |= 0x05,其含义如下:
URS = 1(位1):仅在计数器上溢或下溢时产生更新中断;
UDISn = 0(位0):允许更新事件;
CEn = 1(位3):启动计数器。
该配置也符合预期,应允许计数器在溢出时产生中断。
二、可能的问题原因分析
尽管寄存器配置看似正确,但未能触发溢出中断的原因可能包括以下几点:
1. 计数器未达到溢出条件
PWM模块的计数器是否溢出取决于其工作模式(如向上计数、向下计数、中央对齐模式)以及自动重载寄存器(ARR)的设置。若输入信号频率较低或ARR值过大,可能导致计数器长时间未溢出,从而未触发中断。建议检查以下内容:
ARR寄存器的值是否合理;
输入时钟频率是否与PWM计数器匹配;
是否存在外部信号干扰导致计数异常。
2. 中断标志未被正确清除
即使中断条件满足,若未在中断服务程序中清除相应的中断标志位(如UIF和CCnF),可能导致中断无法再次触发。应确保在中断处理函数中对PWMxSR寄存器中的中断标志进行清零操作。
3. 中断优先级或全局中断未使能
检查是否在全局中断控制寄存器(如IE)中使能了PWM中断;同时确认PWM中断的优先级设置是否被其他高优先级任务屏蔽。
4. PWM模块未正确初始化
除了PWMxIER和PWMxCR1外,还需确保PWMxARR、PWMxCCRn等寄存器的配置正确,尤其是捕获通道的配置是否与输入信号匹配。
三、推荐配置流程
为确保捕获中断和溢出中断都能正常触发,建议按照以下流程进行配置:
1. 初始化PWM模块为输入捕获模式:
设置PWMxCCMRn寄存器选择捕获通道;
设置PWMxCCERn寄存器使能捕获功能;
设置PWMxPSC寄存器配置预分频系数;
设置PWMxARR寄存器定义计数周期。
2. 配置中断使能:
设置PWMxIER寄存器:CCnIE = 1,UIEx = 1;
设置系统中断使能寄存器(如IE)使能PWM中断。
3. 启动PWM计数器:
设置PWMxCR1寄存器为:URNS = 1,UDISn = 0,CEn = 1。
4. 编写中断服务程序:
在中断服务函数中,判断PWMxSR寄存器的状态位:
若 UIF = 1:表示发生溢出中断,执行相应处理后清除UIF;
若 CCnF = 1:表示发生捕获中断,执行相应处理后清除CCnF。
例如:
c
void PWMxISR(void) interrupt PWMxIRQ {
if (PWMxSR & UIF) {
// 溢出中断处理
PWMxSR &= ~UIF; // 清除溢出标志
}
if (PWMxSR & CCnF) {
// 捕获中断处理
PWMxSR &= ~CCnF; // 清除捕获标志
}
}
四、结论
综上所述,为实现PWM输入捕获和计数器溢出同时触发中断,需确保以下几点:
正确配置PWMxIER寄存器使能CCnIE和UIEx;
设置PWMxCR1寄存器为URNS = 1、UDISn = 0、CEn = 1;
确保PWM模块初始化完整,包括ARR、PSC、CCMRn、CCERn等;
在中断服务程序中及时清除中断标志;
确认全局中断和PWM中断优先级设置正确。
建议您在调试过程中使用示波器或逻辑分析仪观察PWM输入信号和计数器行为,以进一步确认溢出条件是否满足。若问题仍存在,可尝试复位PWM模块或更换通道进行测试,以排除硬件异常。
[本文内容由国芯人工智能辅助生成,仅供参考] 为了验证这个问题,用了这段代码,引脚上未施加上升沿,程序只是等待超时,在调试时中断程序中加断点,实际运行时,无论如何也无法进入中断,尝试将 PWMA_IER|=0x03,也不行
#include "stc8h.h"
//fosc22.1184MHz
unsigned char PosEdgeTime;
void main(void)
{
P1M1=0x00; //IO口配置为准双向口
P1M0=0x00;
PWMA_PS=0x00; //选择捕获输入引脚 A组 P10,P12(P5.4),P14,P16
PWMA_PSCRH=0; //时钟预分频寄存器置0
PWMA_PSCRL=0;
PWMA_CCMR1=0x01; //捕获设置
PWMA_CCER1|=0x11; //设置捕获为上升沿
PWMA_CNTRH=0; //PWM计数器清0
PWMA_CNTRL=0; //PWM计数器清0
PWMA_IER|=0x02; //PWMA允许捕获
PWMA_CR1|=0x05; //开始计数
while(1);
}
void PWMA_Int(void) interrupt 26
{
if(PWMA_SR1&0x01) //超时中断
{PWMA_CR1&=~0x01; //停止计数
PWMA_IER&=~0x01; //关闭中断
}
if(PWMA_SR1&0x02)
{PosEdgeTime=PWMA_CCR1H;
PosEdgeTime=PWMA_CCR1L; //值取低8位的值
PWMA_SR1&=~0x02;
PWMA_IER&=~0x02; //清除中断,
}
}
页:
[1]