前言
这次使用的依旧是 STC8G1K8-16PIN。
可编程计数器阵列
STC8G 中集成有 3 组可编程计数器阵列(PCA/CCP/PWM)模块,可用于软件定时、外部脉冲捕获、高速脉冲输出和 PWM 脉宽输出。
相关寄存器
CCON(PCA控制寄存器)
符号 | 地址 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|---|
CCON | D8H | CF | CR | - | - | CCF3 | CCF2 | CCF1 | CCF0 |
- CF:PCA 计数器溢出中断标志
- CR:PCA 计数器允许控制位
- 0:停止 PCA 计数
- 1:启动 PCA 计数
- CCFn:PCA 模块中断标志
CMOD(PCA模式寄存器)
符号 | 地址 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|---|
CMOD | D9H | CIDL | - | - | - | CPS2 | CPS1 | CPS0 | ECF |
- CIDL:空闲模式下是否停止 PCA 计数
- 0:空闲模式下 PCA 继续计数
- 1:空闲模式下 PCA 停止计数
- CPS[2:1]:PCA 计数脉冲源选择位
- 010:定时器0的溢出脉冲
- 011:ECI脚的外部输入时钟
- 100:系统时钟
- ECF:PCA 计数器溢出中断允许位
- 0:禁止 PCA 计数器溢出中断
- 1:使能 PCA 计数器溢出中断
CL,CH(PCA 计数器寄存器)
CL 和 CH 两个字节合成一个 16 位计数器,CL 为低 8 位计数器,CH 为高 8 位计数器。每个 PCA 时钟16位计数器自动加 1。
CCAPMn(PCA 模块模式控制寄存器)
STC8G 芯片中拥有 3 组 PCA/CCP/PWM 模块。
符号 | 地址 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|---|
CCAPMn | - | - | ECOMn | CCAPPn | CCAPNn | MATn | TOGn | PWMn | ECCFn |
- ECOMn:允许 PCA 模块 n 的比较功能
- CCAPPn:允许 PCA 模块 n 进行上升沿捕获
- CCAPNn:允许 PCA 模块 n 进行下降沿捕获
- MATn:允许 PCA 模块 n 的匹配功能
- TOGn:允许 PCA 模块 n 的高速脉冲输出功能
- PWMn:允许 PCA 模块 n 的脉宽调制输出功能
- ECCFn:允许 PCA 模块 n 的匹配/捕获中断
PCA_PWMn(PCA 模块 PWM 模式控制寄存器)
符号 | 地址 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|---|
PCA_PWMn | - | EBSn[1:0] | XCCAPnH[1:0] | XCCAPnL[1:0] | EPCnH | EPCnL |
- EBSn[1:0]:PCA 模块 n 的 PWM 位数控制
- 00:8位PWM
- 01:7位PWM
- 10:6位PWM
- 11:10位PWM
- XCCAPnH[1:0]:10 位 PWM 的第 9 位和第 10 位的重载值
- XCCAPnL[1:0]:10 位 PWM 的第 9 位和第 10 位的比较值
- EPCnH:PWM 模式下,重载值的最高位(8 位 PWM 的第 9 位…)
- EPCnL:PWM 模式下,比较值的最高位(8 位 PWM 的第 9 位…)
注意:更新 10 位 PWM 的重载值时,必须先写 XCCAPnH[1:0],再写 CCAPnH[7:0]
CCAPnL,CCAPnH(PCA模块模式捕获值/比较值寄存器)
当 PCA 模块 捕获功能 使能时,CCAPnL 和 CCAPnH 用于保存发生捕获时 PCA 的计数值(CL 和 CH)。
当 PCA 模块 比较功能 使能时,PCA 控制器会将当前 CL 和 CH 中计数值与保存在 CCAPnL 和 CCAPnH 中的值进行比较,并给出比较结果。
当 PCA 模块 匹配功能 使能时,PCA 控制器会将当前 CL 和 CH 中的计数值与保存在 CCAPnL 和 CCAPnH 中的值进行比较,看是否匹配,并给出匹配结果。
PWM 脉宽调制模式及频率计算公式
频率计算公式
PCA时钟输入源频率
6位模式的PWM频率:
7位模式的PWM频率:
8位模式的PWM频率:
10位模式的PWM频率:
8位PWM
当 {0,CL[7:0]} 小于 {EPCnL,CCAPnL[7:0]} 时,输出低电平。
当 {0,CL[7:0]} 大于或等于 {EPCnL,CCAPnL[7:0]} 时,输出高电平。
其中,CCAPnL 和 CCAPnH 分别是比较值和重载值,当 CL[7:0] 由 FF 变为 00 溢出时,{EPCnH, CCAPnH[7:0]} 将重新装载到 {EPCnL,CCAPnL[7:0]} 中,这样就能实现无干扰地更新 PWM。
- 注意1:初始化时,CCAPnL 和 CCAPnH 应当相同
- 注意2:更新时,建议只更新 CCAPnH,忽略 CCAPnL
案例 系统时钟
STC8G1K08 芯片,默认的 IRC 频率是 11.0592MHz:
在 11.0592MHz 的 IRC 频率下,选择系统时钟作为 PWM 的时钟输入源,能实现 5.79us ~ 69.48us 的最大脉宽调制。
代码 - 点击查看详情
#include <STC8G.h>
void main(){ P1M0 = 0x00; P1M1 = 0x00;
CCON = 0x00; CMOD = 0x08; //PCA时钟为系统时钟 CL = 0x00; CH = 0x00;
CCAPM0 = 0x42; //PCA模块0为PWM工作模式 PCA_PWM0 = 0x80; //PCA模块0输出6位PWM CCAP0L = 0x20; CCAP0H = 0x20; //PWM占空比为50%[(40H-20H)/40H] CR = 1; //启动PCA计时器
while (1);}
案例 定时器0
选择定时器0(模式0,1T)作为PCA时钟输入源:
详见 17.2.4 和 12.2.14
代码 - 点击查看详情
//2.5ms PWM信号#include <STC8G.h>
void main(){ P1M0 = 0x00; P1M1 = 0x00;
/*----PWM----*/ CCON = 0x00; CMOD = 0x04; //定时器0 CL = 0x00; CH = 0x00; CCAPM0 = 0x42; //PCA模块0为PWM工作模式 PCA_PWM0 = 0x80; //PCA模块0输出6位PWM CCAP0L = 0x20; //PWM占空比为50%[(40H-20H)/40H] CCAP0H = 0x20; //PWM占空比为50%[(40H-20H)/40H]
/*----定时器0----*/ AUXR = 0x80; //定时器时钟1T模式 TMOD = 0x00; //设置定时器模式 TL0 = 0x50; //设置定时初始值 TH0 = 0xFE; //设置定时初始值 TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时 CR = 1; //启动PCA计时器
while (1);}
增强型 PWM
2022-09-22 很遗憾,STC8G 中仅有部分型号支持,我并没有此类芯片
代码 - 点击查看详情
// 18.1.1 PWM采用独立配置 不复位 开启PWM0PWMSET = 0x01; //使能PWM0模块(必须先使能模块后面的设置才有效)
// 3.1.2 使能访问 XFRP_SW2 = 0x80;// 18.1.6 PWM 时钟选择 系统时钟分频(SYSclk/1)PWM0CKS = 0x00; //PWM0时钟为系统时钟// 18.1.5 PWM 计数器寄存器 From 0x1000 >> 0x0000PWM0C = 0x1000; //设置PWM0周期为1000H个PWM时钟// 18.1.8 PWM 电平输出设置寄存器PWM00T1= 0x0100; //在计数值为100H地方PWM00通道输出低电平PWM00T2= 0x0500; //在计数值为500H地方PWM00通道输出高电平// 18.1.9 ENO INI NULL NULL NULL ENI ENT2I ENT1IPWM00CR= 0x80; //使能PWM00输出// 3.1.2 禁止访问 XFRP_SW2 = 0x00;// 18.1.2 PWM0CEN 开始计数PWMCFG01 = 0x01; //启动PWM0模块
软件延时
不多赘述,简单的通过延时函数和高低电平控制 PWM 信号的脉宽。