此例程設(shè)置了按鍵可以調(diào)整100-1000hz的不同頻率(100的倍數(shù))的方波,另外還加入了串口通信,可以通過串口發(fā)送來的數(shù)字來設(shè)置相對應(yīng)的頻率;
#include
#include"uart.h"
sbit PWMOUT = P1^0;
sbit led = P2^2;
sbit KEY1 = P1^2;
sbit KEY2 = P3^3;
unsigned char HighRH = 0; //高電平重載值的高字節(jié)
unsigned char HighRL = 0; //高電平重載值的低字節(jié)
unsigned char LowRH = 0; //低電平重載值的高字節(jié)
unsigned char LowRL = 0; //低電平重載值的低字節(jié)
unsigned int fr;
unsigned int k=0,t,i;
unsigned int s= 100;
unsigned char a[3];
unsigned int b=0;
void ConfigPWM(unsigned int fr, unsigned char dc);
void ConfigUART(unsigned int baud);
void delay(unsigned int n){ while (n--);}
void main()
{
bit backup1 = 1;
bit backup2 = 1;
bit keybuf1 = 1; //按鍵值暫存,臨時保存按鍵的掃描值
bit keybuf2 = 1; //按鍵值暫存,臨時保存按鍵的掃描值
//keybuf1 = KEY1; //把當前掃描值暫存
EA=1;
led = 0;
ConfigUART(9600); //配置波特率為9600
ConfigPWM(100,50);
//Timer1Init();
while (1)
{
if(k==1)
{
k=0;
ConfigPWM(s,50);
led = ~led;delay(2000);
}
keybuf1 = KEY1; //把當前掃描值暫存
if (keybuf1 != backup1) //當前值與前次值不相等說明此時按鍵有動作
{
delay(1000); //延時大約10ms
if (keybuf1 == KEY1) //判斷掃描值有沒有發(fā)生改變,即按鍵抖動
{
if (backup1 == 0) //如果前次值為0,則說明當前是彈起動作
{
s = s-50;
}
backup1 = keybuf1; //更新備份為當前值,以備進行下次比較
}
ConfigPWM(s,50);
}
keybuf2 = KEY2; //把當前掃描值暫存
if (keybuf2 != backup2) //當前值與前次值不相等說明此時按鍵有動作
{
delay(1000); //延時大約10ms
if (keybuf2 == KEY2) //判斷掃描值有沒有發(fā)生改變,即按鍵抖動
{
if (backup2 == 0) //如果前次值為0,則說明當前是彈起動作
{
s = s+50;
}
backup2 = keybuf2; //更新備份為當前值,以備進行下次比較
}
ConfigPWM(s,50);
}
}
}
void ConfigUART(unsigned int baud)
{
SCON = 0x50; //配置串口為模式1
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1為模式2
TH1 = 256 - (11059200/12/32)/baud; //計算T1重載值
TL1 = TH1; //初值等于重載值
ET1 = 0; //中斷T1
ES = 1; //串口中斷
TR1 = 1; //啟動T1
}
void ConfigPWM(unsigned int fr, unsigned char dc)
{
unsigned int high, low;
unsigned long tmp;
tmp = (11059200/12)/fr; //計算一個周期所需的計數(shù)值
high = (tmp*dc) / 100; //計算高電平所需的計數(shù)值
low = tmp - high; //計算低電平所需的計數(shù)值
high = 65536 - high + 12; //計算高電平的重載值并補償中斷延時
low = 65536 - low + 12; //計算低電平的重載值并補償中斷延時
HighRH = (unsigned char)(high>>8); //高電平重載值拆分為高低字節(jié)
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low>>8); //低電平重載值拆分為高低字節(jié)
LowRL = (unsigned char)low;
TMOD &= 0xF0; //清零 T0 的控制位
TMOD |= 0x01; //配置 T0 為模式 1
TH0 = HighRH; //加載 T0 重載值
TL0 = HighRL;
ET0 = 1; //使能 T0 中斷
TR0 = 1; //啟動 T0
PWMOUT = 1; //輸出高電平
}
void InterruptTimer0() interrupt 1
{
if (PWMOUT == 1) //當前輸出為高電平時,裝載低電平值并輸出低電平
{
TH0 = LowRH;
TL0 = LowRL;
PWMOUT = 0;
}
else //當前輸出為低電平時,裝載高電平值并輸出高電平
{
TH0 = HighRH;
TL0 = HighRL;
PWMOUT = 1;
}
}
/*void Timer1Init()
{
TMOD|=0X10;//選擇為定時器1模式,工作方式1,僅用TR1打開啟動。
TH1=0XFC; //給定時器賦初值,定時1ms
TL1=0X18;
ET1=1;//打開定時器1中斷允許
EA=1;//打開總中斷
TR1=1;//打開定時器
}
void Timer1() interrupt 3
{
static u16;
TH1=0XFC; //給定時器賦初值,定時1ms
TL1=0X18;
i++;
if(i==1000)
{
i=0;
t++;
if(t%2==0)
{
SBUF=t/10;
SBUF=t%10;
}
}
}*/
void ComINT() interrupt 4 //中斷接收程序
{
if(RI) //判斷是否接收完,接收完成后,由硬件置RI位
{
RI=0;
//SBUF=SBUF;
a[b]=SBUF;
b++;
if(b==3)
{
/*if(a[0]=='a'&&a[1]=='b'&&a[2]=='c')
{led = 0;delay(2000);}
else
{led = 1;}*/
b=0;s=(a[0]-0x30)*100+(a[1]-0x30)*10+(a[2]-0x30);
k=1;
//SBUF = 'T';
}
}
if(TI)
{
TI=0;
}
}