找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机数控恒流源(电路原理图讲解+程序代码)

  [复制链接]
跳转到指定楼层
楼主
电路原理图如下:


该项设计的主要目的是设计一种数控稳压电源。它利用单片机STC89C51作为主控芯片,控制数字/模拟转换器(TLC5615)的输出电压的大小,经过运算放大器LM358与IRF9Z24N构成负反馈系统,从而输出恒定电压。最后通过电位器分压将输出信号反馈到运算放大器LM358上,使输出准确度可以调节。此设计通过键盘电路与单片机连接,读入控制数据,利用软件进行判断,从而起到控制电源输出的作用。通过LCD1602(或LED数码管)显示数控电源的输出电压,实现简单的人机对话。该项设计具有设计简单,控制灵活,调节方便,携带方便、成本低等优势,具有较强的实用性。

下图是为了了解整个电路如何工作的,把整个电路拆开。
二、原理讲解:
供电部分:
P2为接线柱,是整个系统的输入电压端口,整个数控电源有此输入能量。D1、D2、D3、D4为四个二极管(in4007),起整流的作用,C6为滤波电容。整流滤波电路是使供电可以为交流,同时也可以用直流供电(交流供电不要超过20V,直流不要超过35V)。受电压限制的主要是后级运放耐压、TL431耐压以及7812的耐压值。7812主要为保护7805,7805稳出5V电压共单片机供电使用。但是7805耐压值是15V,所以前级要加7812保护7805。
晶振部分:
C2、C3、Y1(12MHZ)与单片机端口构成震荡电路,为51单片机提供时钟。
复位电路:
RST连接单片机复位管脚,此电路及有上电复位功能,又有手动复位功能。C1、R2构成上电复位电路,上电瞬间C1导通,则RST为高电平,单片机将复位,电压稳定后C1储存的电能通过R2对地释放掉,单片机将正常运行。同样K2按下时RST为高电平,单片机复位,弹起来时RST为低电平,单片机正常运行.
单片机部分:
单片机默认选用STC89C51,同时兼容STC89C52、AT89S52、AT89S51、AT89C51等51单片机。
按键部分:
按键选用独立按键,扫描时间短,使程序更简单且扫描时间更短,从而提高稳定性。按键弹起时P20、P21、P22、P23为弱上拉状态,所以为高电平。按键按下时对应的I/O口为低电平,可以被程序中的扫描函数检测到。

数码管显示部分:
数码管显示采用四位一体共阳数码管,这样使电路更为简单,只需四个9012三极管就可以将其驱动。P24、P25、P26、P27分别作为数码管的位选端,控制是否选通哪一位数码管。采用PNP型三极管,低电平导通,高电平截止。R20、R30、R40、R50为三极管基极限流电阻,此电阻及能保护三极管又能保证三极管导通时处于完全导通状态。R51为限流电阻,此电阻的大小直接决定数码管的亮暗成都,在此选择220欧姆、1/4色环电阻。数码管的阴极端直接接单片机的P0口,而不需上拉电阻。STC89C51的单片机P0口为漏极开路,所以作为输出时必须接上拉电路,而作为输入时相当于数码管作为上拉,所以不再需要上拉电阻,及简化了电路又节省了成本。
数模转换部分:(此为数控电压数控调压关键所在)
数模转换采用德州仪器的TLC5615,此为一片10位串行单5V电源DAC,直接电压输出。单片机P33、P32、P34分别连接TLC5615的时钟端、片选端、数据端即可控制它输出想要的电压。此时TLC5615的6脚及参考电压输入端需接入2.5V的参考电压。根据公式可知,当参考电压为2.5V时,TLC5615将最大输出5V电压。
TL5615(DAC)电压计算公式

Vout为7脚输出电压,Vrefin为6脚参考电压输入端,N为单片机通过1、2、3管脚向TLC5615写入的数据,1024是根据这是一片10位数模转换而计算出来的(210=1024),最后乘以二是因为TLC5615内部有2倍的增益放大器。
在给TLC输入2.5V参考电压的时候,我们用了TL431芯片。TL431是可控精密稳压源。它的输出电压用两个电阻就可以任意的设置到从Verf(2.5V)到36V范围内的任何值。该器件的典型动态阻抗为0.2Ω,在很多应用中用它代替稳压二极管。
同时用LM358作为跟随器,减小2.5V基准电源的阻抗,再送入TLC5615 参考电压端。
(写论文时,可以在此讲解TL41技术参数LM358技术参数和原理和跟随器电路原理)
TLC5615内部原理图:
                         TLC5615逻辑时序图:



在给TLC输入2.5V参考电压的时候,我们用了TL431芯片。TL431是可控精密稳压源。它的输出电压用两个电阻就可以任意的设置到从Verf(2.5V)到36V范围内的任何值。该器件的典型动态阻抗为0.2Ω,在很多应用中用它代替稳压二极管。
同时用OPA2107作为跟随器,减小2.5V基准电源的阻抗,再送入TLC5615 参考电压端。
(写论文时,可以在此讲解TL41技术参数OPA2107技术参数和原理和跟随器电路原理)
MOS放大部分:
将上述TLC5615输出的可调电压送到运放LM358的反相端,通过MOS管(F9Z24N)放大。同时在F9Z24N的输出端用RW1(10K)电位器分压,取一定比例的输出电压反馈到比较器正相端,构成一个反馈系统。此时MOS管输出的PWM波的占空比将根据负载和输入电压而变化以保证输出电压的稳定。C5作为输出滤波电容,滤掉输出电压纹波。
根据反馈系统的稳定原理计算出输出电压的公式,如下:
设:Vo为输出电压,Vin为LM358的2脚输入电压,RWH为电位器上部分电阻,RWL为电位器下部分电阻,RW为电位器阻值。
Vo=Vin×(RW/RWL);
(写论文时,可以在此讲解F9Z24N技术参数)
报警电路:
此电路可以由单片机控制三极管(8550/9012)的通断来控制蜂鸣器的报警。当P36为高时,三极管不高通,为低时三极管导通蜂鸣器响。当过流或短路时,单片机切断输出,同时蜂鸣器报名。

单片机源程序如下:
  1. #include "reg52.h"                        //包含头文件

  2. //宏定义
  3. #define uchar unsigned char
  4. #define uint  unsigned int

  5. //按键定义
  6. sbit KEY1= P2^0;
  7. sbit KEY2= P2^1;
  8. sbit KEY3= P2^2;
  9. sbit KEY4= P2^3;

  10. //数码管位选端定义
  11. sbit W1= P2^4;
  12. sbit W2= P2^5;
  13. sbit W3= P2^6;
  14. sbit W4= P2^7;

  15. //DAC定义
  16. sbit  CS_5615=P1^5;                 //定义片选信号IO口
  17. sbit CLK_5615=P1^6;                 //定义时钟信号IO口
  18. sbit DAT_5615=P1^7;                 //定义数据输入IO口

  19. //ADC定义
  20. sbit  CS=P3^5;                         //定义片选信号IO口
  21. sbit CLK=P3^3;                       //定义时钟信号IO口
  22. sbit DIO=P3^4;                                   //定义数据输入IO口

  23. uint  U;
  24. uchar GETU=0;
  25. bit flag=0;

  26. uchar code table[]=
  27. {
  28.         0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7
  29. };        //共阳数码管段码表        没有小数点 0~9
  30. uchar code table1[]=
  31. {
  32.         0x7F,0x64,0xBD,0xF5,0xE6,0xF3,0xFB,0x67,0xFF,0xF7,0x5e
  33. };//带小数点的编码            0~9


  34. void delay_ms(uint z)                          //延时函数
  35. {
  36.   uint a,b;
  37.   for(a=z;a>0;a--)
  38.    for(b=5;b>0;b--);
  39. }

  40. void  shuma(uint buf)                          //数码管显示程序
  41. {
  42.         uchar a,b,c,d;                                  //定义变量
  43.         a=buf/1000;                                          //将数据除以1000得到千位数据
  44.         b=buf%1000/100;                                  //取余1000除以100得到百位数据
  45.         c=buf%100/10;                                  //得到十位数据
  46.         d=buf%10;                                          //得到个位数据

  47.         W1=0;W2=1;W3=1;W4=1;                  //选中第一个位
  48.         P0=~table[a];                                  //输入该位要显示的数据
  49.         delay_ms(60);                                  //延时

  50.         W1=1;W2=0;W3=1;W4=1;                  //选中第二个位
  51.         P0=~table1[b];                                  //注释同上
  52.         delay_ms(60);

  53.         W1=1;W2=1;W3=0;W4=1;
  54.         P0=~table[c];
  55.         delay_ms(60);

  56.         W1=1;W2=1;W3=1;W4=0;
  57.         P0=~table1[10];
  58.         delay_ms(60);
  59.         W1=1;W2=1;W3=1;W4=1;
  60. }

  61. void tlc_5615(uint buf)                         //DA输出
  62. {
  63.         uint a,c;                                         //定义变量
  64.         c=buf;                                             //要输出的数据赋值
  65.     CS_5615=0;                                          //引脚拉低
  66.         for(a=16;a>0;a--)                         //循环16次
  67.         {
  68.          DAT_5615=c>>15;               //把数据串行输入进da芯片(把数据右移15位得到最高位数据,赋值给数据脚)
  69.          c=c<<1;                                 //将数据左移一位,下次循环时就是传输第二位数据了
  70.          CLK_5615=1;                         //拉高
  71.          CLK_5615=0;                 //拉低
  72.     }
  73.         CLK_5615=1;
  74.         CLK_5615=0;
  75.         CLK_5615=1;
  76.         CLK_5615=0;
  77.         CS_5615=1;
  78. }

  79. unsigned int  A_D()
  80. {
  81.         unsigned char i,dat;
  82.         CS=1;   //一个转换周期开始
  83.         CLK=0;  //为第一个脉冲作准备
  84.         CS=0;  //CS置0,片选有效
  85.         
  86.         DIO=1;    //DIO置1,规定的起始信号  
  87.         CLK=1;   //第一个脉冲
  88.         CLK=0;   //第一个脉冲的下降沿,此前DIO必须是高电平
  89.         DIO=1;   //DIO置1, 通道选择信号  
  90.         CLK=1;   //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
  91.         CLK=0;   //第二个脉冲下降沿
  92.         DIO=0;   //DI置0,选择通道0
  93.         CLK=1;    //第三个脉冲
  94.         CLK=0;    //第三个脉冲下降沿
  95.         DIO=1;    //第三个脉冲下沉之后,输入端DIO失去作用,应置1
  96.         CLK=1;    //第四个脉冲
  97.         for(i=0;i<8;i++)  //高位在前
  98.         {
  99.                 CLK=1;         //第四个脉冲
  100.                 CLK=0;
  101.                 dat<<=1;       //将下面储存的低位数据向右移
  102.                 dat|=(unsigned char)DIO;          //将输出数据DIO通过或运算储存在dat最低位
  103.         }                                 
  104.         CS=1;          //片选无效
  105.         return dat;         //将读出的数据返回     
  106. }


  107. //主函数
  108. void main(void)
  109. {
  110.         U=0;                                           //电压值显示0
  111.         while(1)                                   //进入循环
  112.         {
  113.                 tlc_5615(U);                   //输出电压值
  114.                 shuma(U/8*10);                   //显示电压值
  115.                 if(flag==0)                           //没有短路
  116.                 {
  117.                         if(KEY1==0)                   //按键1按下
  118.                         {
  119.                                 shuma(U/8*10);
  120.                                 shuma(U/8*10);
  121.                                 shuma(U/8*10);
  122.                                 shuma(U/8*10);
  123.                                 shuma(U/8*10);        //此处调用显示函数就是延时去抖的作用
  124.                                 if(KEY1==0)                //再次判断按键按下
  125.                                 {
  126.                                         if(U<960)        //1V对应的是80  10位ad(10位ad最大数据是1024,这里为了取整数,选择80对应1V,也就是8对应0.1V,因为电压调节的变化一共有120种)
  127.                                         U=U+8;                //电压加0.1V
  128.                                 }        
  129.                         }
  130.                         if(KEY2==0)                        //按键2按下
  131.                         {
  132.                                 shuma(U/8*10);
  133.                                 shuma(U/8*10);
  134.                                 shuma(U/8*10);
  135.                                 shuma(U/8*10);
  136.                                 shuma(U/8*10);
  137.                                 if(KEY2==0)
  138.                                 {
  139.                                         if(U>=8)   //电压减
  140.                                         U=U-8;
  141.                                 }        
  142.                         }                        
  143.                         if(KEY3==0)                                //按键3按下
  144.                         {
  145.                                 shuma(U/8*10);
  146.                                 shuma(U/8*10);
  147.                                 shuma(U/8*10);
  148.                                 shuma(U/8*10);
  149.                                 shuma(U/8*10);
  150.                                 if(KEY3==0)
  151.                                 {
  152.                                         U=400;                          //输出5V电压
  153.                                 }        
  154.                         }        
  155.                         if(KEY4==0)                                   //按键4按下
  156.                         {
  157.                                 shuma(U/8*10);
  158.                                 shuma(U/8*10);
  159.                                 shuma(U/8*10);
  160.                                 shuma(U/8*10);
  161.                                 shuma(U/8*10);
  162.                                 if(KEY4==0)
  163.                                 {
  164.                                         U=0;                           //关闭输出
  165.                                 }        
  166.                         }
  167.                 }
  168.                 GETU=A_D();                          //读取ad数据
  169.                 if(GETU>=12)   //0.0196V,采样电阻采集到的电压数据
  170.                 {
  171.                         U=0;                 //关闭输出
  172.                         flag=1;                 //短路标志位
  173.                 }                                
  174.         }
  175. }
复制代码

以上程序51hei提供下载:
C程序注释.zip (43.94 KB, 下载次数: 144)
原理图.pdf (222.22 KB, 下载次数: 134)
重点:电路原理讲解.doc (791.5 KB, 下载次数: 129)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:1 发表于 2019-7-25 18:39 | 只看该作者
本帖需要重新编辑补全图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

板凳
ID:544367 发表于 2019-7-26 09:10 | 只看该作者
admin 发表于 2019-7-25 18:39
本帖需要重新编辑补全图片即可获得100+黑币(帖子下方有编辑按钮)

我是截图不能粘贴,所以上传了一个Word文档,里面有详解
回复

使用道具 举报

地板
ID:591254 发表于 2019-7-31 09:39 | 只看该作者
芯片选择stc89c52的不行吗
回复

使用道具 举报

5#
ID:449126 发表于 2019-12-16 21:32 | 只看该作者
你这个是个恒压源吧,不是恒流源
回复

使用道具 举报

6#
ID:101394 发表于 2020-2-15 09:02 | 只看该作者
下载来研究一下
回复

使用道具 举报

7#
ID:688987 发表于 2020-3-17 09:00 | 只看该作者
这个楼主全面吗
回复

使用道具 举报

8#
ID:731970 发表于 2020-6-6 17:45 | 只看该作者
采样电阻选择那么大,这样出来的恒流源电流会很小啊
回复

使用道具 举报

9#
ID:323651 发表于 2020-6-7 09:46 | 只看该作者
学习下,谢谢分享
回复

使用道具 举报

10#
ID:763621 发表于 2020-6-7 10:31 | 只看该作者

学习下,谢谢分享
回复

使用道具 举报

11#
ID:765652 发表于 2020-6-9 21:21 | 只看该作者
请问没有仿真文件和原理图文件吗
回复

使用道具 举报

12#
ID:56960 发表于 2020-7-8 13:47 | 只看该作者
路过顶起,这个可以制作来玩玩,电源是经常用到的
回复

使用道具 举报

13#
ID:95778 发表于 2021-1-3 00:03 | 只看该作者
其实实际LM358驱动 MOSFET并不理想 发热十分严重,理论上358 反相输入 输出的是 矩形波 但是用示波器测试是一个类似于正弦波,用12V供电时  358输出的 电压大概是3-6V 由于MOSFET不是工作在开关状态导致发热严重.
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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