⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwm.c

📁 直流电机的PWM速度控制程序?绷鞯缁腜WM速度控制程序?绷鞯缁腜WM速度控制程序?绷鞯缁腜WM速度控制程序
💻 C
字号:
/*==============================================================
at12c2052所带的PWM功能演示,内部公用了一个定时器,当启动PWM时PCA
定时器只工作在8位模式,匹配比较器也是按8位的。本程序演示了PWM启动
的设置和调节。
 改用在tasking c51下面编译,并尝试了tasking 方便的在线汇编方式
                                       ------- 晓奇 2006.01.12											--xiaoqi  2005.12.21
 ===============================================================*/
#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){};
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -