找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2372|回复: 0
打印 上一主题 下一主题
收起左侧

基于ATC51的新型数控直流电源设计

[复制链接]
跳转到指定楼层
楼主
  摘要:针对目前的电源普遍存在输出恒定、精度较差的问题,设计了一种基于单片机的新型数控直流电源。主要分为电源模块,单片机控制模块,数码管、按键模块和PWM波输出驱动模块这4部分。首先通过键盘输入预期的电压值,单片机根据输入值输出不同占空比的PWM波,控制可控稳压芯片LM317的输出,输出结果在数码管上显示。在整个系统中,由专门的电源稳压模块提供稳定电压以减小误差。输出电压范围为0.00~15.00V,电流范围0.1 A,误差不超过5%,具有使用灵活、精度高、工作稳定,成本低的优点,适宜推广使用。

    在各种电子设备中,电源是一种必不可少的仪器。随着科技的进步,电子设备逐渐综合化,复杂化,对电源部分使用的灵活性和精度都提出了更高的要求。
    目前所用的电源大多是只有固定电压输出(例如常用的有:±5 V、±12 V或±15 V),其缺点是输出电压不可人为地改变,输出精度和稳定性都不高;在测量上,传统的电源一般采用指针式或数字式来显示电压或电流,搭配电位器调整所要的电压及电流输出值。若要调整精确的电压输出,须搭配精确的显示仪表监测;又因电位器的阻值特性非线性,在调整时,需要花费一定的时间,而且会产生漂移。市场上销售的数字可调电源成本较高,使用也不方便。
    针对这一现象,本文提出了一种基于AT98C51单片机的新型数控直流电源。
    键盘输入控制输出电压值,数码管显示输出电压值。输出电压范围0.00~15.00 V,电流范围0~1 A,输出电压的精度为百分位,误差小于0.5%。具有使用灵活,精度高,工作稳定,成本低的优点,适宜推广使用。

1 硬件电路组成及工作原理
1.1 系统硬件结构
    系统硬件结构如图1所示。系统分为电源模块,单片机控制模块,数码管、按键模块和PWM波输出驱动模块4部分组成。电源模块主要由外接不可控电源和二级滤波电路组成PI型滤波电路;单片机控制模块主要由AT98C51单片机及其外围电路组成;数码管、按键模块包括数码管显示部分和键盘输入部分;PWM波输出驱动模块主要由稳压芯片LM317,三极管及其配套电路组成。本数控直流电源通过按键控制单片机产生PWM信号驱动级(三极管)的线性放大,来控制稳压芯片LM317的ADJ控制端口,通过调节其占空比对电容进行充放电实现能量转换,从而调节输出电压,最后通过数码管显示。各部分的电源由电源模块提供的稳压输出提供。本系统还可以通过串行口实现上位计算机和数字电源之间的通讯,人机交互图形用户界面(GUI)可以是设计人员按照计算机屏幕上的指示的步骤,通过选择参数来对电源电压,电流阀值与响应,软启动,容限,环路补偿的功能的管理工作,也可以通过按键来设定。

1.2 电源模块
    电源模块是通过外部输入20 V的不可控电压输入,经过稳压管系统提供电源保证。LM78012是12 V的稳压芯片,输出12 V的稳定电压,提供给输出驱动模块LM317的输入级。LM7805是5 V的稳压芯片,提供稳定的5 V电压,提供给单片机的电压输入端。VD2为二极管串入,起保护作用,防止输入反极性时烧毁电路芯片。C9,C5,C12n,C6,C7,C3为滤波电容,阻值如图2所示,组成PI型二阶滤波电路,消除电源纹波的干扰影响。

1.3 单片机控制系统
    本系统采用Atmel公司生产的AT98C51单片机。它是一种低电压、低功耗、高性能的CMOS 8位单片机,片内含8 kB可反复擦写的程序存储器和256 B的数据存储器。单片机及其必要的外围电路,包括复位电路和晶振电路如图3所示。
    本系统使用AT98C51自带的PWM模块,通过内部定时器,采用脉宽调制技术。P1.0~P1.2作为输入端,输入3位按键控制量,P2.0~P2.7作为输出端,输出8位数码管信号,由P1.6口输出不同占空比的方波。这样将输入的外界光强的变化转化为输出的PWM波的占空比的变化。
1.4 数码管,按键模块
    数码管显示模块:LED驱动显示用的是共阴极的4位显示数码管(MY5841AH),外带8位上拉电阻(510 R),提高贯穿电流,用于显示电源输出的电压幅度值,便于人机交互。

    按键模块:用于外界输入设定电源初值与调节输出使用。S3为电压增加按钮,每按一下输出电压值增加0.01 V;S4为电压减小按钮,每按一下输出电压减小0.01 V;S5为备用按键。
1.5 PWM驱动输出模块
    PWM为脉宽调制技术,不同的占空比来控制目标的动态变化,通常在线性调节、输出调节、电压调整以及电机控制方面都有很大的应用。如图5所示,此模块为电源核心模块。R5为上拉电阻,R1为限流电阻,为三极管基极提供稳定的PWM波型,起到稳定PWM输出的作用。风将三极管集电极输出的放大电流转化为电压,同时与高精度可控稳压芯片LM317的控制端ADJ和电容C10相接。通过对电容C10进行充放电实现能量转换,控制输出可调ADJ调节端口,即达到通过调节PWM波占空比来控制输出电压的目的。

    PWM波占空比的改变,即改变稳压回路的三极管的导通时间及导通状态。以占空比从50%~100%的增加来举例说明。当占空比增加,三极管在一个周期内导通时间减少,C10充放电频率加快,放电时间减小,控制端输入电流增大,输出电压增大。本电源设定占空比范围即为50%~100%。
    调节R6可以调节输入控制电压最高值的大小与最小值的范围。C8与C10均作为滤波电容,滤除高噪声,R8与R4为分压电阻,用于配合R6来校正输出值。其大小根据不同使用要求而定。

2 系统软件设计
    系统的主要任务是根据按键的输入值,通过单片机控制输出PWM波占空比的改变,控制三极管的导通时间和导通状态,进而达到控制可控稳压芯片LM317输出电压的目的。系统软件设计的重点在于单片机的编程。系统主程序流程如图6所示。

    单片机编程主要包括初始化程序,键盘处理程序,外部中断程序和PWM波输出程序等。初始化包括硬件的初始化和定时器的初始化;键盘处理程序主要包括键盘扫描和防抖动;外部中断程序起保护电路的作用;产生PWM波采用中断延时配合循环指令。
    系统工作流程为:单片机上电复位,初始化系统内部定时器寄存器,固定输出的PWM管脚,系统按键值,通过内部定时器定时产生定器最小的中断时间,通过按键扫描程序检测需要输出的电压值和变量累加到达输出不同要求的占空比的方波,以控制稳压芯片控制管脚,并通过LED显示扫描程序显示实际输出电压值。
    其中有以下两点需要注意:
    1)键盘在定时中断服务程序中读取,用中断间隔时间实现键盘去抖动,不必编写另外的延时程序,提高CPU的效率。键盘值存入数据缓冲区,在主程序中读数据缓冲区的内容。
    2)外部中断为高优先级中断,编制子程序实现电源过流,短路保护时,要充分考虑到电源启动瞬间会产生数倍于额定电流的冲击电流,大约会持续3~5 ms,应在软件上采取措施,避免短路和电源开启的误判。确定电源过流、短路后,切断电源输出。间隔一段时间后,试接通电源开关,当发现过流、短路信号已消除,则恢复电源的输出,否则电源开关仍然保持断开。
    核心程序代码:
    中断函数产生PWM程序
   

3 测试数据分析
    在实验室环境下,对该电源进行功能测试和误差分析。在输出范围1~15 V内共测试16组数据,平均间隔值为1 V。首先通过键盘输入预期值,同时记录输出显示值,再进行记录对比。数据如表1所示。由表1可见,在测试范围内输出误差在5%之内,在中间段误差相对较大。


4 结束语
    本文设计了一种基于ATC51的新型高精度数控直流电源以解决传统数控直流电源价格昂贵,误差较大的问题。本电源通过键盘输入值控制单片机输出不同占空比的PWM波,进而控制可控稳压芯片LM317的输出。在整个系统中,由专门的电源稳压模块提供稳定电压以减小误差。输出电压范围为0.00~15.00 V,电流范围0~1 A,误差不超过5%,具有使用灵活,精度高,工作稳定,成本低的优点,适宜推广使用。

单片机源程序如下:
  1. #include <reg52.h>                        //通用52单片机头文件
  2. #define uchar unsigned char                                 
  3. sbit RESET=P3^3;                   //DA转换数值复位端口位定义
  4. sbit keyup=P3^4;                   //步进加端口位定义
  5. sbit keydown=P3^5;                   //步进减端口位定义
  6. sbit LEDwei1=P2^7;                   //低位数码管位选
  7. sbit LEDwei2=P2^6;                   //高位数码管位选
  8. #define duan P0            //段选宏定义  
  9. void delay(int);                   //延时函数声明
  10. void display(uchar);           //显示函数声明
  11. uchar code LEDcode[]={0xc0,0xf9,0xa4,0xb0,0x99,
  12.                                       0x92,0x82,0xF8,0x80,0x90,0x8e};       //共阳数码管0-9和F(为段选所用)
  13. uchar code byte[]={ 0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,        0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,
  14.                                        
  15.                                         0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,        0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,
  16.                                        
  17.                                         0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,        0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,
  18.                                        
  19.                                         0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,        0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,
  20.                                        
  21.                                         0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,        0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,
  22.                                        
  23.                                         0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,        0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,
  24.                                        
  25.                                         0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,        0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,
  26.                                        
  27.                                         0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,        0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe,
  28.                                        
  29.                                         };//DA转换数据

  30. uchar code table[]={0x11,0x12,15,16,17,18,20,21,22,23, 24,25,27,28,29,30,31,32,34,35,
  31.                                         36,37,38,39,41,42,43,44,45,47, 48,49,50,51,52,53,55,56,57,58,
  32.                                         59,61,62,63,64,65,66,68,69,70, 71,72,73,75,76,77,78,79,80,82,
  33.                                         83,84,85,86,87,89,90,91,92,93, 94,96,97,98,99};        //用于显示电压值的数组

  34. void main()
  35. {
  36.         uchar num=0;         
  37.         while(1)
  38.         {
  39.                          if(keyup==0)                 //步进加端口为低电平,
  40.                         {        
  41.                                 delay(10);                  //稍作延时,消抖,
  42.                                 if(keyup==0)          //步进加端口依然为低电平,说明的确是被按下,
  43.                                 {        
  44.                                         if(num==128)  //执行电压DA转换数值步进增加一
  45.                                         num=0;
  46.                                         else
  47.                                         num++;
  48.                                 }
  49.                                 while(keyup==0);        //防止按死语句
  50.                          }
  51.                  if(keydown==0)                                 //步进减端口为低电平,
  52.                          {
  53.                                  delay(10);                         //稍作延时,消抖,
  54.                                 if(keydown==0)                 //步进减端口依然为低电平,说明的确是被按下,
  55.                                 {        
  56.                                         if(num==0)                  //执行电压DA转换数值步进减一
  57.                                         num=128;
  58.                                         else
  59.                                         num--;
  60.                                 }
  61.                                 while(keydown==0);          //防止按死语句
  62.                          }
  63.                  if(RESET==0)                                  // 复位端口为低电平
  64.                          {
  65.                                  delay(10);                          //稍作延时,消抖,
  66.                                 if(RESET==0)                  //复位端口依然为低电平,说明的确是被按下,
  67.                                 {        
  68.                                         num=0;                          //执行复位操作
  69.                                 }
  70.                                 while(RESET==0);           //防止按死语句
  71.                          }
  72.         
  73.                  P1=byte[num];           //给DA一个数值,转化成相应的电压值
  74.                  delay(10);
  75.                  display(num);           //调用显示函数显示电压值
  76.          }
  77. }

  78. void delay(int x)                   //12M晶振,约1ms延时函数
  79. {
  80.         int i;
  81.         for(;x>0;x--)
  82.         for(i=0;i<123;i++)
  83.                 ;
  84. }
  85. void display(uchar num)              //显示函数
  86. {        uchar temp;
  87.         temp=table[num];
  88.         if(num<75)                //电压值小于10V的可以直接在数码管上显示出来
  89.         {
  90.              duan=LEDcode[temp/10]&0x7f;        //显示个位,并加显小数点
  91.                  LEDwei1=1;
  92.                  delay(5);
  93.                  LEDwei1=0;
  94.                  duan=LEDcode[temp%10];;          //显示小数点后一位
  95.                  LEDwei2=1;
  96.                  delay(5);
  97.                  LEDwei2=0;
  98.         }
  99.         else               //电压值大于10V的在数码管上显示字母"FF"
  100.         {                                          
  101.                  duan=LEDcode[10];            //显示高位
  102.                  LEDwei1=1;
  103.                  delay(5);
  104.                  LEDwei1=0;
  105.                  duan=LEDcode[10];            //显示低位
  106.                  LEDwei2=1;
  107.                  delay(5);
  108.                  LEDwei2=0;
  109.         }
  110. }                                            
复制代码

所有资料51hei提供下载:
wenya.zip (27.04 KB, 下载次数: 28)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表