中颖51芯片学习4. 可编程计数器阵列PCA0
- 一、PCA介绍
- 1. PCA简介
- 2. SH79F9476的PCA0特性
- 3. PCA0 功能
- 4. 时钟
- 5. PCA0原理框图
- 6. 工作方式
- 二、PCA0寄存器
- 1. PCA0标志寄存器
- 2. PCA使能寄存器
- 3. PCA0方式寄存器
- 4. P0CPMn PCA捕捉/比较寄存器
- 5. P0FORCE强制输出控制寄存器
- 6. PCA0计数最大值低字节
- 7. PCA0计数最大值高字节
- 8. PCA0比较/捕捉模块低字节
- 9. PCA0比较/捕捉模块高字节
- 三、中断
- 四、工作方式详解
- 1. Mode0 边沿触发的捕捉模式
- (1)工作方式介绍
- (2)代码实现
- 2. Mode1 软件定时器方式
- (1)工作方式简介
- (2)代码实现
- 3. Mode2 频率输出方式
- (1)工作方式简介
- (2)代码实现
- 4. Mode3 PWM模式
- (1)工作方式简介
- 功能配置
- 溢出与自动重载
- 占空比
- 工作方式原理框图
- (2)8位脉宽PWM代码实现
- (3)16 位脉宽调制器(PWM16 )实现
- (4) 16位相位修正脉宽XPWM16
- (5) 16 位相频修正 XPPWM16 方式
一、PCA介绍
1. PCA简介
PCA(Programmable Counter Array)是一种可编程计数器阵列,是常见于一些8位和16位微控制器中的重要外设之一,包括中颖C51单片机。
PCA0的功能包括计时器和捕获/比较功能,它能够执行多种定时和控制任务。
-
计时器功能: PCA可以作为一个多功能的定时器,能够产生精确的定时脉冲,用于计时、延时等应用。它可以以不同的时钟源(如系统时钟、外部时钟等)来进行计数,并且支持不同的计数模式(例如定时器、捕获/比较等)。
-
捕获/比较功能: PCA还可以用作捕获/比较器,能够捕获外部输入信号的脉冲宽度、频率等信息,并与预设的比较值进行比较,从而实现对输入信号的精确控制。
-
多通道功能: PCA通常具有多个计时通道,可以同时管理多个计时任务,这使得它在复杂的控制系统中非常有用。
-
中断支持: PCA通常会提供中断功能,当计数或捕获操作完成时,可以触发相应的中断,用于处理特定的事件或执行特定的任务。
-
PWM输出: PCA通常也可以用来生成PWM(脉冲宽度调制)信号,用于控制电机速度、LED亮度等应用。
2. SH79F9476的PCA0特性
- SH79F9476有1个16位定时器PCA0,PCA0具有两路独立比较捕捉模块
- 可以实现相位修正,相频修正
与标准的8051计数器/定时器相比,PCA0需要较少的CPU干预 。
3. PCA0 功能
- 1个专用的16位计数器/定时器
- 2个16位捕捉/比较模块
每个捕捉/比较模块有自己的I/O线(P0CEX0,P0CEX1)。
4. 时钟
PCA0的计数器/定时器有一个可编程选择时钟源:系统时钟、系统时钟/4、系统时钟/12、系统时钟/32、定时器4溢出或ECI0 输入引脚上的外部时钟信号、32.768KHz晶振/内建128kHzRC,通过P0CMD寄存器中的P0CPS2-P0CPS0位选择定时器/计数器的时钟源:
P0CPS2 | P0CPS1 | P0CPS0 | 时钟源 |
---|---|---|---|
0 | 0 | 0 | 系统时钟 |
0 | 0 | 1 | 系统时钟的4分频 |
0 | 1 | 0 | 系统时钟的12分频 |
0 | 1 | 1 | 系统时钟的32分频 |
1 | 0 | 0 | 定时器4溢出 |
1 | 0 | 1 | 保留 |
1 | 1 | 0 | ECI0下降沿 |
1 | 1 | 1 | 32.768Khz/内建128kHzRC |
按官方文档说明:
- 系统时钟频率不得低于计数时钟频率的4倍频(计数时钟为系统时钟时除外)。
- 当OP_OSC[3:0] = 1010(32.768kHz晶体谐振器作为振荡器1,24MHz内部RC作为振荡器2),外部32.768kHz晶振作为计数源时钟;当OP_OSC[3:0]=0011(内部128KHz RC振荡器作为振荡器1,24MHz内部RC作为振荡器2)时,内建的128kHz作为计数器源时钟。
5. PCA0原理框图
6. 工作方式
PCA0 可以工作在Mode0、Mode1、Mode2、Mode3等4种方式,其中Mode3可分成以下几种 PWM 方式:
- 8位PWM(单斜坡)
- 16位PWM(单斜坡)
- 16位相位修正PWM(双斜坡)
- 16位相频修正PWM(双斜坡)
二、PCA0寄存器
1. PCA0标志寄存器
98H,Bank1 | 第7位 | 第6位 | 第5位 | 第4位 | 第3位 | 第2位 | 第1位 | 第0位 |
---|---|---|---|---|---|---|---|---|
P0CF | CF0 | - | - | - | - | - | P0CCF1 | P0CCF0 |
读/写 | 读/写 | - | - | - | - | - | 读/写 | 读/写 |
复位值(POR/WDT/LVR/PIN) | 0 | - | - | - | - | - | 0 | - |
位编号说明:
位编号 | 位符号 | 说明 |
---|---|---|
7 | CF0 | PCA0计数器/定时器溢出标志 |
1 | P0CCF1 | PCA0模块1捕捉/比较标志 |
0 | P0CCF0 | PCA0模块0捕捉/比较标志 |
2. PCA使能寄存器
D8H,Bank1 | 第7位 | 第6位 | 第5位 | 第4位 | 第3位 | 第2位 | 第1位 | 第0位 |
---|---|---|---|---|---|---|---|---|
PCACON | - | - | - | - | - | - | - | PR0 |
读/写 | - | - | - | - | - | - | - | 读/写 |
复位值 | - | - | - | - | - | - | - | 0 |
PR0 位编号说明:
PCA0 计数器/ 定时器运行控制位:
- 0:禁止PCA0计数器/定时器
- 1:允许PCA0计数器/定时器
3. PCA0方式寄存器
99H,Bank1 | 第7位 | 第6位 | 第5位 | 第4位 | 第3位 | 第2位 | 第1位 | 第0位 |
---|---|---|---|---|---|---|---|---|
P0CMD | ECF0 | P0SDEN | - | - | - | P0CPS2 | P0CPS1 | P0CPS0 |
读/写 | 读/写 | 读/写 | - | - | - | 读/写 | 读/写 | 读/写 |
复位值 | 0 | 0 | - | - | - | 0 | 0 | 0 |
位编号说明:
位编号 | 位符号 | 说明 |
---|---|---|
7 | ECF0 | PCA0计数器/定时器溢出中断允许位 |
6 | P0SDEN | 单/双斜坡选择位 |
2 | P0CPS2 | PCA0计数器/定时器时钟选择 |
1 | P0CPS1 | PCA0计数器/定时器时钟选择 |
0 | P0CPS0 | PCA0计数器/定时器时钟选择 |
4. P0CPMn PCA捕捉/比较寄存器
9AH-9BH,Bank1 | 第7位 | 第6位 | 第5位 | 第4位 | 第3位 | 第2位 | 第1位 | 第0位 |
---|---|---|---|---|---|---|---|---|
P0CPM0 | P0SMP0 | P0SMN0 | P0FSP0 | P0FSN0 | P0ECOM0 | P0TCP0 | P0MAT0 | P0ECCF0 |
P0CPM1 | P0SMP1 | P0SMN1 | P0FSP1 | P0FSN1 | P0ECOM1 | P0TCP1 | P0MAT1 | P0ECCF1 |
读/写 | 读/写 | 读/写 | 读/写 | 读/写 | 读/写 | 读/写 | 读/写 | 读/写 |
复位值 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
位编号说明:
位编号 | 位符号 | 说明 |
---|---|---|
7 | P0SMPn | PCA0模式选择位 |
6 | P0SMNn | PCA0捕捉方式选择位 |
5 | P0FSPn | PCA0捕捉方式选择位 |
4 | PxECOMn | 比较/捕捉模块功能使能位 |
3 | P0TCPn | PCA0捕捉信号边沿指示位/波形输出控制位 |
2 | - | 此位在频率输出方式下无效 |
1 | P0MATn | 匹配标志控制位 |
0 | P0ECCFn | 捕捉/比较标志中断允许位 |
5. P0FORCE强制输出控制寄存器
DCH ,Bank1 | 第7位 | 第6位 | 第5位 | 第4位 | 第3位 | 第2位 | 第1位 | 第0位 |
---|---|---|---|---|---|---|---|---|
P0FORCE | - | - | P0OSC1 | P0OSC0 | - | - | P0FCO1 | P0FCO0 |
读写 | - | - | 读/写 | 读/写 | - | - | 读/写 | 读/写 |
复位值 | - | - | 0 | 0 | - | - | 0 | 0 |
位说明:
位编号 | 位符号 | 说明 |
---|---|---|
5 | P0OSC1 | 模块1引脚P0CEX1输出寄存器,该位只有当P0SMPn:P0SMNn=01且P0FSPn:P0FSNn=1x时有效 |
4 | P0OSC0 | 模块0引脚P0CEX0输出寄存器,该位只有当P0SMPn:P0SMNn=01且P0FSPn:P0FSNn=1x时有效 |
1 | P0FCO1 | 模块1强制匹配控制位(该位只有当P0SMPn:P0SMNn=01时有效) |
0 | P0FCO0 | 模块0强制匹配控制位(该位只有当P0SMPn:P0SMNn=01时有效) |
6. PCA0计数最大值低字节
P0TOPL, 9EH ,Bank1。
7. PCA0计数最大值高字节
P0TOPH, 9FH, Ban1。
8. PCA0比较/捕捉模块低字节
- P0CPL0 (9CH)
- P0CPL1 (ACH)
9. PCA0比较/捕捉模块高字节
- P0CPH0(9DH)
- P0CPH1(ADH)
三、中断
SH79F9476的PCA0中断号是20,
- 向量地址:00A3H;
- 允许位:EPCA0
- 标志位:CF0/P0CCF0/P0CCF1
示例:
void INT_PCA0(void) interrupt 20
{
}
四、工作方式详解
1. Mode0 边沿触发的捕捉模式
(1)工作方式介绍
在这种模式下,当P0CEXn引脚上的电平发生跳变时,PCA0计数器/定时器的当前计数值将被捕获并存储到对应模块的16位捕捉/比较寄存器(P0CPLn和P0CPHn)中。
要启用这种捕捉方式,需要配置P0SMPn寄存器的P0SMNn位和P0SMNn位为00。
可以通过PCA0CPMn寄存器中的P0FSPn和P0FSNn位选择触发捕捉的电平变化类型,用来选在低电平到高电平变化时触发(P0FSPn:P0FSNn = 00)、在高电平到低电平变化时触发(P0FSPn:P0FSNn = 10),或者在任何电平变化时触发(P0FSPn:P0FSNn = 11)。
当捕捉事件发生时,PCA0CF中的捕捉/比较标志(P0CCFn)会被置为逻辑‘1’,并产生一个中断请求(如果已允许中断)。当CPU进入中断服务程序时,P0CCFn位不会自动清零,需要通过软件来清除。如果P0FSPn和P0FSNn位都设置为逻辑‘1’,可以通过读取P0CPMn寄存器的P0TCPn位来确定本次捕捉是由上升沿触发还是由下降沿触发。
要注意: P0CEXn 输入信号必须在高电平或低电平期间至少保持四个系统时钟周期,以保证能够被硬件识别。
捕获原理框图:
(2)代码实现
下面代码配置PCA0工作方式0 , 在 P0CEX0(P1.2)输入1kHz信号,配置双边沿触发方式,在P1_0口输出方波。
#include "pca0_util.h"
/**
* @brief PCA0 工作方式0 边沿触发
*/
void PCA0Mode0(void){
select_bank1();
// 工作在单沿模式、禁止PCA0溢出中断、选择系统时钟作为PCA0时钟源
P0CMD=0x00;
// 捕捉方式、任意沿触发、打开捕捉/比较中断、使能比较/捕捉模块0
P0CPM0=0x39;
// 配置计数器最大值
P0TOPH=0x08;
P0TOPL=0x00;
// 启动PCA0计数器
PCACON=0x1;
select_bank0();
}
/**
* @brief PCA0中断
*/
void INT_PCA0(void) interrupt 20
{
_push_(INSCON);
Select_Bank1();
// 清除溢出标志
P0CF = 0x00;
Select_Bank0();
P1_0=~P1_0;
_pop_(INSCON);
}
P1_0 输出波形频率1kHz,如下图所示:
计数器值可以从P0CPLn、P0CPHn获取。
2. Mode1 软件定时器方式
(1)工作方式简介
在软件定时器方式下(也称为比较输出方式),可以实现连续的软件定时。在这种模式下,PCA0会将计数器/定时器的计数值与对应模块的16位捕捉/比较寄存器(P0CPHn和P0CPLn)进行比较。当计数值与比较寄存器中的值匹配时,PCA0CF中的捕捉/比较标志(P0CCFn)会被置为逻辑‘1’(如果P0MATn = 1),并且会产生一个中断请求(如果已经允许中断)。此外,与模块相关的P0CEXn引脚上的逻辑电平也会发生变化(通过简单设置P0TCPn来启用该功能)。
当CPU进入中断服务程序时,P0CCFn位不会自动清零,需要通过软件来清除。
原理框图:
(2)代码实现
下面代码实现连续软件定时,当PCA0计数值与P0CPH0和P0CPL0中的值匹配时产生一次中断,同时P0CEX0(P1.2) 口翻转一次。
/**
* @brief PCA0 工作方式1 软件定时器
*/
void PCA0Mode1(void){
select_bank1();
// 单沿模式、禁止PCA0溢出中断、选择系统时钟作为PCA0时钟源
P0CMD = 0x00;
// 连续软件定时方式、允许P0CEX0输出波形、打开捕捉/比较中断
P0CPM0 = 0x47;
// 配置PCA0 计数器最大值
P0TOPH = 0x40;
P0TOPL = 0x20;
// 配置比较/捕捉模块匹配值
P0CPH0 = 0x00;
P0CPL0 = 0x20;
// 使能比较/捕捉模块
P0CPM0 |= 0x08;
// 启动PCA0计数器
PCACON = 0x1;
select_bank0();
}
频率计算: 24M/(0x4020*2) 约为731Hz,实测波形:
3. Mode2 频率输出方式
(1)工作方式简介
在频率输出方式下,模块的P0CEXn引脚会产生可编程频率的方波。要启用这种模式,需要设置P0SMPn寄存器的P0SMNn位为10。在这种模式下,P0CPn寄存器的更新不使用双缓冲机制。
方波的频率由以下公式确定:
F P 0 C E X n = F P C A 0 2 × P 0 C P H n F_{P0CEXn} = \frac{F_{PCA0}}{2 \times P0CPHn} FP0CEXn=2×P0CPHnFPCA0
其中,( F_{PCA0} ) 是由PCA0的方式寄存器(P0CMD)中的P0CPS2-P0CPS0位选择的PCA0时钟的频率。
P0CPHn中的值代表P0CEXn引脚发生电平变化前要计的PCA时钟数。如果P0CPHn的值为0x00,相当于256。
具体操作流程如下:
- 比较/捕捉模块的低字节P0CPLn与PCA0计数器的低字节进行比较。
- 当两者匹配时,P0CEXn引脚的电平会发生改变,并且P0CPLn中的偏移值会加到P0CPHn。
- 计数器会继续计数,直到再次匹配。
- 周而复始,P0CEXn引脚输出频率由P0CPHn控制。
如果PCA0的某个比较/捕捉模块启用了该模式,P0TOPL的值将固定为0xFF,用户可以通过配置P0TOPH值来改变计数的最大值。
(2)代码实现
下面代码实现 P0CEX0 引脚可输出750kHz波
形,频率计算为:
24
M
2
∗
0
x
10
=
750
k
H
z
\frac{24M}{2*0x10} = 750kHz
2∗0x1024M=750kHz
/**
* @brief PCA0 工作方式2 频率输出方式
*/
void PCA0Mode2(void){
select_bank1();
// 单沿模式、允许PCA0溢出中断、选择系统时钟作为PCA0时钟源
P0CMD = 0x80;
// 频率输出方式、允许P0CEX0输出波形
P0CPM0 = 0x80;
// 配置比较/捕捉模块匹配值
P0CPH0 = 0x10;
P0CPL0 = 0x20;
// 使能比较/捕捉模块、启动PCA0计数器
PCACON = 0x1;
P0CPM0 |= 0x08;
select_bank0();
}
实测波形752kHz。
修改 P0CPHn 可以改变输出波形。
4. Mode3 PWM模式
(1)工作方式简介
PCA0的每个模块都可以被独立地配置为产生脉宽调制(PWM)输出。要启用PWM模式,可以通过配置P0SMPn寄存器的P0SMNn位为11来实现。
功能配置
在PWM模式下,可以通过配置P0FSPn和P0FSNn位来选择四种不同的PWM功能:
- 8位PWM(单斜坡)
- 16位PWM(单斜坡)
- 16位相位修正PWM(双斜坡)
- 16位相频修正PWM(双斜坡)
溢出与自动重载
当比较/捕捉模块工作在8位PWM功能时,PCA0Counter低8位PL0从0x00向P0TOPL递增计数(单斜坡模式)。当PL0溢出时(从0xFF到0x00),保存在P0CPHn中的值被自动装入到P0CPLn,这个过程不需要软件干预。
占空比
在8位PWM方式下,P0CPHn寄存器用来改变PWM输出信号的占空比。当P0TCPn = 0时,当PCA计数器/定时器的低字节(PL0)与P0CPLn中的值相等时,P0CEXn引脚上的输出被清‘0’;当PL0中的计数值溢出时,P0CEXn输出被置‘1’。而当P0TCPn = 1时,P0CEXn引脚输出相反极性的波形。
8位PWM方式的占空比计算公式为:
[ \text{Duty} = \frac{256 - (P0CPHn + 1)}{256} ]
工作方式原理框图
(2)8位脉宽PWM代码实现
下面代码实现输出:
- P0CEX0(P1.2) 输出占空比为 0.8 的正向波形,
- P0CEX1(P1.0) 输出占空比为 0.8 的反向波形。
其中占空比的计算:
D
u
t
y
=
(
256
−
(
P
0
C
P
H
n
+
1
)
)
256
≈
0.8
Duty = \frac{(256-(P0CPHn+1))}{256} ≈ 0.8
Duty=256(256−(P0CPHn+1))≈0.8
频率为 24M/0xFF≈94KHz
/**
* @brief PCA0 工作方式3 PWM8模式
*/
void PCA0Mode3PWM8(void){
select_bank1();
// 单沿模式、允许PCA0溢出中断、选择系统时钟作为PCA0时钟源
P0CMD = 0x80;
// P0CM0 配置比较/捕捉模块0工作方式:PWM8模式、打开捕捉/比较中断
P0CPM0 = 0xC3;
// 配置比较/捕捉模块0匹配值
P0CPH0 = 0x30;
P0CPL0 = 0x30;
// 使能比较/捕捉模块、PWM正向输出波形
P0CPM0 |= 0x08;
// P0CPM1 配置比较/捕捉模块1工作方式: PWM输出方式,打开捕捉/比较中断
P0CPM1 = 0xC3;
// 配置比较/捕捉模块1匹配值
P0CPH1 = 0x30;
P0CPL1 = 0x30;
// 使能比较/捕捉模块1、PWM反向输出波形
P0CPM1 |= 0x0C;
// 启动PCA0计数器
PCACON = 0x01;
select_bank0();
}
(3)16 位脉宽调制器(PWM16 )实现
16位脉宽调制(PWM)与8位PWM相似,都是基于PCA0计数器的单边计数模式。在16位PWM模式下,P0CPn(16位捕捉/比较模块)定义了PWM信号低电平的持续时间,以PCA0时钟数计算。当P0TCPn = 0时,当PCA0计数器与P0CPn值匹配时,P0CEXn输出被置为低电平;当计数器溢出时,P0CEXn输出被置为高电平。当P0TCPn = 1时,P0CEXn引脚输出极性相反的波形。
16位PWM的占空比计算方式为:Duty =(65536-(P0CPn+1))/65536。
下面代码实现:
- P0CEX0 输出占空比为 0.8 的正向波形,
- P0CEX1 输出占空比为 0.8 的反向波形。
频率为 24M/0xFFFF≈366Hz
/**
* @brief PCA0 工作方式3 PWM16模式
*/
void PCA0Mode3PWM16(void){
select_bank1();
// 单沿模式、允许PCA0溢出中断、选择系统时钟作为PCA0时钟源
P0CMD=0x80;
// P0CPM0 配置比较/捕捉模块0工作方式:PWM16模式、打开捕捉/比较中断
P0CPM0=0xD3;
// 配置比较/捕捉模块0匹配值
P0CPH0=0x30;
P0CPL0=0x30;
// 使能比较/捕捉模块0、PWM正向输出波形
P0CPM0|=0x08;
// P0CPM1 配置比较/捕捉模块1工作方式:PWM16模式,打开捕捉/比较中断
P0CPM1=0xD3;
// 配置比较/捕捉模块1匹配值
P0CPH1=0x30;
P0CPL1=0x30;
// 使能比较/捕捉模块1、PWM反向输出波形
P0CPM1|=0x0c;
// 启动PCA0计数器
PCACON=0x1;
select_bank0();
}
(4) 16位相位修正脉宽XPWM16
16位相位修正脉宽调制器(XPWM16)提供了一种获得高精度、相位准确的PWM波形的方法。这种模式基于双斜坡操作,即计时器从0x0000计数到P0TOP,然后从P0TOP倒退回到0x0000。在P0TCPn = 0时,当计时器往P0TOP计数时,若PCA0计数器与P0CPn匹配,P0CEXn输出被置为低电平;而在计时器往0x0000计数时,若PCA0计数器与P0CPn匹配,P0CEXn输出被置为高电平。当P0TCPn = 1时,P0CEXn引脚输出极性相反的波形。
在16位相位修正PWM模式下,PWM的分辨率由P0TOP定义,最小分辨率为2比特(P0TOP设为0x0003),最大分辨率为16位。PWM周期起始于P0TOP点,终止于P0TOP点,并且P0TOP和P0CPn寄存器的值在达到P0TOP值时得到更新。
若要在PCA0运行时改变P0TOP值,建议使用相位与频率修正模式代替相位修正模式。若P0TOP保持不变,则这两种模式实际上没有区别。
在相位修正模式下,PWM的频率为:
F
P
x
XPWM
=
f
sysclk
2
×
P0TOP
F_{P_x\text{XPWM}} = \frac{f_{\text{sysclk}}}{2 \times \text{P0TOP}}
FPxXPWM=2×P0TOPfsysclk
匹配值P0CPn和最大值P0TOPn用来修改占空比,计算公式与后面16位相频修正方式相同 。
下面的代码实现:
- P0CEX0 输出频率为 46.9KHz 的正向波形,
- P0CEX1 输出频率为 46.9Hz 的反向波形
频率计算为: 24M/(2*0x0100) ≈ 47kHz
/**
* @brief PCA0 工作方式3 XPWM16模式
*/
void PCA0Mode3XPWM16(void){
select_bank1();
// 双沿模式、允许PCA0溢出中断、选择系统时钟作为PCA0时钟源
P0CMD=0xC0;
// 配置PCA0计数最大值
P0TOPH=0x01;
P0TOPL=0x00;
// P0CPM0 配置比较/捕捉模块0工作方式:16位相位修正PWM输出方式、打开捕捉/比较中断
P0CPM0=0xE3;
// 配置比较/捕捉模块0匹配值
P0CPH0=0x0;
P0CPL0=0x90;
// 使能比较/捕捉模块0、PWM正向输出波形
P0CPM0|=0x08;
// P0CPM1 配置比较/捕捉模块1工作方式:16位相位修正PWM输出方式,打开捕捉/比较中断
P0CPM1=0xE3;
// 配置比较/捕捉模块1匹配值
P0CPH1=0x0;
P0CPL1=0x90;
// 使能比较/捕捉模块1、PWM反向输出波形
P0CPM1|=0x0c;
// 启动PCA0计数器
PCACON=0x1;
select_bank0();
}
(5) 16 位相频修正 XPPWM16 方式
相频修正PWM(XPPWM)模式也是一种基于双斜坡操作的方法,用于产生高精度、相位与频率准确的PWM波形。
相频修正PWM模式与相位修正PWM模式的主要区别在于P0CPn和P0TOP寄存器的更新时间。在相频修正PWM模式中,P0CPn和P0TOP寄存器的值在0x0000点更新,而在相位修正PWM模式中则是在P0TOP点更新。因此,在相频修正PWM模式下,PWM输出的所有周期均为对称信号,这确保了输出的脉冲是绝对对称的,从而保证了频率的准确性。在P0CPn寄存器通过双缓冲方式得到更新的同一个时钟周期里,PCA0溢出标志CF0被置位,可用来在每次计数器达到0x0000时产生中断。
相频修正PWM模式的PWM分辨率由P0TOP定义,最小分辨率为2比特(P0TOP设为0x0003),最大分辨率为16位(P0TOP设为0xff)。
输出的PWM频率由以下公式定义:
F
P
x
XPPWM
=
f
sysclk
2
×
P0TOP
F_{P_x\text{XPPWM}} = \frac{f_{\text{sysclk}}}{2 \times \text{P0TOP}}
FPxXPPWM=2×P0TOPfsysclk
输出的占空比由以下公式定义:
Duty
=
(
P
0
T
O
P
−
P
0
C
P
n
)
P
0
T
O
P
\text{Duty} = \frac{(P0TOP - P0CPn)}{P0TOP}
Duty=P0TOP(P0TOP−P0CPn)
下面代码实现:
- P0CEX0 输出频率为 46.9KHz 的正向波形
- P0CEX1 输出频率为 46.9KHz 的反向波形
频率为: 24M/(2*0x100) ≈ 47kHz
占空比: (0x100-0x90)/0x100 ≈ 0.44
与相位修正方式相比 ,仅修改了工作模式值。
/**
* @brief PCA0 工作方式3 XPPWM16模式
*/
void PCA0Mode3XPPWM16(void){
select_bank1();
// 双沿模式、允许PCA0溢出中断、选择系统时钟作为PCA0时钟源
P0CMD=0xC0;
// 配置PCA0计数最大值
P0TOPH=0x01;
P0TOPL=0x00;
// P0CPM0 配置比较/捕捉模块0工作方式:16位相频修正PWM输出方式、打开捕捉/比较中断
P0CPM0=0xF3;
// 配置比较/捕捉模块0匹配值
P0CPH0=0x0;
P0CPL0=0x90;
// 使能比较/捕捉模块0、PWM正向输出波形
P0CPM0|=0x08;
// P0CPM1 配置比较/捕捉模块1工作方式:16位相频修正PWM输出方式,打开捕捉/比较中断
P0CPM1=0xF3;
// 配置比较/捕捉模块1匹配值
P0CPH1=0x0;
P0CPL1=0x90;
// 使能比较/捕捉模块1、PWM反向输出波形
P0CPM1|=0x0c;
// 启动PCA0计数器
PCACON=0x1;
select_bank0();
}
本文学习资源来自中颖官方文档。
本文代码开源地址:
https://gitee.com/xundh/learn-sinowealth-51