此例程设置了按键可以调整100-1000hz的不同频率(100的倍数)的方波,另外还加入了串口通信,可以通过串口发送来的数字来设置相对应的频率;
#include <reg52.h> #include"uart.h" sbit PWMOUT = P1^0; sbit led = P2^2; sbit KEY1 = P1^2; sbit KEY2 = P3^3; unsigned char HighRH = 0; //高电平重载值的高字节 unsigned char HighRL = 0; //高电平重载值的低字节 unsigned char LowRH = 0; //低电平重载值的高字节 unsigned char LowRL = 0; //低电平重载值的低字节 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) //判断扫描值有没有发生改变,即按键抖动 { if (backup1 == 0) //如果前次值为0,则说明当前是弹起动作 { s = s-50; } backup1 = keybuf1; //更新备份为当前值,以备进行下次比较 } ConfigPWM(s,50); } keybuf2 = KEY2; //把当前扫描值暂存 if (keybuf2 != backup2) //当前值与前次值不相等说明此时按键有动作 { delay(1000); //延时大约10ms if (keybuf2 == KEY2) //判断扫描值有没有发生改变,即按键抖动 { 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; //计算一个周期所需的计数值 high = (tmp*dc) / 100; //计算高电平所需的计数值 low = tmp - high; //计算低电平所需的计数值 high = 65536 - high + 12; //计算高电平的重载值并补偿中断延时 low = 65536 - low + 12; //计算低电平的重载值并补偿中断延时 HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节 HighRL = (unsigned char)high; LowRH = (unsigned char)(low>>8); //低电平重载值拆分为高低字节 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; } }