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

来源:互联网 发布:淘宝神器返利是真的吗 编辑:程序博客网 时间:2024/06/05 05:29

一个按键可以调整频率的简易方波信号发生器,当频率超出范围时LED亮,频率范围是100-1000hz。

#include <reg52.h>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--);}