基于51单片机的简单方波发生器
2017-11-12 20:41
141 查看
一个按键可以调整频率的简易方波信号发生器,当频率超出范围时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--);
}
#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--);
}
相关文章推荐
- 基于51单片机的简单交通灯程序
- 基于msp430单片机的方波发生器
- 基于51单片机的蓝牙小车手机端遥控的简单实现 (下篇)
- 用51单片机做信号发生器,同时输出四种频率的方波
- 最简单的基于FFmpeg的封装格式处理:视音频分离器(demuxer)
- 基于qml创建最简单的android机图像采集程序
- 基于服务器端缓存redis的简单实现
- 基于javamail简单实现邮件发送和相关问题的解决
- 最简单的基于FFmpeg的AVfilter例子(水印叠加)
- 51单片机教程(从原理开始基于汇编)
- [转载]通达信插件选股(基于通达信插件编程规范的简单分析)
- 基于Swing的简单应用(计算器)
- 基于TCP Socket的简单网络通信
- Spring简单配置-基于工厂模式装载bean
- 基于对话框的简单双缓冲绘图框架
- 基于PHP+MySQL实现简单留言板
- 中文TTS 的简单实现(基于linux)之 实现语音合成
- 50行代码实现的一个最简单的基于 DirectShow 的视频播放器
- 简单认识什么是基于Web Service的云端应用开发
- 基于Fundation框架的简单管理系统