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

一个按键可以调整频率的简易方波信号发生器,当频率超出范围时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--);
}


  • 14
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值