找回密码
 立即注册
查看: 161|回复: 2

STC8H的16位 PWM 做输入捕获模式时,PWM计数器溢出时中断的配置

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-18 15:30:46
已绑定手机

3

主题

2

回帖

37

积分

新手上路

积分
37
发表于 2025-9-18 15:30:46 | 显示全部楼层 |阅读模式
在使用PWM做输入捕获时,想在捕获和计数器溢出时(检测超时)都产生中断,
配置时,将 PWMx_IER寄存器的 CCnIE,UIEx都置位了。
启动的时候   PWMx_CR1 |=0x05;   //URNS 为1 计数器上溢或下溢产生中断    UDISn=0 允许更新事件  CEn=1 开始计数

测试程序时,只有捕获发生时产生了中断, 一直没有计数器溢出中断产生。

要达到这样的目的,这几个寄存器是怎么配置的?
回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 2025-9-18 15:33:00 | 显示全部楼层
在使用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。

例如:
  1. c
  2. void PWMxISR(void) interrupt PWMxIRQ {
  3.     if (PWMxSR & UIF) {
  4.         // 溢出中断处理
  5.         PWMxSR &= ~UIF; // 清除溢出标志
  6.     }
  7.     if (PWMxSR & CCnF) {
  8.         // 捕获中断处理
  9.         PWMxSR &= ~CCnF; // 清除捕获标志
  10.     }
  11. }
复制代码

四、结论

综上所述,为实现PWM输入捕获和计数器溢出同时触发中断,需确保以下几点:
正确配置PWMxIER寄存器使能CCnIE和UIEx;
设置PWMxCR1寄存器为URNS = 1、UDISn = 0、CEn = 1;
确保PWM模块初始化完整,包括ARR、PSC、CCMRn、CCERn等;
在中断服务程序中及时清除中断标志;
确认全局中断和PWM中断优先级设置正确。

建议您在调试过程中使用示波器或逻辑分析仪观察PWM输入信号和计数器行为,以进一步确认溢出条件是否满足。若问题仍存在,可尝试复位PWM模块或更换通道进行测试,以排除硬件异常。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-18 15:30:46
已绑定手机

3

主题

2

回帖

37

积分

新手上路

积分
37
发表于 2025-9-18 16:41:42 | 显示全部楼层
为了验证这个问题,用了这段代码,引脚上未施加上升沿,程序只是等待超时,在调试时中断程序中加断点,实际运行时,无论如何也无法进入中断,尝试将 PWMA_IER|=0x03,也不行
#include "stc8h.h"
//fosc  22.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;                //清除中断,
         }
}
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-16 10:29 , Processed in 0.107114 second(s), 54 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表