兩個頭文件 main.c #include <REG51.H> #include <intrins.h> #define U8 unsigned char #define U16 unsigned int void DelayMs(U8 ms); void PWM_clock(U8 clock); void PWM_start(U8 module,U8 mode); ////////////////////// 延時子程序///////////////////////////// void DelayMs(U8 ms) //在11.0592M晶振下,stc10f系列(單周期指令)的ms級延時 { U16 i; while(ms--) { for(i = 0; i < 850; i++); } } ////////////////////主函數入口//////////////////////////// sfr CCON = 0xD8; //PCA控制寄存器 sfr CMOD = 0xD9; //PCA模式寄存器 sfr CCAPM0 = 0xDA; //PCA模塊0模式寄存器 //模塊0對應P1.3/CEX0/PCA0/PWM0(STC12C5A60S2系列) sfr CCAPM1 = 0xDB; //PCA模塊1模式寄存器 //模塊1對應P1.4/CEX1/PCA1/PWM1(STC12C5A60S2系列) sfr CL = 0xE9; //PCA 定時寄存器 低位 sfr CH = 0xF9; //PCA 定時寄存器 高位 sfr CCAP0L = 0xEA; //PCA模塊0的 捕獲寄存器 低位 sfr CCAP0H = 0xFA; //PCA模塊0的 捕獲寄存器 高位 sfr CCAP1L = 0xEB; //PCA模塊1的 捕獲寄存器 低位 sfr CCAP1H = 0xFB; //PCA模塊1的 捕獲寄存器 高位 sfr PCA_PWM0 = 0xF2; //PCA PWM 模式輔助寄存器0 sfr PCA_PWM1 = 0xF3; //PCA PWM 模式輔助寄存器1 sbit CF = 0xDF; //PCA計數溢出標志位 sbit CR = 0xDE; //PCA計數器 運行控制位 sbit CCF1 = 0xD9; //PCA模塊1中斷標志 sbit CCF0 = 0xD8; //PCA模塊0中斷標志 //* CCAPOH = CCAPOL = 0XC0; //模塊0輸出 占空因數為25% //* CCAPOH = CCAPOL = 0X80; //模塊0輸出 占空因數為50% //* CCAPOH = CCAPOL = 0X40; //模塊0輸出 占空因數為75% void PWM_clock(U8 clock); void PWM_start(U8 module,U8 mode); void PWM_clock(U8 clock) { CMOD |= (clock<<1); CL = 0x00; CH = 0x00; } void PWM_start(U8 module,U8 mode,U8 zkb) { CCAP0L = 0XC0; CCAP0H = 0XC0; //模塊0初始輸出 占空因數為25% CCAP1L = 0XC0; CCAP1H = 0XC0; //模塊1初始輸出 占空因數為25% if(module==0) { switch(mode) { case 0: CCAPM0 = 0X42;break; //模塊0設置為8位PWM輸出,無中斷 case 1: CCAPM0 = 0X53;break; //模塊0設置為8位PWM輸出,下降沿產生中斷 case 2: CCAPM0 = 0X63;break; //模塊0設置為8位PWM輸出,上升沿產生中斷 case 3: CCAPM0 = 0X73;break; //模塊0設置為8位PWM輸出,跳變沿產生中斷 default: break; } } else if(module==1) { switch(mode) { case 0: CCAPM1 = 0X42;break; //模塊1設置為8位PWM輸出,無中斷 case 1: CCAPM1 = 0X53;break; //模塊1設置為8位PWM輸出,下降沿產生中斷 case 2: CCAPM1 = 0X63;break; //模塊1設置為8位PWM輸出,上升沿產生中斷 case 3: CCAPM1 = 0X73;break; //模塊1設置為8位PWM輸出,跳變沿產生中斷 default: break; } } else if(module==2) { switch(mode) { case 0: CCAPM0 = CCAPM1 = 0X42;break; //模塊0和1設置為8位PWM輸出,無中斷 case 1: CCAPM0 = CCAPM1 = 0X53;break; //模塊0和1設置為8位PWM輸出,下降沿產生中斷 case 2: CCAPM0 = CCAPM1 = 0X63;break; //模塊0和1設置為8位PWM輸出,上升沿產生中斷 case 3: CCAPM0 = CCAPM1 = 0X73;break; //模塊0和1設置為8位PWM輸出,跳變沿產生中斷 default: break; } } CR=1; //PCA計數器開始計數 } void PCA_Intrrpt(void) interrupt 7 { if(CCF0) CCF0=0; if(CCF1) CCF1=0; //軟件清零 if(CF) CF=0; //軟件清零 } void main() { TMOD|=0x02; /* timer 0 mode 2: 8-Bit reload */ TH0=0xff; TR0=1; PWM_clock(2); // PCA/PWM時鐘源為 定時器0的溢出 PWM_start(0,0); // 模塊0,設置為PWM輸出,無中斷,初始占空因素為25% DelayMs(250); IT0=1; //下降沿觸發 EX0=1; //開中斷0 EA=1; //開總中斷 while(1); //等待中斷產生,按下S15按鍵產生中斷信號 } #include "reg51.h" #define uchar unsigned char #define uint unsigned int sbit di=P3^7; uchar jishu=0x00; //用來記錄中斷的次數 void delay(uchar z) { uchar i; for(i=0;i<z;i++); } //##################################### //外部中斷0子函數 void PWM_Select(void) interrupt 0 { U8 mod jishu++; //中斷一次加1 mod=jishu%3; switch(mod) { case 0: CCAPM0 = 0X42;break; //0設置為25%PWM輸出 case 1: CCAPM0 = 0X53;break; //0設置為50%PWM輸出 case 2: CCAPM0 = 0X63;break; //0設置為75%PWM輸出 default: break; } delay(255); }