這個問題困擾我三天了,剛開始在考慮怎樣做,結果很快程序完成,不幸的是程序在脈寬調寬是竟然是尖峰波,斷續,后多次調試未果,后來跟蹤time0變量,也正常,原來是在中斷時位對立即采樣寄存器清零造成,程序判斷錯誤,而誤動作!在修改變量time0是結束加兩條請立即采樣寄存器,一切變得如此簡單,加油!PWM是很有用的!
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit p1_0=P0^0;
sbit p2_0=P2^0;//加鍵
sbit p2_1=P2^1;//減鍵
uint t=100; //周期
uint time0; // 低電平可按鍵調整量
uint time1; // 高點平基準量
uint timeing0;//立即低電平動態變量
uint timeing1; //立即高電平動態變量
void delay(uint z) //延時程序
{
uint x,a,b;
for (x=0;x<z;x++)
{
for(b=120;b>0;b--)
{
for(a=3;a>0;a--);
}
}
}
void keyball()//{按鍵修改定時數據,實現實時PWM調制
if(p2_0==0)
{
delay(3);
if(p2_0==0)
{
if(time0>1)
{
time0--;
time1=(t-time0);
timeing0=0;
timeing1=0;
}
}
}
//
*********************已上是減低電平************一下是加低電平******************if(p2_1==0)
{
delay(3);
if(p2_1==0)
{
if(time0<100)
{
time0++;
time1=(t-time0);
timeing0=0;
timeing1=0; //太關鍵了!這一步,因為不加的話,當再一次的time0被修改時timeing0,和timeing1不為0
// 所以才會發生錯誤,表現為波形時斷時續,而且有尖鋒脈沖,這都是沒有在刷新TIME0的同時刷新tineing的后果
// 沒想到很簡單的一點事竟差點PWM做不出來!真是有有教訓了
// 2010年10月7日晚8:34分與天津開發區第四項目部宿舍1
}
}
}
}
void InitTimer0(void) //10us
{
TMOD = 0x01;
TH0 =0xff;
TL0 =0xf7;
EA = 1;
ET0 = 1;
TR0 = 1;
p1_0=1;
}
void main(void)//主函數
{ P2=0x0f;
InitTimer0(); //10 us time0=10;(根據不同的精準度和頻率要求)
time1=10;
while(1)
{
keyball();
P3=time0;
}
}
void Timer0Interrupt(void) interrupt 1
{
if(time0==timeing0)
{
if(time1!=timeing1)
{
TH0 =0xff;
TL0 =0xf7;
p1_0=1;
timeing1++;
}
//中斷函數(定時器參量修改)
}
else
if(time0!=timeing0)
{
TH0 =0xff;
TL0 =0xf7;
p1_0=0;
timeing0++;
}
if(time0==timeing0)
{
if(time1==timeing1)
{
timeing0=0;
timeing1=0;
}
}
}
|