历史上的今天
今天是:2025年01月12日(星期日)
2020年01月12日 | 基于51单片机产生占空比和频率可调的方波信号发生器
2020-01-12 来源:51hei
前段时间开始接触到单片机,以为单片机会很简单,但比我预想的要复杂一些,特别是刚开始接触的时候,需要下载各种软件,然后自己慢慢地去熟悉这些软件的操作。我是从51单片机开始入手,毕竟51单片机是最基本的了。正好这学期学习了波形的产生,就做一个基本的函数信号发生器吧。
这次实现的函数发生器是基于51单片机的占空比、频率可调的方波发生器,适用于AT89C51/52、STV89C51/52等,现在把具体过程给大家说说。
第1步:安装一个单片机仿真图软件,推荐使用Protues,这是一款专门用来仿真单片机的,功能十分强大。我用的是Protues8.6,下载安装步骤大家就自行查询了,学习起来比较简单,半小时就能掌握了。下面是我的仿真图形。
第2步:单片机仿真图形界限完成之后,就是写程序了,程序写好之后,需要下载Keil软件将程序转换为单片机能识别的机器语言,即hex文件,程序可以使是c语言,也可以是汇编语言。在Keil上运行程序没有错误后就会自动生成hex文件,Keil的使用大家自行查询。下面那个“单片机1111.hex”就是我们写好的程序转换为hex文件了,其他的是附加产物。
第3步:回到Protues仿真,双击单片机,就会弹出一个窗口,在Program File栏加入我们刚才产生的hex文件就可以了,然后点击运行就可以运行了。很多人仿真的时候可能没有示波器窗口,点击运行后,然后点击上方“调试”,再点击弹出窗口的最后一行,示波器窗口就弹出来了,就可以看到单片机产生的波形了。
下面是仿真波形图
(两张图的频率不一样,即频率可调)
(这两张图的占空比不一样,即占空比可调)
现在说说具体功能,一共有4个按键,初始频率为500Hz,第1个按键按下后频率增加500Hz,第2个按键按下后频率增加100Hz,当频率增加到最大值1MHz后重新定义为500Hz,即频率500~1MHz可变;初始占空比为50%,第3个按键按下后占空比增加10%,第4个按键按下后占空比增加1%,当占空增加到100%后就定义为0%,即占空比0%~100%可调。大家还可以稍微修改程序,实现频率和占空比在不同范围内可调。
源代码:
#include
#define uchar unsigned char
#define uint unsigned int
float fosc=12000000;
sbit KEY1=P1^0;
sbit KEY2=P1^1;
sbit KEY3=P1^2;
sbit KEY4=P1^3;
sbit OUTPUT=P2^0;
uchar zkb;
uint freq;
uchar TIMER0_L,TIMER0_H,TIMER1_L,TIMER1_H;
void delay(uchar n)
{
uchar i;
while(n--)
{for(i=255;i>0;i--)
{}
}}
void chushihua(void)
{
P1=0x0f;
freq=500;
zkb=50;
TIMER0_L=0xe0;
TIMER0_H=0xb1;
TIMER1_L=0xf0;
TIMER1_H=0xd8;
TL0=0xe0;
TH0=0xb1;
TL1=0xf0;
TH1=0xd8;
TMOD=0x11;
IT0=1;
EX0=1;
ET0=1;
ET1=1;
EA=1;
TR0=1;
TR1=1;
}
void main(void)
{
chushihua();
while(1)
{ }
}
void Timer0_freq() interrupt 1
{
TR1=1;
TL0=TIMER0_L;
TH0=TIMER0_H;
OUTPUT=1;
}
void Timer1_zkb() interrupt 3
{
TR1=0;
TL1=TIMER1_L;
TH1=TIMER1_H;
OUTPUT=0;
}
void keyscan() interrupt 0 using 1
{
float TF0,TZ1;
EX0=0;
delay(10);
if(P1!=0x0f)
{
if(KEY1==0) freq+=500;
if(KEY2==0) freq+=50;
if(freq>10000) freq=500;
if(KEY3==0) zkb+=10;
if(KEY4==0) zkb++;
if(zkb>100) zkb=1;
TF0=(65536-fosc/(12.0*freq));
TZ1=(65536-(fosc*zkb)/(12.0*100*freq));
TIMER0_H=(uint)TF0/256;
TIMER0_L=(uint)TF0%256;
TIMER1_H=(uint)TZ1/256;
TIMER1_L=(uint)TZ1%256;
}
P1=0x0f;
EX0=1;
TR0=1;
TR1=1;
}
史海拾趣
|
虽然不是我自己整理的,但是我是综合很多的相关资料整理的,发出来不为别的,只为养家糊口,大家看着有用的话就收藏吧! 算了 还是不卖了,来这的新手也不容易,大家实惠才是真的!… 查看全部问答> |
|
电池技术发展到今天,已经走过了铅 酸电池和镍镉电池时代。目前正处于镍氢电池和锂离子电池的绿色电池时代。镍氢电池VS锂电池,谁才是真命天子?周末了解一些动态,分享出来。 2009年6月25日,工信部出台的《新能源汽车生产企业及产品准入管理规则 ...… 查看全部问答> |
|
我用C8051F340单片机向串口发送送据 从0发到10 为什么到接收上显示会是 00 81 82 83 84 05 06 87 88 89 8A 我再发送一次 显示是 80 81 82 83 04 05 86 87 88 89 0A 在发送数据最高位的有1 和0 的变化 照理来说应该只能是0的 遇到这样问题 ...… 查看全部问答> |
|
是这样的,我最近在弄socket编程方面的东西。基uC/TCPIP 的,连接是建立好了,就是收发数据有问题:我将收发函数放在循环while(1)里面,发端开始一直发,发了一会就不发了,收端只能接收一次数据,第二次循环到recv时就卡死了…… 想 ...… 查看全部问答> |
|
#include unsigned char code tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char code digittab[10][8]={{0x00,0x00,0x3e,0x41,0x41,0x41,0x3e,0x00}, //0 ...… 查看全部问答> |
|
哪位大虾能发给我个串口通信的实例呀??最好用EVC写的。。感激涕零。\\ 我的邮箱6094189ye@163.com 我看到书上有CSerial 这个类,但STANDARDSDK下面没有这个类呀。。。???… 查看全部问答> |
|
我的是DELL1501本本,要实现纯DOS下使用串口(RS232)通信,在市场上买了个prolific USB转串口,不知是否可行?之前试过在DOS下可以使用USB鼠标,和读取USB软驱(B:)里的资料!… 查看全部问答> |
|
也是偶然看到一个节目,当初算是有炒作的因素在里面,是北大才子卖猪肉。好像是广州那边的,某人在九几年的时候从政府辞职下海,前后做过房地产、醋饮料等。让我感兴趣的是,当其瞅准猪肉市场时,带着自己手下千来口子,一齐转型。于是那些人一齐跨 ...… 查看全部问答> |
|
我的电脑是笔记本,现在要ISP烧程序,用了一个BUS转RS232的转接卡,主控芯片是PL-2303,晶振12M,BUS转RS232后 我设置为端口2; 现在我用的单片机STM32F103C8T6,在使用STMicroelectronics Flas ...… 查看全部问答> |
|
哪位高手能帮忙把下面按键扫描程序改成用定时器对按键进行定时扫描啊,我用的是51单片机,感激万分!!!!/*键盘扫描*/void judge(void){ P1=0xf0;lie=P1;lie=lie&0xf0;if(lie!=0xf0){delay();if(lie!=0xf0) //假设 ...… 查看全部问答> |




