可以獨立調節,這個系列的時PCA,關斷時會一起關,但調節PWM是沒問題的。
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在文章中應用此代碼,請在文章中注明使用了宏晶科技的資料及程序 */
/*---------------------------------------------------------------------*/
#include <reg52.h>
/************* 功能說明 **************
輸出3路9~16位PWM信號。
PWM頻率 = MAIN_Fosc / PWM_DUTY, 假設 MAIN_Fosc = 24MHZ, PWM_DUTY = 6000, 則輸出PWM頻率為4000HZ.
******************************************/
/***************************用戶宏定義*******************************************************/
#define MAIN_Fosc 16000000UL //定義主時鐘
#define PWM_DUTY 6000 //定義PWM的周期,數值為PCA所選擇的時鐘脈沖個數。
#define PWM_HIGH_MIN 80 //限制PWM輸出的最小占空比, 避免中斷里重裝參數時間不夠。
#define PWM_HIGH_MAX (PWM_DUTY - PWM_HIGH_MIN) //限制PWM輸出的最大占空比。
/********************************************************************************************/
#define PCA0 0
#define PCA1 1
#define PCA2 2
#define PCA_Counter 3
#define PCA_P12_P11_P10_P37 (0<<4)
#define PCA_P34_P35_P36_P37 (1<<4)
#define PCA_P24_P25_P26_P27 (2<<4)
#define PCA_Mode_PWM 0x42
#define PCA_Mode_Capture 0
#define PCA_Mode_SoftTimer 0x48
#define PCA_Mode_HighPulseOutput 0x4c
#define PCA_Clock_1T (4<<1)
#define PCA_Clock_2T (1<<1)
#define PCA_Clock_4T (5<<1)
#define PCA_Clock_6T (6<<1)
#define PCA_Clock_8T (7<<1)
#define PCA_Clock_12T (0<<1)
#define PCA_Clock_Timer0_OF (2<<1)
#define PCA_Clock_ECI (3<<1)
#define PCA_Rise_Active (1<<5)
#define PCA_Fall_Active (1<<4)
#define PCA_PWM_8bit (0<<6)
#define PCA_PWM_7bit (1<<6)
#define PCA_PWM_6bit (2<<6)
#define ENABLE 1
#define DISABLE 0
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sfr AUXR1 = 0xA2;
sfr CCON = 0xD8;
sfr CMOD = 0xD9;
sfr CCAPM0 = 0xDA; //PCA模塊0的工作模式寄存器。
sfr CCAPM1 = 0xDB; //PCA模塊1的工作模式寄存器。
sfr CCAPM2 = 0xDC; //PCA模塊2的工作模式寄存器。
sfr CL = 0xE9;
sfr CCAP0L = 0xEA; //PCA模塊0的捕捉/比較寄存器低8位。
sfr CCAP1L = 0xEB; //PCA模塊1的捕捉/比較寄存器低8位。
sfr CCAP2L = 0xEC; //PCA模塊2的捕捉/比較寄存器低8位。
sfr CH = 0xF9;
sfr CCAP0H = 0xFA; //PCA模塊0的捕捉/比較寄存器高8位。
sfr CCAP1H = 0xFB; //PCA模塊1的捕捉/比較寄存器高8位。
sfr CCAP2H = 0xFC; //PCA模塊2的捕捉/比較寄存器高8位。
sbit CCF0 = CCON^0; //PCA 模塊0中斷標志,由硬件置位,必須由軟件清0。
sbit CCF1 = CCON^1; //PCA 模塊1中斷標志,由硬件置位,必須由軟件清0。
sbit CCF2 = CCON^2; //PCA 模塊2中斷標志,由硬件置位,必須由軟件清0。
sbit CR = CCON^6; //1: 允許PCA計數器計數,0: 禁止計數。
sbit CF = CCON^7; //PCA計數器溢出(CH,CL由FFFFH變為0000H)標志。
//PCA計數器溢出后由硬件置位,必須由軟件清0。
sbit PPCA = IP^7; //PCA 中斷 優先級設定位
sfr P2M1 = 0x95; //P2M1.n,P2M0.n =00--->Standard, 01--->push-pull
sfr P2M0 = 0x96; // =10--->pure input, 11--->open drain
//================================================================
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;
u16 CCAP0_tmp,PWM0_high,PWM0_low;
u16 CCAP1_tmp,PWM1_high,PWM1_low;
u16 CCAP2_tmp,PWM2_high,PWM2_low;
u16 pwm0,pwm1,pwm2;
void PWMn_Update(u8 PCA_id, u16 pwm);
void PCA_Init(void);
void delay_ms(u8 ms);
/******************** 主函數 **************************/
void main(void)
{
PCA_Init(); //PCA初始化
EA = 1;
//P2M1 &= ~(0xe0); //P2.7 P2.6 P2.5 設置為推挽輸出
//P2M0 |= (0xe0);
while (1)
{
delay_ms(2);
if(++pwm0 >= PWM_HIGH_MAX-10)
{pwm0 = PWM_HIGH_MIN+10;PWMn_Update(PCA0,pwm0);delay_ms(255);delay_ms(255);}
PWMn_Update(PCA0,pwm0);
// if(++pwm1 >= PWM_HIGH_MAX) pwm1 = PWM_HIGH_MIN;
// PWMn_Update(PCA1,pwm1);
// if(++pwm2 >= PWM_HIGH_MAX) pwm2 = PWM_HIGH_MIN;
// PWMn_Update(PCA2,pwm2);
}
}
//========================================================================
// 函數: void delay_ms(u8 ms)
// 描述: 延時函數。
// 參數: ms,要延時的ms數, 這里只支持1~255ms. 自動適應主時鐘.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 備注:
//========================================================================
void delay_ms(u8 ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 13000;
while(--i) ;
}while(--ms);
}
//========================================================================
// 函數: void PWMn_SetHighReg(unsigned int high)
// 描述: 更新占空比數據。
// 參數: high: 占空比數據,即PWM輸出高電平的PCA時鐘脈沖個數。
// 返回: 無
// 版本: VER1.0
// 日期: 2013-5-15
// 備注:
//========================================================================
void PWMn_Update(u8 PCA_id, u16 pwm)
{
if(pwm > PWM_HIGH_MAX) pwm = PWM_HIGH_MAX; //如果寫入大于最大占空比數據,強制為最大占空比。
if(pwm < PWM_HIGH_MIN) pwm = PWM_HIGH_MIN; //如果寫入小于最小占空比數據,強制為最小占空比。
if(PCA_id == PCA0)
{
CR = 0; //停止PCA一會, 一般不會影響PWM。
PWM0_high = pwm; //數據在正確范圍,則裝入占空比寄存器。
PWM0_low = PWM_DUTY - pwm; //計算并保存PWM輸出低電平的PCA時鐘脈沖個數。
CR = 1; //啟動PCA。
}
else if(PCA_id == PCA1)
{
CR = 0; //停止PCA。
PWM1_high = pwm; //數據在正確范圍,則裝入占空比寄存器。
PWM1_low = PWM_DUTY - pwm; //計算并保存PWM輸出低電平的PCA時鐘脈沖個數。
CR = 1; //啟動PCA。
}
else if(PCA_id == PCA2)
{
CR = 0; //停止PCA。
PWM2_high = pwm; //數據在正確范圍,則裝入占空比寄存器。
PWM2_low = PWM_DUTY - pwm; //計算并保存PWM輸出低電平的PCA時鐘脈沖個數。
CR = 1; //啟動PCA。
}
}
|