1339|0

3836

帖子

19

TA的资源

纯净的硅(中级)

楼主
 

基于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--);
}
 

 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表