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