#include <reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;//數據類型重定義
uint8 count = 0; //計進入外部中斷次數
bit flag = 1; //捕獲結束標志位
long Pwm_All; //PWM的周期
long Pwm_High; //PWM的高電平時間 占空比=Pwm_High/Pwm_All
void delay(long i)
{
while(i--);
}
void Interrupt_Init()
{
/*定時器1為工作模式1 16位計數器 由TR1直接啟動
定時器0為工作模式1 16位計數器 由GATE和TR0共同啟動*/
TMOD = 0x19;
TH1 = 0;
TL1 = 0;
TH0 = 0;
TL0 = 0;
IT0 = 1;//下降沿觸發
IT1 = 1;
//TR0 = 1; //GATE高電平啟動
EX0 = 1;
EA = 1;
}
void main()
{
uint16 Pwm_percentage; //PWM占空比
Interrupt_Init();
LCD1602_Initialize( );
LCD1602_PrintString(1,1,"ALL:");
LCD1602_PrintString(1,10,"us");
LCD1602_PrintString(2,1,"HIGH:");
LCD1602_PrintString(2,11,"us");
while(1)
{
if(flag)
{
Pwm_percentage = Pwm_High*1000 / Pwm_All;
LCD1602_PrintChar(1,12,0x30+Pwm_percentage/100);
LCD1602_PrintChar(1,13,0x30+Pwm_percentage%100/10);
LCD1602_PrintChar(1,14,'.');
LCD1602_PrintChar(1,15,0x30+Pwm_percentage%10);
LCD1602_PrintChar(1,16,'%');
LCD1602_PrintChar(1,5,0x30+Pwm_All/10000);
LCD1602_PrintChar(1,6,0x30+Pwm_All%10000/1000);
LCD1602_PrintChar(1,7,0x30+Pwm_All%1000/100);
LCD1602_PrintChar(1,8,0x30+Pwm_All%100/10);
LCD1602_PrintChar(1,9,0x30+Pwm_All%10);
LCD1602_PrintChar(2,6,0x30+Pwm_High/10000);
LCD1602_PrintChar(2,7,0x30+Pwm_High%10000/1000);
LCD1602_PrintChar(2,8,0x30+Pwm_High%1000/100);
LCD1602_PrintChar(2,9,0x30+Pwm_High%100/10);
LCD1602_PrintChar(2,10,0x30+Pwm_High%10);
flag = 0; //計算完一次清零
}
delay(70000);
}
}
void EXTI0 () interrupt 0
{
count++;
if(count == 1) //第一次下降沿,啟動定時器1
{
TR1 = 1;
TR0 = 1;
}
if(count == 2) //第二次下降沿,一整個周期完畢
{
EX0 = 0; //關閉外部中斷,防止被其他打斷計算
TR1 = 0; //周期停止計數
TR0 = 0; //高電平時間停止計數
Pwm_All = TH1; //獲取數據
Pwm_All = (Pwm_All<<8)+TL1;
Pwm_High = TH0;
Pwm_High = (Pwm_High<<8)+TL0;
TH1 = 0; //清零為下一次做準備
TL1 = 0;
TH0 = 0;
TL0 = 0;
count = 0;
flag = 1;
EX0 = 1; //開啟下一次計算
TR1 = 0;
TR0 = 0;
}
}
|