只是一個(gè)PWM控制LED燈的小程序。我對(duì)于C語言的定時(shí)器修正值判斷不清楚,這里的修正值13, 不知道從哪里開始數(shù)機(jī)械周期的 #include <reg52.h> sbit PWMOUT = P0^0; sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4; unsigned char HReloadH = 0; //高電平重載值的高字節(jié) unsigned char HReloadL = 0; //高電平重載值的低字節(jié) unsigned char LReloadH = 0; //低電平重載值的高字節(jié) unsigned char LReloadL = 0; //低電平重載值的低字節(jié) void ConfigPWM(unsigned int fr, unsigned char dc); void ClosePWM(); void main () { unsigned int i; P0 = 0xFF; //P0口初始化 ADDR0 = 0; //選擇獨(dú)立LED ADDR1 = 1; ADDR2 = 1; ADDR3 = 1; ENLED = 0; //LED總使能 EA = 1; //開總中斷
while(1) { ConfigPWM(100, 10); //頻率100Hz,占空比10% for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(100, 40); //頻率100Hz,占空比40% for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(100, 90); //頻率100Hz,占空比90% for (i=0; i<40000; i++); ClosePWM(); for (i=0; i<40000; i++); } } void ConfigPWM(unsigned int fr, unsigned char dc) //PWM配置函數(shù),fr-頻率,dc-占空比 { unsigned int high, low; unsigned long tmp;
tmp = (11059200 / 12) / fr; //計(jì)算一個(gè)周期所需的計(jì)數(shù)值 high = (tmp * dc) / 100; //計(jì)算高電平所需的計(jì)數(shù)值 low = tmp - high; //計(jì)算低電平所需的計(jì)數(shù)值 high = 65536 - high + 13; //計(jì)算高電平的定時(shí)器重載值并修正 low = 65536 - low + 13; //計(jì)算低電平的定時(shí)器重載值并修正
HReloadH = (unsigned char)(high >> 8); //高電平重載值拆分為高低字節(jié) HReloadL = (unsigned char)high; LReloadH = (unsigned char)(low >> 8); //低電平重載值拆分為高低字節(jié) LReloadL = (unsigned char)low;
TMOD &= 0xF0; //清零T0的控制位 TMOD |= 0x01; //配置T0為模式1 TH0 = HReloadH; //加載T0重載值 TL0 = HReloadL; ET0 = 1; //使能T0中斷 TR0 = 1; //啟動(dòng)T0 PWMOUT = 1; //輸出高電平 } void ClosePWM() //關(guān)閉PWM { TR0 = 0; //停止定時(shí)器 ET0 = 0; PWMOUT = 1; //輸出高電平 } void InterruptTimer0() interrupt 1 //T0中斷服務(wù)函數(shù) { if (PWMOUT == 1) //當(dāng)前輸出為高電平時(shí),裝載低電平值并輸出低電平 { TH0 = LReloadH; TL0 = LReloadL; PWMOUT = 0; } else //當(dāng)前輸出為低電平時(shí),裝載高電平值并輸出高電平 { TH0 = HReloadH; TL0 = HReloadL; PWMOUT = 1; }
|