文号
t35807
阅读
25571
回复
23
收藏
14
[原创]51单片机输出可调PWM信号
2011/08/22
IP:澳大利亚
上个月帮忙设计了一个线切割机的高频信号源,完成后感觉可以稍加改造后应用到数控电源的设计上,于是写了这篇贴子供大家参考研究。这个项目要求使用51单片机输出脉宽可调的脉冲信号,高低电平脉宽分别可调,脉宽值有5us、8us、10us、16us、32us、48us若干个档位。难点在于如何使用51的定时器产生满足精度的高低电平。51单片机使用24MHz的晶振,它的时钟周期就是0.5us,最极端的情况是要每隔10个时钟周期产生一次定时器中断。若只使用一个定时器,则在定时器中断函数中要判断当前是处于高电平还是低电平,还要重新设置定时器初装值,这些操作会使用较多的CPU时间,甚至会超过10个时钟周期,结果没有办法得到相应宽度的脉冲。简化定时器中断函数中的操作是唯一能解决这个问题的办法,最终我使用的方案是使用两个定时器分别控制高电平与低电平的时间。定时器0只负责将输出脚的电平拉高,定时器1只负责将输出脚的电平拉低,这样定时器中断函数都可以在1个时钟周期内完成操作。两个定时器都采用自动重装的方式工作,周期均为脉冲的周期,令定时器1后于定时器0一定时间工作,令这个时间差正好等于高电平的脉宽,两个定时器轮流工作,正好可以达到要求。(见图)
934_bea813139984020c235d6f0fff4b3.png


附设计原理图和源码
934_b2b813139985587722990038c3f2d.png



/*
* File:                main.h
* Author:                luodichen@126.com
* Date:                2011-07-23
*
* MCU:                    AT89C52            
*/

#include <reg52.h>
#include <intrins.h>
#include <string.h>

#define SCANSPEED(X) ((X)*2000)

#define KEYSCAN_DELAY_TIME         50
#define SIGNALWIDE_TYPE_NUM        5

#define OPERAT_MINUS         -1
#define OPERAT_PLUS            1
#define SET_LOWLEVAL        0
#define SET_HIGHLEVAL        1        

#define NUM_SHOW P0

#define FRESH_NUM_TIME            20000

typedef unsigned char BYTE;

sbit sbOutput = P1^7;

sbit sbP2_6 = P2^6;
sbit sbP2_7 = P2^7;

sbit sbControl = P1^6;

void TimerInit();
void SystemInit();
void NumScan(BYTE *buf);
void delay(unsigned long t);
void ShowWelcome();
void BeginToWork();
void SetSignalSource(BYTE time_l, BYTE time_h);
void UpdateBitsOut();
void KeysScan();
void ShowData();
void SetBitsOut(char operat);
void SetSignalOut(char opeart, BYTE type);




[/i]
+1
学术分
虎哥
2011/08/22
赞扬您的作品。为什么用51方案,是系统可靠性有要求吗
23
ldc作者
15年4个月前IP:未同步
317800
1楼
捕获2.png
高电平8us,低电平10us,挺准确的~
+1
科创币
jrcsh
2011/08/22
不错不错
+10
科创币
delete
2011/08/22
引用
评论
ldc作者
15年4个月前IP:未同步
317898
6楼
回 4楼(kokming999) 的帖子
Proteus[10字节10字节]
引用
评论
ldc作者
15年4个月前IP:未同步
317955
10楼
回 9楼(虎哥) 的帖子
虎哥还记得俺俺表示无限感动啊[s:241]
图里的是GQL,目前考研奋斗中...
引用
评论
ldc作者
15年4个月前IP:未同步
318621
20楼
回 19楼(神之觉醒) 的帖子
使用定时器的好处是可以充分利用CPU资源。不用定时器的话勉强可以达到要求的精度,但是必须不使用中断,键盘扫描、显示等其它功能函数也必须仔细地设计。因为不能合理有效地利用CPU资源,输出脉宽是不可能达到几微秒这个数量级的。
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的