用定時器1查詢延時和中斷延時都試過了,示波器上顯示的都是相位一樣的PWM波。求大神指點。 每路的相位差值是打算弄成(一個周期的時間/pwm路數)。
PWM波是直接用STC8A上pwm寄存器生成的代碼如下(這個生成pwm波應該沒有問題示波器上顯示是正確的):
void PWM_init(int pin,long f,int pwm) //PWM初始化函數
{
switch(pin%10)
{
case 0:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==10) PWM0CR=0x08;
if(pin==20) PWM0CR=0x00;
if(pin==60) PWM0CR=0x10;
PWM0_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數(精度)
PWMC = PWM0_T; //設置PWM周期時鐘數
PWM0T1= (long)pwm*PWM0_T/10000; //PWM0在計數值為15000地方輸出低電平
PWM0T2= 0; //PWM0在計數值為0地方輸出高電平
PWM0CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM0
}
case 1:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==11) PWM1CR=0x08;
if(pin==21) PWM1CR=0x00;
if(pin==61) PWM1CR=0x10;
PWM1_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數
PWMC = PWM1_T; //設置PWM周期時鐘數
PWM1T1= (long)pwm*PWM1_T/10000; //PWM1在計數值為100H地方輸出低電平
PWM1T2= 0; //PWM1在計數值為700H地方輸出高電平
PWM1CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM1
}
case 2:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==12) PWM2CR=0x08;
if(pin==22) PWM2CR=0x00;
if(pin==62) PWM2CR=0x10;
PWM2_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數
PWMC = PWM2_T; //設置PWM周期時鐘數
PWM2T1= (long)pwm*PWM2_T/10000; //PWM0在計數值為100H地方輸出低電平
PWM2T2= 0; //PWM0在計數值為700H地方輸出高電平
PWM2CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM0
}
case 3:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==13) PWM3CR=0x08;
if(pin==23) PWM3CR=0x00;
if(pin==63) PWM3CR=0x10;
PWM3_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數
PWMC = PWM3_T; //設置PWM周期時鐘數
PWM3T1= (long)pwm*PWM3_T/10000; //PWM0在計數值為100H地方輸出低電平
PWM3T2= 0; //PWM0在計數值為700H地方輸出高電平
PWM3CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM0
}
case 4:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==14) PWM4CR=0x08;
if(pin==24) PWM4CR=0x00;
if(pin==64) PWM4CR=0x10;
PWM4_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數
PWMC = PWM4_T; //設置PWM周期時鐘數
PWM4T1= (long)pwm*PWM4_T/10000; //PWM0在計數值為100H地方輸出低電平
PWM4T2= 0; //PWM0在計數值為700H地方輸出高電平
PWM4CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM0
}
case 5:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==15) PWM5CR=0x08;
if(pin==25) PWM5CR=0x00;
if(pin==65) PWM5CR=0x10;
PWM5_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數
PWMC = PWM0_T; //設置PWM周期時鐘數
PWM5T1= (long)pwm*PWM5_T/10000; //PWM0在計數值為100H地方輸出低電平
PWM5T2= 0; //PWM0在計數值為700H地方輸出高電平
PWM5CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM0
}
case 6:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==16) PWM6CR=0x08;
if(pin==26) PWM6CR=0x00;
if(pin==66) PWM6CR=0x10;
PWM6_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數
PWMC = PWM6_T; //設置PWM周期時鐘數
PWM6T1= (long)pwm*PWM6_T/10000; //PWM0在計數值為100H地方輸出低電平
PWM6T2= 0; //PWM0在計數值為700H地方輸出高電平
PWM6CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM0
}
case 7:
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
PWMCKS = 0x0f; // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。
PWMCFG = 0x00; //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
if(pin==17) PWM7CR=0x08;
if(pin==27) PWM7CR=0x00;
if(pin==67) PWM7CR=0x10;
PWM7_T = Main_Fosc16/f; //計算PWM一個周期總脈沖數
PWMC = PWM7_T; //設置PWM周期時鐘數
PWM7T1= (long)pwm*PWM7_T/10000; //PWM0在計數值為100H地方輸出低電平
PWM7T2= 0; //PWM0在計數值為700H地方輸出高電平
PWM7CR|=0x80; //使能PWM輸出
P_SW2 &= ~0x80; //PSW2寄存器最高位清0
PWMCR |= 0x80; //使能PWM波形發生器,PWM計數器開始工作
break; //PWM0
}
}
}void PWM_change(int pin,int pwm) //改變PWM模塊占空比
{
//STORE=P_SW2;
P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1
switch(pin%10)
{
case 0: PWM0T1= (long)pwm*PWM0_T/10000; //PWM0在計數值為100H地方輸出低電平
break;
case 1: PWM1T1= (long)pwm*PWM1_T/10000; //PWM1在計數值為100H地方輸出低電平
break;
case 2: PWM2T1= (long)pwm*PWM2_T/10000; //PWM2在計數值為100H地方輸出低電平
break;
case 3: PWM3T1= (long)pwm*PWM3_T/10000; //PWM3在計數值為100H地方輸出低電平
break;
case 4: PWM4T1= (long)pwm*PWM4_T/10000; //PWM4在計數值為100H地方輸出低電平
break;
case 5: PWM5T1= (long)pwm*PWM5_T/10000; //PWM5在計數值為100H地方輸出低電平
break;
case 6: PWM6T1= (long)pwm*PWM6_T/10000; //PWM6在計數值為100H地方輸出低電平
break;
case 7: PWM7T1= (long)pwm*PWM7_T/10000; //PWM7在計數值為100H地方輸出低電平
break;
}
P_SW2 &= ~0x80; //以上寄存器為擴展sfr,訪問后需將PSW2寄存器最高位置0
} |