1457 字
7 分钟
STC PWM输出
2022-08-22

前言#

这次使用的依旧是 STC8G1K8-16PIN。


可编程计数器阵列#

STC8G 中集成有 3 组可编程计数器阵列(PCA/CCP/PWM)模块,可用于软件定时、外部脉冲捕获、高速脉冲输出和 PWM 脉宽输出。

相关寄存器#

CCON(PCA控制寄存器)#

符号地址B7B6B5B4B3B2B1B0
CCOND8HCFCR--CCF3CCF2CCF1CCF0
  • CF:PCA 计数器溢出中断标志
  • CR:PCA 计数器允许控制位
    • 0:停止 PCA 计数
    • 1:启动 PCA 计数
  • CCFn:PCA 模块中断标志

CMOD(PCA模式寄存器)#

符号地址B7B6B5B4B3B2B1B0
CMODD9HCIDL---CPS2CPS1CPS0ECF
  • 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 模块。

符号地址B7B6B5B4B3B2B1B0
CCAPMn--ECOMnCCAPPnCCAPNnMATnTOGnPWMnECCFn
  • 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频率:PWMFrequency=PCAFrequency64PWM_{Frequency}=\frac{PCA_{Frequency}}{64}

7位模式的PWM频率:PWMFrequency=PCAFrequency128PWM_{Frequency}=\frac{PCA_{Frequency}}{128}

8位模式的PWM频率:PWMFrequency=PCAFrequency256PWM_{Frequency}=\frac{PCA_{Frequency}}{256}

10位模式的PWM频率:PWMFrequency=PCAFrequency1024PWM_{Frequency}=\frac{PCA_{Frequency}}{1024}

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:

  • PWMFrequency=11.059264=0.1728MHzPWM_Frequency=\frac{11.0592}{64}=0.1728MHz
  • PWMCycle=1PWMFrequency=5.79usPWM_Cycle=\frac{1}{PWM_Frequency}=5.79us

在 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时钟输入源:

  • TimerFrequency=PWMFrequency×64Timer_Frequency=PWM_Frequency \times 64
  • [TH0,TL0]=65536SYSclkTimerFrequency[TH0,TL0]=65536-\frac{SYSclk}{Timer_Frequency}

详见 17.2.412.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采用独立配置 不复位 开启PWM0
PWMSET = 0x01; //使能PWM0模块(必须先使能模块后面的设置才有效)
// 3.1.2 使能访问 XFR
P_SW2 = 0x80;
// 18.1.6 PWM 时钟选择 系统时钟分频(SYSclk/1)
PWM0CKS = 0x00; //PWM0时钟为系统时钟
// 18.1.5 PWM 计数器寄存器 From 0x1000 >> 0x0000
PWM0C = 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 ENT1I
PWM00CR= 0x80; //使能PWM00输出
// 3.1.2 禁止访问 XFR
P_SW2 = 0x00;
// 18.1.2 PWM0CEN 开始计数
PWMCFG01 = 0x01; //启动PWM0模块

软件延时#

不多赘述,简单的通过延时函数和高低电平控制 PWM 信号的脉宽。

STC PWM输出
https://fuwari.vercel.app/posts/嵌入式/stc/stc-pwm输出/
作者
Asuwee
发布于
2022-08-22
许可协议
CC BY-NC-SA 4.0