- /*==============================================================
- at12c2052所带的PWM功能演示,内部公用了一个定时器,当启动PWM时PCA
- 定时器只工作在8位模式,匹配比较器也是按8位的。本程序演示了PWM启动
- 的设置和调节。
- 改用在tasking c51下面编译,并尝试了tasking 方便的在线汇编方式
- ------- 晓奇 2006.01.12
- ===============================================================*/
- #include "STC12C2052AD.h"
- /*#include<INTRINS.h>*/
- #define uint unsigned int
- #define uchar unsigned char
- uint i;
- uchar upordn; /* 升降标志,1=上升 */
- void initall(void);
- _interrupt(1) void timers0(void);
- _interrupt (6) void PCA_LVD(void);
- void initall(void)
- {
- TMOD= 0x11; /* 0000 0001 T0作为16位计数器 */
- TH0 = 0xc0; /* 定时器0初始值装入 */
- TL0 = 0x00;
- ET0 = 1; //开中断
- IE |= 0x40; /* 使能PCA定时功能 */
- EA = 1;
- AUXR = 0x80;
- /* 1000 0000
- |||| ||++-保留
- |||| |+---低电压中断允许:0=禁止,1=允许,5V..3.7V,3V..2.4V以下
- |||| +----SPI中断允许位:0=禁止,1=允许
- |||+------ADC中断允许位:0=禁止,1=允许
- ||+-------串口模式0时时钟设定:0=传统1/12, 1=1/2 2分频;
- |+--------定时器ct1时钟源设定:0=传统1/12,1=1:1不分频;
- +---------定时器ct0时钟源设定:0=传统1/12,1=1:1不分频;
- */
- P1 = 0xff;
- P1M0 = 0x00; /* P1口用传统51准双向口模式 */
- P1M1 = 0x00;
- CMOD = 0x03; /* 内部时钟,Fosc/2, PCA计数溢出中断使能*/
- /* 0000 0011 PCA 模式寄存器
- |||| |||+--ECF...PCA计数溢出中断使能:ECF=1时,使能寄存器CCON CF位的
- |||| ||| 中断。ECF=0时,禁止该功能。
- |||| |++---CPS1,CPS0 选择PCA 时钟源输入(PCA计数脉冲选择)
- |||| | 0 0 0,内部时钟,Fosc/12
- |||| | 0 1 1,内部时钟,Fosc/2
- |||| | 1 0 2,定时器0溢出,由于定时器0可以工作在1T方式,
- |||| | 所以可以达到计一个时钟就溢出, 频率反而
- |||| | 是最高的,可达到Fosc
- |||| | 1 1 3,ECI/P3.4脚的外部时钟输入(最大速率=Fosc/2)
- |+++-+-----保留
- +----------CIDL...计数器阵列空闲控制:CIDL=0时,空闲模式下PCA计数器
- 继续工作。CIDL=1时,空闲模式下PCA计数器停止工作。
- */
- CH = 0x00; /* PCA计数器初始值高8位 */
- CL = 0x00; /* PCA计数器初始值低8位 */
- CCAP0H = 0x00; /* 当出现捕获或比较时,它们用来保存16 位的计数值。
- 当PCA 模块用在PWM 模式中时,它们用来控制输出的
- 占空比。CCAP0H.CCAP0L分别为高低8位,组合使用
- */
- CCAP0L = 0x00;
- CCAP1H = 0x00; /* 当出现捕获或比较时,它们用来保存16 位的计数值。
- 当PCA 模块用在PWM 模式中时,它们用来控制输出的
- 占空比。CCAP1H.CCAP1L分别为高低8位,组合使用
- */
- CCAP1L = 0x00;
- CCAPM1 = 0x4c; /* PCA 比较/捕获模块寄存器1作为16位软件定时器。使能
- 比较器,PCA计数值与模块的比较/捕获寄存器的值的匹配将
- 置位CCON寄存器的中断标志位CCF1,使能CCF1中断 */
- /*
- 0100 1100 功能说明
- |||| |||+---ECCF1.. 使能CCF1中断。使能寄存器CCON的比较/捕获标志CCF1,
- |||| ||| 用来产生中断。
- |||| ||+----PWM1... 脉宽调节模式。当PWMn=1时,使能CEXn脚用作脉宽调节输出。
- |||| |+-----TOG1... 翻转。当TOG1= 1时, PCA计数值与模块的比较/捕获寄存
- |||| | 器的值的匹配将使CEXn脚翻转。(CEX1/P3.5)
- |||| +------MAT1... 匹配。当=1时, PCA计数值与模块的比较/捕获寄存器的值
- |||| 的匹配将置位CCON寄存器的中断标志位CCF1。
- |||+--------CAPN1.. 负捕获。CAPN1= 1时使能下降沿捕获。
- ||+---------CAPP1.. 正捕获。CAPP1= 1时使能上升沿捕获。
- |+----------ECOM1.. 使能比较器。ECOM1= 1时使能比较器功能。
- +-----------CCAPM1^7保留
- 使用的机种基本模式组合:
- ECOM1 CAPP1 CAPN1 MAT1 TOG1 PWM1 ECCF1 模块功能
- 0 0 0 0 0 0 0 无此操作
- X 1 0 0 0 0 X 16位捕获模式,由CEX1的上升沿触发
- X 0 1 0 0 0 X 16位捕获模式,由CEX1的下降沿触发
- X 1 1 0 0 0 X 16位捕获模式,由CEX1的跳变触发
- 1 0 0 1 0 0 X 16位软件定时器
- 1 0 0 1 1 0 X 16位高速输出
- 1 0 0 0 0 1 0 8位PWM
- */
- CCAPM0 = 0x42; /* PCA 比较/捕获模块寄存器0作为16位软件定时器。使能
- 比较器,PCA计数值与模块的比较/捕获寄存器的值的匹配将
- 置位CCON寄存器的中断标志位CCF0,使能CCF0中断 寄存器
- 位功能同上*/
- CR = 1; //Start PCA Timer.
- TR0 = 1; //启动计时
- i = 0;
- upordn = 1;
- }
- /* ------------- 定时器0用来定时调节PWM的输出占空比 ------------- */
- _interrupt(1) void timers0(void)
- {
- TL0 = 0x00;
- TH0 = 0xc0;
- CCAP0H = i>>8; /* CCAP0L不用赋值,他不参与工作 */
- if(upordn) /* 逐步加宽PWM、加快脉冲输出 */
- {
- if(++i==65535) /* 到头 */
- {
- upordn=0; /* 调头 */
- }
- }
- else /* 逐步减窄PWM、减慢脉冲输出 */
- {
- if(--i==0) /* 到头 */
- {
- upordn=1; /* 调头 */
- }
- }
- P1 = ~(i>>8); /* 高8位输出LED指示,作监视用 */
- }
- /* ------------ PCA 定时中断,负责清除溢出标志并赋初值 ------------- */
- /* 摇晃编程板可以看到P3.5连接的led闪亮频率的缓慢变化,虚线在变长变短 */
- _interrupt (6) void PCA_LVD(void)
- {
- CH = i>>8;
- CL = i&0xff;
- CF = 0;
- CCF0 = 0;
- // LedPCA ^= 1; /* 频率要求不高的时候这里可以插入用户代码 */
- }
- void main(void)
- {
- initall();
- // 测试tasking c51的在线汇编功能
- #pragma asm
- mov r0,#0f0h
- v1: nop
- nop
- djnz r0,v1
- nop
- #pragma endasm
- // 编译很顺利通过,不用作任何附加的设定
- while(1){};
- }
STC单片机PWM的实现方法与原理参考实例
最新推荐文章于 2023-06-05 21:29:51 发布