用STC单片机的PCA做定时器,输出PWM

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用STC单片机的PCA做定时器,输出PWM相关的知识,希望对你有一定的参考价值。

下面程序代码是用定时器0输出PWM,用来调LED灯光。但是我项目中的所有定时器已做其它用途,请问:怎样用PCA做个定时器,代替程序中定时器0?
/****************************************************
8个按键决定8个亮度
****************************************************/
#include<reg51.h>
#define uIntunsigned int
#define ucharunsigned char
sfr AUXR = 0x8E;
uchar PWM_T =0; //占空比控制变量
sbit c7=P3^7; //8个按键,决定输出PWM_T值
sbit c6=P3^6;
sbit c5=P3^5;
sbit c4=P3^4;
sbit c3=P3^3;
sbit c2=P3^2;
sbit c1=P3^1;
sbit c0=P3^0;
sbitBLED=P1^0; //设定从P1^0口输出PWM,用来控制三极管调光
/****************************************************
主程序
****************************************************/
voidmain(void)

AUXR |= (1<<7); // Timer0取_1T
TMOD=0x02; //定时器0,工作模式2,8位定时模式
TH0=210; //写入预置初值(
TL0=210; //写入预置值
TR0=1; //启动定时器
ET0=1; //允许定时器0中断
EA=1; //允许总中断
BLED=1; //初始化P1^0,输出端口

while(1) //PWM周期100,高电平100-PWM_T,低电平PWM_T,低电平工作

if(c7==0) PWM_T=0; //最亮 
else if(c6==0) PWM_T=10;
else if(c5==0) PWM_T=25;
else if(c4==0) PWM_T=40;
else if(c3==0) PWM_T=55;
else if(c2==0) PWM_T=70;
else if(c1==0) PWM_T=85; //
else if(c0==0) PWM_T=100; //最暗


/****************************************************
/定时器0中断模拟PWM
****************************************************/
timer0() interrupt1 using 2

static uchar t ; //PWM计数
t++; //每次定时器溢出加1
if(t==100) //PWM周期 100个单位

t=0; //使t=0,开始新的PWM周期
BLED=0; //使LED灯亮 ,输出端口


if(PWM_T==t) //按照当前占空比切换输出为高电平
BLED=1; //使LED灯灭

既然你选择的STC单片机带PCA,为什么不直接利用PCA模块配置成PWM功能,说一下具体型号,给你段利用PWM产生固定频率方波的代码参考。
//****************pwm.h********************************
#define Start_PWM() CR = 1 //PCA计时器开始工作
#define Stop_PWM() CR = 0 //PCA计时器停止工作

extern void InitPWM();
extern void ChangePWM(uint16 f);

//****************pwm.C********************************
#include "pwm.h"
#include "stc15F2k60s2.h"

#define CCP_S0 0x10 //P_SW1.4
#define CCP_S1 0x20 //P_SW1.5

static uint16 data frequency;
static uint16 data value;

void PCAisr() interrupt 7

CCF1 = 0; //清中断标志
CCAP1L = value;
CCAP1H = value >> 8; //更新比较值
value += frequency; //累加


void SetPWMFrenquency(uint16 frq)

frequency=frq;
value = frequency;
CCAP1L = value; //将值得低8位赋给CCAP1L
CCAP1H = value >> 8; //高8位赋给CCAP1H
value += frequency; //累加,为下一次赋值做好准备。产生同固定频率的方波就靠它了。


//p2.6/CCP1_3
void InitPWM()

ACC = P_SW1;

ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=0 CCP_S1=1
ACC |= CCP_S1; //(P2.4/ECI_3, P2.5/CCP0_3, P2.6/CCP1_3, P2.7/CCP2_3)
P_SW1 = ACC;

CCON = 0; //初始化PCA控制寄存器
//PCA定时器停止
//清除CF标志
//清除模块中断标志

CL = CH = 0; //复位PCA计数寄存器

CMOD = 0x08; //设置PCA时钟源为sysclock,禁止PCA计数器溢出中断
CCAPM1 = 0x4d; //0100 1101 //PCA模块1为16位定时器模式,同时反转(P2.6)口
PPCA = 1; //中断优先级

SetPWMFrenquency(12000); //frq=24000000/2/1000=12000,每秒钟1000hz


void ChangePWM(uint16 frq)

Stop_PWM(); //停止PCA计时器

CL=CH=0; //PCA计数器清零
CCF1=0; //PCA1的中断标记清零
SetPWMFrenquency(frq);

Start_PWM();
追问

我用的型号是STC15W408AS, 没有P2.6口,现在只有P1.0口可用了。试用过STC自带的PCA,但是PWM在P3口输出,且占空比不好控制。

参考技术A CMOD = 0X00 ;PCA空闲时运行,时钟fosc/12,屏蔽溢出中断
CCON = 0x40 ;PCA计数器启动,清零各个中断请求标志位
CCAPM0 = 0x49 ;PCA模块0设置为软件定时器比较捕捉功能
EPCALVD = 1 ;PCA比较中断允许

//PCA模块中断服务程序(输出控制)
if(CCF0 = 1)

CCF0 = 0x00;//PCA模块0中断标志,由硬件置位,必须由软件清0
CCON = 0x40;//PCA计数器允许计数,清0各个中断请求标志位
XHOUT = !XHOUT;//自定义的输出高低电平标志
if (XHOUT==1)

PWMout = 1;//置位PWM输出管脚
CCAP0L = CCAP0L + MC1L;//脉冲1低位
CCAP0H = CCAP0H + MC1H;//脉冲1高位

else

PWMout = 0;//复位PWM输出管脚
CCAP0L = CCAP0L + MC0L;//脉冲0低位
CCAP0H = CCAP0H + MC0H;//脉冲0高位



你看哪个简单。
参考技术B 放入忒让人发货人投入费用投入

STC15系列CCP/PWM/PCA介绍

STC15系列CCP/PWM/PCA介绍


  • CCP:是英文单词的缩写Capture(捕获),Compare(比较),PWM(脉宽调制)

STC15系列部分单片机集成了3路可编程计数器阵列(CCP/PCA)模块,可用于软件定时器外部脉冲的捕捉高速脉冲输出以及脉宽调制(PWM)输出


与CCP/PWM/PCA应用有关的特殊功能寄存器

  • STC15系列 1T 8051单片机 CCP/PCA/PWM特殊功能寄存器表

PCA控制寄存器:CCON

  • PCA控制寄存器
  • CF:PCA计数器阵列溢出标志位。当PCA计数器溢出时 CF由硬件置位。如果CMOD寄存器
    的ECF位置位, CF标志可用来产生中断。CF位可通过硬件或软件置位, 但只可通过软件清零。
  • CR:PCA计数器阵列 位通过软件置位, 用来起动PCA计数器阵列计数。该位通过软件清零, 用来关闭PCA计数器。
  • CCF2:PCA模块2中断标志。当出现匹配或捕获时该位由硬件置位。该位必须通过软件清零。
  • CCF1:PCA模块1中断标志。当出现匹配或捕获时该位由硬件置位。该位必须通过软件清零。
  • CCF0:PCA模块0中断标志。当出现匹配或捕获时该位由硬件置位。该位必须通过软件清零。

PCA工作模式寄存器:CMOD

  • PCA工作模式寄存器(PCA时钟源设置寄存器)
  • CIDL:空闲模式下是否停止PCA计数的控制位。

当CIDL=0时, 空闲模式下PCA计数器继续工作
当CIDL=1时,空闲模式下 PCA计数器停止工作。

  • CPS2、CPS1、CPS0:PCA计数脉冲源选择控制位。PCA计数脉冲选择如下表所示。
  • 例如,CPS2/CPS1/CPS0 = 1/0/0时,CCP/PCA/PWM的时钟源是SYSclk,不用定时器0,PWM的频率为SYSclk/256.
  • 如果要用系统时钟/3来作为PCA的时钟源,应选择TO的溢出作为CCP/PCA/PWM的时钟源,此时应让T0工作在1T模式,计数3个脉冲即产生溢出。用TO的溢出可对系统时钟进行1~65536级分频(T0工作在16位重装载模式)。
  • ECF:PCA计数溢出中断使能 。

当ECF = 0时,禁止寄存器CCON中CF位的中断;
当ECF = 1时,允许寄存器CCON中CF位的中断.

3.PCA比较/捕获寄存器CCAPM0、CCAPM1和CCAPM2

  • B7:保留为将来之用。
  • ECOM0:允许比较器功能控制位
    当ECOM0=1时,允许
  • CAPP0: 正捕获控制位
    当CAPP0=1时,允许
  • CAPN0:负捕获控制位
    当CAPN0=1时 下降
  • MAT0: 匹配控制位
    当MAT0=1时,PCA计数值与模块的比较/捕获寄存器的值的匹配将置位CCON寄存器的中断标志位CCF0。
  • TOG0: 翻转控制位
    当TOG0=1时,工作在PCA高速脉冲输出 PCA计数器的值与模块的比较/捕获
    寄存器的值的匹配将使CCP0脚翻转。
    (CCP0/PCA0/PWM0/P1.1或CCP0_2/PCA0/PWM0/P3.5或CCP0_3/PCA0/PWM0/P2.5)
  • PWM0: 脉宽调节模式。
    当PWM0=1时, CCP0脚用作脉宽调节输出。
    (CCP0/PCA0/PWM0/P1.1或CCP0_2/PCA0/PWM0/P3.5或CCP0_3/PCA0/PWM0/P2.5)
    ECCF0: 使能CCF0中断。使能寄存器CCON的比较/捕获标志CCF0, 用来产生中断。

还有 CCAPM1 ,CCAPM2与上面的CCAPM0差不多

4. PCA的16位计数器 — 低8位CL和高8位CH

  • CL和CH地址分别为E9H和F9H,复位值均为00H,用于保存PCA的装载值。

5. PCA捕捉/比较寄存器 — CCAPnL(低位字节)和CCAPnH(高位字节)

当PCA模块用于捕获或比较时,它们用于保存各个模块的16位捕捉计数值;当PCA模块用
于PWM模式时,它们用来控制输出的占空比。其中,n=0、1、2,分别对应模块0、模块1和模
块2。复位值均为00H。它们对应的地址分别为:

CCAP0L — EAH、CCAP0H — FAH:模块0的捕捉/比较寄存器。
CCAP1L — EBH、CCAP1H — FBH:模块1的捕捉/比较寄存器。
CCAP2L — ECH、CCAP2H — FCH:模块2的捕捉/比较寄存器。

6. PCA模块PWM寄存器PCA_PWM0、PCA_PWM1和PCA_PWM2


  • EPC0H:在PWM模式下,与CCAP0H组成9位数。
  • EPC0L:在PWM模式下,与CCAP0L组成9位数。

PCA模块的工作模式设定表如下表所列:

将单片机的CCP/PWM/PCA功能在3组管脚之间切换的寄存器AUXR1(P_SW1)

  • 辅助寄存器1的格式



CCP/PWM/PCA模块的结构

  • STC15系列部分单片机有3路可编程计数器阵列CCP/PCA/PWM(通过AUXR1/P_SW1寄存器可以设置CCP/PCA/PWM从P1口切换到P2口切换到P3口)。
  • PCA含有一个特殊的16位定时器,有3个16位的捕获/比较模块与之相连 ,如下图所示。
  • 每个模块可编程工作在4种模式下:上升/下降沿捕获、软件定时器,高速脉冲输出或可调制脉冲输出。

  • 寄存器CH和CL的内容是正在自由递增计数的16位PCA定时器的值。PCA定时器是3个模块的公共时间基准,可通过编程工作在:1/12系统时钟、1/8系统时钟、1/6系统时钟、1/4系统时钟、1/2系统时钟、系统时钟、定时器0溢出或ECI脚的输入(STC15W4K60S4系列在P1.2或P2.4或P3.4口)。定时器的计数源由CMOD特殊功能寄存器中的CPS2,CPS1和CPS0位来确定(见CMOD特殊功能寄存器说明)。
  • CMOD特殊功能寄存器还有2个位与PCA相关。它们分别是:CIDL,空闲模式下允许停止PCA;ECF,置位时,使能PCA中断,当PCA定时器溢出将PCA计数溢出标志CF(CC0ON.7)置位。
  • CCON特殊功能寄存器包含PCA的运行控制位(CR)和PCA定时器标志(CF)以及各个模块的标志(CCF2/CCF1/CCFO)。通过软件置位CR位(CCON.6)来运行PCA。CR位被清零时PCA关闭。
  • 当PCA计数器溢出时,CF位(CCON.7)置位,如果CMOD寄存器的ECF位置位,就产生中断。CF位只可通过软件清除。CCON寄存器的位0~2是PCA各个模块的标志(位0对应模块0,位1对应模块1,位2对应模块2),当发生匹配或比较时由硬件置位。这些标志也只能通过软件清除。所有模块共用一个中断向量。PCA的中断系统如图所示。
  • PCA的每个模块都对应一个特殊功能寄存器。它们分别是:模块0对应CCAPMO,模块1对应CCAPM1,模块2对应CCAPM2,特殊功能寄存器包含了相应模块的工作模式控制位。
  • 当模块发生匹配或比较时,ECCFn位(CCAPMn.0,n=0,1,2由工作的模块决定)使能CCON特殊功能寄存器的CCFn标志来产生中断。
  • PWM(CCAPMn.1)用来使能脉宽调制模式。
  • 当PCA计数值与模块的捕获/比较寄存器的值相匹配时,如果T0G位(CCAPMn.2)置位,模块的CCPn输出将发生翻转。
  • 当PCA计数值与模块的捕获/比较寄存器的值相匹配时,如果匹配位MATn(CCAPlMn.3)置位,CCON寄存器的CCFn位将被置位。
  • CAPNn(CCAPMn.4)和CAPPn(CCAPMn.5)用来设置捕获输入的有效沿。CAPNn位使能下降沿有效,CAPPn位使能上升沿有效。如果两位都置位,则两种跳变沿都被使能,捕获可在两种跳变沿产生。
  • 通过置位CCAPMn寄存器的ECOMn位(CCAPMn.6)来使能比较器功能。
  • 每个PCA模块还对应另外两个寄存器,CCAPnH和CCAPnL。当出现捕获或比较时,它们用来保存16位的计数值。当PCA模块用在PWM模式中时,它们用来控制输出的占空比。

CCP/PCA模块的工作模式

捕获模式

PCA模块工作于捕获模式的结构图如下图所示。要使一个PCA模块工作在捕获模式,寄存器CCAPMn的两位(CAPNn和CAPPn)或其中任何一位必须置1。PCA模块工作于捕获模式时,对模块的外部CCPn输入(CCPO/P1.1,CCP1/P1.0,CCP2/P3.7)的跳变进行采样。当采样到有效跳变时,PCA硬件就将PCA计数器阵列寄存器(CH和CL)的值装载到模块的捕获寄存器中(CCAPnL和CCAPnH)。

如果CCON特殊功能寄存器中的位CCFn和CCAPMn特殊功能寄存器中的位ECCFn位被置位,将产生中断。可在中断服务程序中判断哪一个模块产生了中断,并注意中断标志位的软件清零问题。

16位软件定时器模式

通过置位CCAPMn寄存器的ECOM和MAT位,可使PCA模块用作软件定时器(上图)。PCA定时器的值与模块捕获寄存器的值相比较,当两者相等时,如果位CCFn(在CCON特殊功能寄存器中)和位ECCFn(在CCAPMn特殊功能寄存器中)都置位,将产生中断。
[CH,CL]每隔一定的时间自动加1,时间间隔取决于选择的时钟源。例如,当选择的时
钟源为SYSclk/12,每12个时钟周期[CH,CL]加1。当[CH,CL]增加到等于[CCAPnH, CCAPnL]
时,CCFn=1,产生中断请求。如果每次PCA模块中断后,在中断服务程序中断给[CCAPnH,
CCAPnL]增加一个相同的数值,那么下次中断来临的间隔时间T也是相同的,从而实现了定时
功能。定时时间的长短取决于时钟源的选择以及PCA计数器计数值的设置。下面举例说明PCA
计数器计数值的计算方法。
假设,系统时钟频率SYSclk = 18.432MHz,选择的时钟源为SYSclk/12,定时时间T为5ms,则
PCA计数器计数值为:
PCA计数器的计数值 = T / (( 1 / SYSclk )×12 ) = 0.005 / (( 1 / 18432000)×12 ) = 7680 (10进制数)
= 1E00H (16进制数)
也就是说,PCA计数器计数1E00H次,定时时间才是5ms,这也就是每次给[CCAPnH,
CCAPnL]增加的数值(步长)。

高速脉冲输出模式

该模式中(下图),当PCA计数器的计数值与模块捕获寄存器的值相匹配时,PCA模块的CCPn输出将发生翻转。要激活高速脉冲输出模式,CCAPMn寄存器的TOGn,MATn和ECOMn位必须都置位。

CCAPnL的值决定了PCA模块n的输出脉冲频率。当PCA时钟源是SYSclk/2时,输出脉冲的
频率F为:
f = SYSclk / ( 4×CCAPnL )
其中,SYSclk为系统时钟频率。由此,可以得到CCAPnL的值CCAPnL = SYSclk / ( 4×f ).
如果计算出的结果不是整数,则进行四舍五入取整,即
CCAPnL = INT (SYSclk / ( 4×f ) + 0.5 )
其中,INT( )为取整运算,直接去掉小数。例如,假设SYSclk = 20MHz,要求PCA高速脉
冲输出125kHz的方波,则CCAPnL中的值应为:
CCAPnL = INT (20000000 / ( 4×125000 ) + 0.5 ) = INT ( 40 + 0.5 ) = 40 = 28H

脉宽调节模式(PWM)

  • 脉宽调制(PWM,Pulse Width Modulation)是一种使用程序来控制波形占空比、周期、相位
    波形的技术,在三相电机驱动、D/A转换等场合有广泛的应用。

STC15系列单片机的PCA模块可以通过设定各自的寄存器PCA_PWMn (n=0,1,2.下同)中的位EBSn_1/PCA_PWMn.7及EBSn_0/PCA_PWMn.6,使其工作于8位PWM或7位PWM或6位PWM模式。

  • 8位脉宽调节模式(PWM)

当[EBSn_1,EBSn_0]=[0,0]或[1,1]时,PCA模块n工作于8位PWM模式,此时将0,CL[7:0]与捕获寄存器[EPCnL,CCAPnL[7:0]]进行比较。PWM模式的结构如下图所示。

  • 当PCA模块工作于8位PWM模式时,由于所有模块共用仅有的PCA定时器,所有它们的输出频率相同。各个模块的输出占空比是独立变化的,与使用的捕获寄存器EPCnL,CCAPnL[7:0]有关。当0,CL[7:0]的值小于EPCnL,CCAPnL[7:0]时,输出为低; 0,CL[7:0]的值等于或大于EPCnL,CCAPnL[7:0]时,输出为高。当CL的值由FF变为00溢出时,EPCnH,CCAPnH[7:0]的内容装载到EPCnL,CCAPnL[7:0]中。这样就可实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。
  • 当PWM是8位的时:

PCA时钟输入源可以从以下8种中选择一种:SYSclk, SYSclk/2, SYSclk/4,SYSclk/6,
SYSclk/8,SYSclk/12,定时器0的溢出,ECI/P1.2输入
举例: PCA模块工作于8位PWM模式。 PWM输出频率为38KHz,选SYSclk为PCA/
PWM时钟输入源,求出SYSclk的值
由计算公式38000=SYSclk/256 ,得到外部时钟频率SYSclk=38000 x 256 x 1=9,728,000
如果要实现可调频率的PWM输出,可选择定时器0的溢出率或者ECI脚的输入作为PCA/PWM
的时钟输入源。

  • 当EPCnL = 0及CCAPnL = 00H时,PWM固定输出高

  • 当EPCnL = 1及CCAPnL = FFH时,PWM固定输出低

  • 当某个I/O口作为PWM使用时,该口的状态:

  • 7位脉宽调节模式(PWM)

当[EBSn_1,EBSn_0]=[0,1]时,PCA模块n工作于7位PWM模式,此时将0,CL[6:0]与捕获寄存器[EPCnL,CCAPnL[6:0]]进行比较。PWM模式的结构如下图所示。

当PCA模块工作于7位PWM模式时,由于所有模块共用仅有的PCA定时器,所有它们的输出频率相同。各个模块的输出占空比是独立变化的,与使用的捕获寄存器EPCnL,CCAPnL[6:0]有关。当0,CL[6:0]的值小于EPCnL,CCAPnL[6:0]时,输出为低; 0,CL[6:0]的值等于或大于EPCnL,CCAPnL[6:0]时,输出为高。当CL的值由7F变为00溢出时,
EPCnH,CCAPnH[6:0]的内容装载到EPCnL,CCAPnL[6:0]中。这样就可实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。

  • 当PWM是7位的时:

PCA时钟输入源可以从以下8种中选择一种:SYSclk, SYSclk/2, SYSclk/4,SYSclk/6,
SYSclk/8,SYSclk/12,定时器0的溢出,ECI/P1.2输入。
举例:设PCA模块工作于7位PWM模式。要求PWM输出频率为38KHz,选SYSclk为PCA/
PWM时钟输入源,求出SYSclk的值。
由计算公式38000=SYSclk/128,得到外部时钟频率SYSclk=38000×128×1=4,864,000如果要实现可调频率的PWM输出,可选择定时器0的溢出率或者ECI脚的输入作为PCA/PWM的时钟输入源
当EPCnL=0及CCAPnL=80H时,PWM固定输出高当EPCnL=1及CCAPnL=OFFH时,PWM固定输出低

  • 6位脉宽调节模式(PWM)

当[EBSn_1,EBSn_0]=[1,0]时,PCA模块n工作于6位PWM模式,此时将0,CL[5:0]与捕获寄存器[EPCnL,CCAPnL[5:0]]进行比较。PWM模式的结构如下图所示。

当PCA模块工作于6位PWM模式时,由于所有模块共用仅有的PCA定时器,所有它们的输出频率相同。各个模块的输出占空比是独立变化的,与使用的捕获寄存器EPCnL,CCAPnL[5:0]有关。当0,CL[5:0]的值小于EPCnL,CCAPnL[5:0]时,输出为低; 0,CL[5:0]的值等于或大于EPCnL,CCAPnL[5:0]时,输出为高。当CL的值由3F变为00溢出时,
EPCnH,CCAPnH[5:0]的内容装载到EPCnL,CCAPnL[5:0]中。这样就可实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。

  • 当PWM是6位的时:
  • PCA时钟输入源可以从以下8种中选择一种:SYSclk,SYSclk/2,SYSclk/4,SYSclk/6,SYSclk/8,SYSclk/12,定时器0的溢出,ECI/P1.2输入。

举例:设PCA模块工作于6位PWM模式。要求PWM输出频率为38KHz,选SYSclk为PCA/PWM时钟输入源,求出SYSclk的值。
由计算公式38000=SYSclk/64,得到外部时钟频率SYSclk=38000×64x1=2,432,000如果要实现可调频率的PWM输出,可选择定时器0的溢出率或者ECI脚的输入作为PCA/PWM的时钟输入源

  • 当EPCnL=0及CCAPnL=0C0H时,PWM固定输出高当EPCnL=1及CCAPnL=0FFH时,PWM固定输出低。

示例程序

用CCP/PCA功能扩展外部中断的测试程序

//假定测试芯片的工作频率为18.432MHz
#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
sfr P_SW1 = 0xA2; //外设功能切换寄存器1
#define CCP_S0 0x10 //P_SW1.4
#define CCP_S1 0x20 //P_SW1.5
sfr CCON = 0xD8; //PCA控制寄存器
sbit CCF0 = CCON^0; //PCA模块0中断标志
sbit CCF1 = CCON^1; //PCA模块1中断标志
sbit CR = CCON^6; //PCA定时器运行控制位
sbit CF = CCON^7; //PCA定时器溢出标志
sfr CMOD = 0xD9; //PCA模式寄存器
sfr CL = 0xE9; //PCA定时器低字节
sfr CH = 0xF9; //PCA定时器高字节
sfr CCAPM0 = 0xDA; //PCA模块0模式寄存器
sfr CCAP0L = 0xEA; //PCA模块0捕获寄存器 LOW
sfr CCAP0H = 0xFA; //PCA模块0捕获寄存器 HIGH
sfr CCAPM1 = 0xDB; //PCA模块1模式寄存器
sfr CCAP1L = 0xEB; //PCA模块1捕获寄存器 LOW
sfr CCAP1H = 0xFB; //PCA模块1捕获寄存器 HIGH
sfr PCAPWM0 = 0xf2;
sfr PCAPWM1 = 0xf3;
sbit PCA_LED = P1^0; //PCA测试LED
void PCA_isr() interrupt 7 using 1

 CCF0 = 0; //清中断标志
 PCA_LED = !PCA_LED; //测试LED取反

void main()

 ACC = P_SW1;
 ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=0 CCP_S1=0
 P_SW1 = ACC; //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)
 
// ACC = P_SW1;
// ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=1 CCP_S1=0
// ACC |= CCP_S0; //(P3.4/ECI_2, P3.5/CCP0_2, P3.6/CCP1_2, P3.7/CCP2_2)
// P_SW1 = ACC; 
// ACC = P_SW1;
// ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=0 CCP_S1=1
// ACC |= CCP_S1; //(P2.4/ECI_3, P2.5/CCP0_3, P2.6/CCP1_3, P2.7/CCP2_3)
// P_SW1 = ACC; 
CCON = 0; //初始化PCA控制寄存器
 //PCA定时器停止
 //清除CF标志
 //清除模块中断标志
 CL = 0; //复位PCA寄存器
 CH = 0;
 CMOD = 0x00; //设置PCA时钟源
 //禁止PCA定时器溢出中断
 CCAPM0 = 0x11; //PCA模块0为下降沿触发
// CCAPM0 = 0x21; //PCA模块0为上升沿沿触发
// CCAPM0 = 0x31; //PCA模块0为上升沿/下降沿触发
 CR = 1; //PCA定时器开始工作
 EA = 1;
 while (1);

以上是关于用STC单片机的PCA做定时器,输出PWM的主要内容,如果未能解决你的问题,请参考以下文章

STC15系列CCP/PWM/PCA介绍

11.STC15W408AS单片机CCP/PCA/PWM应用

11.STC15W408AS单片机CCP/PCA/PWM应用

11.STC15W408AS单片机CCP/PCA/PWM应用

11.STC15W408AS单片机CCP/PCA/PWM应用

STC12C系列单片机PWM脉宽调制