STC12C5A60S2上两路PWM的使用方法

写在前面

  这篇博客介绍下如果使用STC12C5A60S2这款单片机上两路自带的PWM模块输出占空比不同的方波。
  先上代码:

/*------------------------------------------------------------------*/
/* --- STC MCU Limited ---------------------------------------------*/
/* --- STC12C5Axx Series MCU PCA module output PWM wave Demo -------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966----------------------*/
/* --- Web: www.STCMCU.com -----------------------------------------*/
/* --- Web: www.GXWMCU.com -----------------------------------------*/
/* If you want to use the program or the program referenced in the  */
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/
/*********************************************************************
*		                		 呼吸灯							     *
实现现象:上电之后,P1.3 P1.4 每5MS占空比增加1%,加到100%之后开始递减到0%
				P1.3与P1.4的波形互补(相反)
注意事项:																				  
*********************************************************************/
#include "reg51.h"
#include "intrins.h"

#define FOSC    11059200L

typedef unsigned char BYTE;
typedef unsigned int WORD;
//寄存器地址声明,因为没有包含STC12C5A60S2的头文件
/*Declare SFR associated with the PCA */
sfr CCON        =   0xD8;           //PCA control register
sbit CCF0       =   CCON^0;         //PCA module-0 interrupt flag
sbit CCF1       =   CCON^1;         //PCA module-1 interrupt flag
sbit CR         =   CCON^6;         //PCA timer run control bit
sbit CF         =   CCON^7;         //PCA timer overflow flag
sfr CMOD        =   0xD9;           //PCA mode register
sfr CL          =   0xE9;           //PCA base timer LOW
sfr CH          =   0xF9;           //PCA base timer HIGH
sfr CCAPM0      =   0xDA;           //PCA module-0 mode register
sfr CCAP0L      =   0xEA;           //PCA module-0 capture register LOW
sfr CCAP0H      =   0xFA;           //PCA module-0 capture register HIGH
sfr CCAPM1      =   0xDB;           //PCA module-1 mode register
sfr CCAP1L      =   0xEB;           //PCA module-1 capture register LOW
sfr CCAP1H      =   0xFB;           //PCA module-1 capture register HIGH
sfr PCAPWM0     =   0xf2;
sfr PCAPWM1     =   0xf3;
//***********************************端口声明************************************//
sbit led1 = P1^0;
sbit led4 = P1^3;

unsigned char num=0x00;
unsigned char num1=0xfe;
unsigned int delay1;
bit flag,flag1,flag2;
//*******************************************************************************/
//* 函数名         :pwm_set(unsigned char x,unsigned char y)
//* 函数功能		  :重设占空比
//* 输入          : num,num1
//* 输出          : 无
//*******************************************************************************/
void pwm_set(unsigned char x,unsigned char y){
	CCAP0H=x; //设置比较值
	CCAP0L=x;
	CCAP1H=y;
	CCAP1L=y;
}
/*******************************************************************************
* 函数名         : delay1ms()
* 函数功能		 :延时1ms
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
bit delay1ms()
{
	unsigned int x,y;
for(x=1; x>0; x--)
  for(y=920; y>0; y--);
	return 1;
}

/*******************************************************************************
* 函数名         : pwm_init()
* 函数功能		 :初始化PWM模块
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void pwm_init(){
	CCON = 0;                       //Initial PCA control register
                                    //PCA timer stop running
                                    //Clear CF flag
                                    //Clear all module interrupt flag
    CL = 0;                         //Reset PCA base timer
    CH = 0;
    CMOD = 0x02;                    //Set PCA timer clock source as Fosc/2
                                    //Disable PCA timer overflow interrupt
    CCAP0H = CCAP0L = 0x00;         //PWM0 port output 0% duty cycle square wave
    CCAPM0  = 0x42;                  //PCA module-0 work in 8-bit PWM mode and no PCA interrupt

    CCAP1H = CCAP1L = 0xff;         //PWM1 port output 0% duty cycle square wave
    CCAPM1 = 0x42;                  //PCA module-1 work in 8-bit PWM mode and no PCA interrupt

    CR = 1;                         //PCA timer start run
}
/*******************************************************************************
* 函数名         : tmr0_init()
* 函数功能		 :初始化定时器0
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void tmr0_init(){
	EA = 0;
	TF0 = 0;
	TMOD = 0X01;
	TH0 = 0XEE;						//5MS
	TL0 = 0X00;
	
	ET0 = 1;
	EA = 1;
	TR0 = 1;
}
/*******************************************************************************
* 函数名         : isr_timer0 ()
* 函数功能		 :定时器0中断服务函数
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void isr_timer0 () interrupt 1 using 0{
	TH0 = 0XEE;						//5MS
	TL0 = 0X00;
	if(!flag){
		if(++num > 0xfe) flag = 1;
	}
	else{
		if(--num < 0x01) flag = 0;
	}
	if(!flag1){
		if(++num1 > 0xfe) flag1 = 1;
	}
	else{
		if(--num1 < 0x01) flag1 = 0;
	}
}

/************************************主函数****************************************/
void main()
{
    pwm_init();
	tmr0_init();
    while (1){
		pwm_set(num,num1);	
	}
}


  代码用的是STC给出的官方示例代码,不过STC的给的代码是占空比固定的。于是再开启定时器0让占空比每5ms改变一次,在主函数中不断把递增的值重新赋值给PWM0和1的比较/捕获寄存器,PWM在开启之后计数器CL会不断的递增,一旦跟CCAP0L或CCAP1L相等,就会让相应的PWM输出口输出高电平,在脉宽调节模式里面,CH暂时没发现作用(推断),CCAP0H和CCAP1H分别是用来调节PWM0和PWM1这两路输出占空比的,当CL的值从FF变为00之后,CCAP0H/CCAP1H会把值赋给CCAP0L/CCAP1L,这样实现无干扰更新占空比。其他模式可以参考芯片手册,这里只介绍PWM模式下的用法。

你可能感兴趣的:(技术分享)