基于51单片机的简单方波发生器

2019-04-15 12:46发布

一个按键可以调整频率的简易方波信号发生器,当频率超出范围时LED亮,频率范围是100-1000hz。 #include sbit PWMOUT = P1^0; sbit LED1 = P2^3; sbit LED2 = P2^2; sbit LED3 = P2^1; sbit LED4 = P2^0; sbit KEY1 = P3^2; sbit KEY2 = P3^3; unsigned char HighRH = 0; //高电平重载值的高字节 unsigned char HighRL = 0; //高电平重载值的低字节 unsigned char LowRH = 0; //低电平重载值的高字节 unsigned char LowRL = 0; //低电平重载值的低字节 void ConfigPWM(unsigned int fr, unsigned char dc); void ClosePWM(); void delay(); void main() { unsigned int i; bit backup1 = 1; bit backup2 = 1; bit keybuf1 = 1; //按键值暂存,临时保存按键的扫描值 bit keybuf2 = 1; //按键值暂存,临时保存按键的扫描值 unsigned int a=100; EA=1; while (1) { keybuf1 = KEY1; //把当前扫描值暂存 if (keybuf1 != backup1) //当前值与前次值不相等说明此时按键有动作 { delay(); //延时大约10ms if (keybuf1 == KEY1) //判断扫描值有没有发生改变,即按键抖动 { if (backup1 == 0) //如果前次值为0,则说明当前是弹起动作 { a = a-10; } backup1 = keybuf1; //更新备份为当前值,以备进行下次比较 } } keybuf2 = KEY2; //把当前扫描值暂存 if (keybuf2 != backup2) //当前值与前次值不相等说明此时按键有动作 { delay(); //延时大约10ms if (keybuf2 == KEY2) //判断扫描值有没有发生改变,即按键抖动 { if (backup2 == 0) //如果前次值为0,则说明当前是弹起动作 { a = a+10; } backup2 = keybuf2; //更新备份为当前值,以备进行下次比较 } } ConfigPWM(a, 50); for (i=0; i<40000; i++); ClosePWM(); if ((a <= 50)||(a >= 150)) { LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 0; } else { LED1 = 1; LED2 = 1; LED3 = 1; LED4 = 1; } } } /* 配置并启动PWM,fr-频率,dc-占空比 */ 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; //输出高电平 } /* 关闭PWM */ void ClosePWM() { TR0 = 0; //停止定时器 ET0 = 0; //禁止中断 PWMOUT = 1; //输出高电平 } /* T0中断服务函数,产生PWM输出 */ void InterruptTimer0() interrupt 1 { if (PWMOUT == 1) //当前输出为高电平时,装载低电平值并输出低电平 { TH0 = LowRH; TL0 = LowRL; PWMOUT = 0; } else //当前输出为低电平时,装载高电平值并输出高电平 { TH0 = HighRH; TL0 = HighRL; PWMOUT = 1; } } /* 软件延时函数,延时约10ms */ void delay() { unsigned int j = 1000; while (j--); }