基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的PWM(脉冲宽度调制)应用
- STC12C5A60S2系列1T 8051单片机管脚图
- STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置
- STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍
- STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的结构
- STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的各种不同工作模式介绍
- 基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的特殊功能寄存器列表
- 基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的PWM(脉冲宽度调制)模块用到的特殊功能寄存器
- PCA辅助寄存器AUXR1
- PCA工作模式寄存器CMOD
- PCA工作模式寄存器CCON
- PCA比较/捕获寄存器CCAPM0和CCAPM1
- PCA的16位定时器/计数器 —— 高八位CH和低八位CL
- PCA捕获/比较寄存器高八位CCAPnH和低八位CCAPnL
- PCA的PWM寄存器PCA_PWM0和PCA_PWM1
- 利用晶振频率为12MHz的STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块0从P1.3引脚输出频率为200Hz且占空比为40%的矩形波 可根据以下CCP/PCA/PWM模块的脉冲宽度调制模式来编写程序
- 利用晶振频率为12MHz的STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块0从P1.3引脚输出频率为200Hz且占空比可调的矩形波 可根据以下CCP/PCA/PWM模块的脉冲宽度调制模式来编写程序
- 三级目录
STC12C5A60S2系列1T 8051单片机管脚图
STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置
STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍
STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的结构
STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的各种不同工作模式介绍
基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的特殊功能寄存器列表
基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的PWM(脉冲宽度调制)模块用到的特殊功能寄存器
PCA辅助寄存器AUXR1
作用:用来设置STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的单片机引脚
PCA工作模式寄存器CMOD
作用:用来设置STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块以下功能
(1)、空闲情况下是否停止CCP/PCA/PWM模块计数
(2)、CCP/PCA/PWM模块计数脉冲时钟源选择 (3)、CCP/PCA/PWM模块计数溢出中断使能
PCA工作模式寄存器CCON
作用:用来设置STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块以下功能
(1)、CCP/PCA/PWM模块计数溢出标志位
(2)、CCP/PCA/PWM模块运行
(3)、CCP/PCA/PWM模块0中断标志位
(4)、CCP/PCA/PWM模块1中断标志位
PCA比较/捕获寄存器CCAPM0和CCAPM1
作用:用来设置STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块以下功能
(1)、CCP/PCA/PWM模块0允许比较器功能控制
(2)、CCP/PCA/PWM模块0上升沿捕获控制
(3)、CCP/PCA/PWM模块0下降沿捕获控制
(4)、CCP/PCA/PWM模块0匹配工作模式寄存器CCON中断标志位控制
(5)、CCP/PCA/PWM模块0匹配CCPn寄存器引脚电平翻转控制
(6)、CCP/PCA/PWM模块0脉冲宽度调制模式
(7)、CCP/PCA/PWM模块0使能工作模式寄存器CCON中断标志位控制
(8)、CCP/PCA/PWM模块1允许比较器功能控制
(9)、CCP/PCA/PWM模块1上升沿捕获控制
(10)、CCP/PCA/PWM模块1下降沿捕获控制
(11)、CCP/PCA/PWM模块1匹配工作模式寄存器CCON中断标志位控制
(12)、CCP/PCA/PWM模块1匹配CCPn寄存器引脚电平翻转控制
(13)、CCP/PCA/PWM模块1脉冲宽度调制模式
(14)、CCP/PCA/PWM模块1使能工作模式寄存器CCON中断标志位控制
PCA的16位定时器/计数器 —— 高八位CH和低八位CL
作用:作为CCP/PCA/PWM模块0或CCP/PCA/PWM模块1的计数器进行脉冲计数
PCA捕获/比较寄存器高八位CCAPnH和低八位CCAPnL
作用:作为捕获或比较时 用于CCP/PCA/PWM模块0或CCP/PCA/PWM模块1的计数器进行脉冲计数 作为脉冲宽度调制时 用于CCP/PCA/PWM模块0或CCP/PCA/PWM模块1的高八位CCAPnH脉冲计数重载给低八位CCAPnL进行脉冲计数控制脉冲宽度调制
PCA的PWM寄存器PCA_PWM0和PCA_PWM1
作用:组成CCP/PCA/PWM模块0或CCP/PCA/PWM模块1的PWM寄存器内部累计计数的9位数据
利用晶振频率为12MHz的STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块0从P1.3引脚输出频率为200Hz且占空比为40%的矩形波 可根据以下CCP/PCA/PWM模块的脉冲宽度调制模式来编写程序
#include <STC12C5A60S2.h>
void main()
{
CMOD = 0x04 ;//CCP/PCA/PWM模块空闲模式下CCP/PCA/PWM模块计数器继续工作 选定时器T0溢出脉冲作为CCP/PCA/PWM模块时钟源 禁止CCP/PCA/PWM模块溢出中断使能
CCON = 0x00;//CCP/PCA/PWM模块计数溢出标志位清0 运行位清0 中断标志位清0
CCAPM0 = 0x42;//CCP/PCA/PWM模块0允许比较器功能控制 不允许边沿捕获控制 不匹配工作模式寄存器CCON中断标志位控制 不匹配CCPn寄存器引脚电平翻转控制 输出脉冲宽度调制模式 不使能工作模式寄存器CCON中断标志位控制
CH = 0x00;//CCP/PCA/PWM模块16位计数器高八位计数寄存器脉冲计数清0
CL = 0x00;//CCP/PCA/PWM模块16位计数器低八位计数寄存器脉冲计数清0
CCAP0H = 0x99;//同下
CCAP0L = 0x99;//CCP/PCA/PWM模块0输出占空比为40%的PWM CCP/PCA/PWM模块0输出占空比为40%的PWM 根据PWM占空比=(256-CCAP0L)/256求出CCAP0L 即40%=(256-CCAP0L)/256 计算转化后 CCAP0L=256-0.4x256=256-102=153=0x99
CR = 1;//启动CCP/PCA/PWM模块16计数器
AUXR = 0x80;//将定时器/计数器设置为1T模式 不用分频
TMOD = 0x02;//选定时器/计数器为定时器0 工作模式为模式2的8位自动重装计数 即溢出时将TH0存放的脉冲计数自动装入TL0
TH0 = 0x16;//由于选定时器/计数器为1T模式不用分频定时器0 工作模式为模式2的8位自动重装计数 因此先根据PWM频率=CCP/PCA/PWM模块时钟源频率/256求出CCP/PCA/PWM模块时钟源频率 即200Hz=CCP/PCA/PWM模块时钟源频率/256 求CCP/PCA/PWM模块时钟源频率=51200Hz 再根据定时器初值(定时计数初值)=2^n-(晶振频率/几分频/定时频率)求出定时器初值(定时计数初值) 即定时器初值(定时计数初值)=2^8-(12MHz/1/51200Hz)=256-(12000000Hz/51200Hz)=256-234=22=0x16
TL0 = 0x16;//同上
TR0 = 1;//启动定时器0
while(1);
}
利用晶振频率为12MHz的STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块0从P1.3引脚输出频率为200Hz且占空比可调的矩形波 可根据以下CCP/PCA/PWM模块的脉冲宽度调制模式来编写程序



#include <STC12C5A60S2.h>
#define uchar unsigned char//自定义无符号字符型为uchar
#define uint unsigned int//自定义无符号整数型为uint
#define KeyPressDeshakeTime 10//自定义按键按下消抖时间为10ms
#define KeyLongPressDelayTime 500//自定义按键长按延时时间为500ms
#define KeyLongPressIntervalChangeTime 25//自定义按键长按间隔变化时间为25ms
uchar AddKeyLockFlag;//声明增加按键锁定标志位变量
uchar DecKeyLockFlag;//声明减少按键锁定标志位变量
uchar KeyNumber = 0;//定义按键键值为0
uchar AddKeyLongPressAddIntervalTime;//声明增加按键长按连增间隔时间变量
uchar DecKeyLongPressDecIntervalTime;//声明减少按键长按连减间隔时间变量
uint AddKeyPressDelayTime;//声明增加按键按下延时时间变量
uint DecKeyPressDelayTime;//声明减少按键按下延时时间变量
sbit AddKey = P2^0;//位定义增加按键为单片机P2.0引脚
sbit DecKey = P2^1;//位定义减少按键为单片机P2.1引脚
uchar PwmValue;//声明脉宽调制变量
void PcaInit();//
void Timer0Init();//
void Timer1Init();//
void PwmDutyCycleSet();//
void main()
{
PcaInit();//
Timer0Init();//
Timer1Init();//
while(1)
{
PwmDutyCycleSet();//
}
}
void PcaInit()//
{
CMOD = 0x04 ;//CCP/PCA/PWM模块空闲模式下CCP/PCA/PWM模块计数器继续工作 选定时器T0溢出脉冲作为CCP/PCA/PWM模块时钟源 禁止CCP/PCA/PWM模块溢出中断使能
CCON = 0x00;//CCP/PCA/PWM模块计数溢出标志位清0 运行位清0 中断标志位清0
CCAPM0 = 0x42;//CCP/PCA/PWM模块0允许比较器功能控制 不允许边沿捕获控制 不匹配工作模式寄存器CCON中断标志位控制 不匹配CCPn寄存器引脚电平翻转控制 输出脉冲宽度调制模式 不使能工作模式寄存器CCON中断标志位控制
CH = 0x00;//CCP/PCA/PWM模块16位计数器高八位计数寄存器脉冲计数清0
CL = 0x00;//CCP/PCA/PWM模块16位计数器低八位计数寄存器脉冲计数清0
CCAP0H = 0x00;//同下
CCAP0L = 0x00;//CCP/PCA/PWM模块
CR = 1;//启动CCP/PCA/PWM模块16计数器
}
void Timer0Init()//
{
AUXR = 0x80;//将定时器/计数器设置为1T模式 不用分频
TMOD = 0x02;//选定时器/计数器为定时器0 工作模式为模式2的8位自动重装计数 即溢出时将TH0存放的脉冲计数自动装入TL0
TH0 = 0x16;//由于选定时器/计数器为1T模式不用分频定时器0 工作模式为模式2的8位自动重装计数 因此先根据PWM频率=CCP/PCA/PWM模块时钟源频率/256求出CCP/PCA/PWM模块时钟源频率 即200Hz=CCP/PCA/PWM模块时钟源频率/256 求CCP/PCA/PWM模块时钟源频率=51200Hz 再根据定时器初值(定时计数初值)=2^n-(晶振频率/几分频/定时频率)求出定时器初值(定时计数初值) 即定时器初值(定时计数初值)=2^8-(12MHz/1/51200Hz)=256-(12000000Hz/51200Hz)=256-234=22=0x16
TL0 = 0x16;//同上
TR0 = 1;//启动定时器0
}
void Timer1Init(void)//定时器1定时2ms初始化函数 晶振为12MHz
{
TMOD &= 0x0f;//设定定时器/计数器工作模式清0
TMOD |= 0x10;//设定定时器/计数器为定时器 工作模式为16位定时器1模式1
TH1 = 0xf8;//设定定时器1计数高8位初值
TL1 = 0x30;//设定定时器1计数低8位初值
TF1 = 0;//定时器1溢出中断标志位清0
ET1 = 1;//打开定时器1中断开关
EA = 1;//打开定时器中断总开关
TR1 = 1//打开定时器1开关
}
void Timer1(void) interrupt 3//定时器1定时2ms中断函数 晶振为12MHz
{
TR1 = 0;//
KeyScan();//按键扫描函数
TH1 = 0xf8;//设定定时器1计数高8位初值
TL1 = 0x30;//设定定时器1计数低8位初值
TR1 = 1;//
}
void KeyScan(void)//按键扫描函数 该函数放在定时器定时2ms的中断函数中扫描
{
if(AddKey)//如果增加按键没按下或弹起
{
AddKeyLockFlag = 0;//增加按键锁定标志位清0
AddKeyPressDelayTime = 0;//增加按键按下延时时间清0
}
else if(!AddKeyLockFlag)//如果增加按键锁定标志位置1 即增加按键按下
{
AddKeyPressDelayTime++;//增加按键按下延时时间自加
if(AddKeyPressDelayTime > KeyPressDeshakeTime)//如果增加按键按下延时时间大于按键按下消抖时间
{
AddKeyPressDelayTime = 0;//增加按键按下延时时间清0
KeyNumber = 1;//按键键值置1 此处是单击增加 可赋给swicth()语句中的变量来对数值单击增加
AddKeyLockFlag = 1;//增加按键锁定标志位置1
}
}
else if(AddKeyPressDelayTime < KeyLongPressDelayTime)//如果增加按键按下延时时间小于按键长按延时时间
{
AddKeyPressDelayTime++;//增加按键按下延时时间自加
}
else//如果增加按键按下延时时间大于按键长按延时时间
{
AddKeyLongPressAddIntervalTime++;//增加按键长按连增间隔时间自加
if(AddKeyLongPressAddIntervalTime > KeyLongPressIntervalChangeTime)//如果增加按键长按连增间隔时间大于按键长按间隔变化时间
{
AddKeyLongPressAddIntervalTime = 0;//增加按键长按连增间隔时间清0
KeyNumber = 1;//按键键值置1 此处是连击增加 可赋给swicth()语句中的变量来对数值连击增加
}
}
if(DecKey)//如果减少按键没按下或弹起
{
DecKeyLockFlag = 0;//减少按键锁定标志位清0
DecKeyPressDelayTime = 0;//减少按键按下延时时间清0
}
else if(!DecKeyLockFlag)//如果减少按键锁定标志位置1 即减少按键按下
{
DecKeyPressDelayTime++;//减少按键按下延时时间自加
if(DecKeyPressDelayTime > KeyPressDeshakeTime)//如果减少按键按下延时时间大于按键按下消抖时间
{
DecKeyPressDelayTime = 0;//减少按键按下延时时间清0
KeyNumber = 2;//按键键值置2 此处是单击减少 可赋给swicth()语句中的变量来对数值单击减少
DecKeyLockFlag = 1;//减少按键锁定标志位置1
}
}
else if(DecKeyPressDelayTime < KeyLongPressDelayTime)//如果减少按键按下延时时间小于按键长按延时时间
{
DecKeyPressDelayTime++;//减少按键按下延时时间自加
}
else//如果减少按键按下延时时间大于按键长按延时时间
{
DecKeyLongPressDecIntervalTime++;//减少按键长按连减间隔时间自加
if(DecKeyLongPressDecIntervalTime > KeyLongPressIntervalChangeTime)//如果减少按键长按连减间隔时间大于按键长按间隔变化时间
{
DecKeyLongPressDecIntervalTime = 0;//减少按键长按连减间隔时间清0
KeyNumber = 2;//按键键值置2 此处是连击减少 可赋给swicth()语句中的变量来对数值连击减少
}
}
}
void PwmDutyCycleSet()//
{
switch(KeyNumber)//
{
case 1 ://
PwmValue++;//
if(PwmValue > 255)//
{
PwmValue = 255;//
}
CCAP0H = CCAP0L = PwmValue;//
KeyNumber = 0;//
break;//
case 2 ://
PwmValue--;//
if(PwmValue < 0)//
{
PwmValue = 0;//
}
CCAP0H = CCAP0L = PwmValue;//
KeyNumber = 0;//
break;//
default:break;//
}
}