上个月帮忙设计了一个线切割机的高频信号源,完成后感觉可以稍加改造后应用到数控电源的设计上,于是写了这篇贴子供大家参考研究。这个项目要求使用51单片机输出脉宽可调的脉冲信号,高低电平脉宽分别可调,脉宽值有5us、8us、10us、16us、32us、48us若干个档位。难点在于如何使用51的定时器产生满足精度的高低电平。51单片机使用24MHz的晶振,它的时钟周期就是0.5us,最极端的情况是要每隔10个时钟周期产生一次定时器中断。若只使用一个定时器,则在定时器中断函数中要判断当前是处于高电平还是低电平,还要重新设置定时器初装值,这些操作会使用较多的CPU时间,甚至会超过10个时钟周期,结果没有办法得到相应宽度的脉冲。简化定时器中断函数中的操作是唯一能解决这个问题的办法,最终我使用的方案是使用两个定时器分别控制高电平与低电平的时间。定时器0只负责将输出脚的电平拉高,定时器1只负责将输出脚的电平拉低,这样定时器中断函数都可以在1个时钟周期内完成操作。两个定时器都采用自动重装的方式工作,周期均为脉冲的周期,令定时器1后于定时器0一定时间工作,令这个时间差正好等于高电平的脉宽,两个定时器轮流工作,正好可以达到要求。(见图)
附设计原理图和源码
/*
* File: main.h
* Author: luodichen@XXXXXXX * 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]
200字以内,仅用于支线交流,主线讨论请采用回复功能。