打印
[其它应用]

可编程计数器阵列PCA0

[复制链接]
457|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-5-7 17:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、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位选择定时器/计数器的时钟源:



按官方文档说明:

系统时钟频率不得低于计数时钟频率的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标志寄存器


-
位编号说明:



2. PCA使能寄存器



PR0 位编号说明:
PCA0 计数器/ 定时器运行控制位:

0:禁止PCA0计数器/定时器
1:允许PCA0计数器/定时器
3. PCA0方式寄存器



位编号说明:



4. P0CPMn PCA捕捉/比较寄存器



位编号说明:



5. P0FORCE强制输出控制寄存器



位说明:



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_{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波
形,频率计算为:


/**
* @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 的反向波形。
其中占空比的计算:


频率为 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的频率为:






匹配值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频率由以下公式定义:





输出的占空比由以下公式定义:




下面代码实现:

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
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/xundh/article/details/137534739

使用特权

评论回复
沙发
weifeng90| | 2024-5-7 21:24 | 只看该作者
其实就是定时器,换了个名字而已。

使用特权

评论回复
板凳
chenqianqian| | 2024-5-8 07:54 | 只看该作者
应该称之为定时器才合理

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1398

主题

14127

帖子

8

粉丝