标题: 单片机+LM2596数控稳压电源源程序 [打印本页]

作者: 51hei小林    时间: 2016-10-11 20:16
标题: 单片机+LM2596数控稳压电源源程序
主要器件:

使用LCD1602显示
电源可调模块用到LM2596
模数转换ADC0832

主要功能:
理论电压范围 1.25V~40V
电压、电流显示
短路保护电路

资料下载:
LM2596 数控电源.rar (2.1 KB, 下载次数: 771)


源程序:
  1. #include"reg52.h"
  2. #include<stdio.h>
  3. #include <intrins.h>

  4. typedef  unsigned char uchar;
  5. typedef  unsigned int uint;


  6. #define LCD_Data P0
  7. #define Busy    0x80 //用于检测LCD状态字中的Busy标识

  8. sbit ADC0832_CLK = P1^5;
  9. sbit ADC0832_DODI = P1^6;
  10. sbit ADC0832_CS = P1^7;

  11. sbit LCD_RS=P2^7;//定义引脚
  12. sbit LCD_RW=P2^6;
  13. sbit LCD_E=P2^5;

  14. float volts,amps;

  15. //5ms延时
  16. void Delay5Ms(void)
  17. {
  18.     unsigned int TempCyc = 5552;
  19.     while(TempCyc--);
  20. }

  21. //400ms延时
  22. void Delay400Ms(void)
  23. {
  24.     unsigned char TempCycA = 5;
  25.     unsigned int TempCycB;
  26.     while(TempCycA--)
  27.     {
  28.         TempCycB=7269;
  29.         while(TempCycB--);
  30.     };
  31. }

  32. //读状态
  33. unsigned char ReadStatusLCD(void)
  34. {
  35.     LCD_Data = 0xFF;
  36.     LCD_RS = 0;
  37.     LCD_RW = 1;
  38.     LCD_E = 0;
  39.     LCD_E = 0;
  40.     LCD_E = 1;
  41.     while (LCD_Data & Busy); //检测忙信号
  42.     return(LCD_Data);
  43. }

  44. //写数据
  45. void WriteDataLCD(unsigned char WDLCD)
  46. {
  47.     ReadStatusLCD(); //检测忙
  48.     LCD_Data = WDLCD;
  49.     LCD_RS = 1;
  50.     LCD_RW = 0;
  51.     LCD_E = 0; //若晶振速度太高可以在这后加小的延时
  52.     LCD_E = 0; //延时
  53.     LCD_E = 1;
  54. }

  55. //写指令
  56. void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测
  57. {
  58.     if (BuysC) ReadStatusLCD(); //根据需要检测忙
  59.     LCD_Data = WCLCD;
  60.     LCD_RS = 0;
  61.     LCD_RW = 0;
  62.     LCD_E = 0;
  63.     LCD_E = 0;
  64.     LCD_E = 1;
  65. }

  66. //读数据
  67. unsigned char ReadDataLCD(void)
  68. {
  69.     LCD_RS = 1;
  70.     LCD_RW = 1;
  71.     LCD_E = 0;
  72.     LCD_E = 0;
  73.     LCD_E = 1;
  74.     return(LCD_Data);
  75. }

  76. void LCDInit(void) //LCM初始化
  77. {
  78.     LCD_Data = 0;
  79.     WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号
  80.     Delay5Ms();
  81.     WriteCommandLCD(0x38,0);
  82.     Delay5Ms();
  83.     WriteCommandLCD(0x38,0);
  84.     Delay5Ms();
  85.    
  86.     WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号
  87.     WriteCommandLCD(0x08,1); //关闭显示
  88.     WriteCommandLCD(0x01,1); //显示清屏
  89.     WriteCommandLCD(0x06,1); // 显示光标移动设置
  90.     WriteCommandLCD(0x0C,1); // 显示开及光标设置
  91. }

  92. //按指定位置显示一个字符
  93. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  94. {
  95.     Y &= 0x1;
  96.     X &= 0xF; //限制X不能大于15,Y不能大于1
  97.     if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  98.     X |= 0x80; // 算出指令码
  99.     WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码
  100.     WriteDataLCD(DData);
  101. }

  102. //按指定位置显示一串字符
  103. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  104. {
  105.     unsigned char ListLength;
  106.    
  107.     ListLength = 0;
  108.     Y &= 0x1;
  109.     X &= 0xF; //限制X不能大于15,Y不能大于1
  110.     while (DData[ListLength]>=0x20) //若到达字串尾则退出
  111.     {
  112.         if (X <= 0xF) //X坐标应小于0xF
  113.      {
  114.             DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  115.             ListLength++;
  116.          X++;
  117.      }
  118.     }
  119. }

  120. //读取ADC0832转换值函数
  121. //入口函数:channel选择通道
  122. uchar ADC0832_Read(uchar channel)
  123. {
  124.     uchar i = 0;   
  125.     uchar tmp = 0;  //高字节数据
  126.     uchar tmp1 = 0; //低字节数据

  127.    
  128.     //开始标志位
  129.     ADC0832_DODI = 1;
  130.     _nop_();  _nop_();

  131.     ADC0832_CS = 0;     //片选信号  

  132.     ADC0832_CLK = 1;
  133.     _nop_();  _nop_();
  134.     ADC0832_CLK = 0;
  135.     _nop_();  _nop_();

  136.     //选择通道
  137.     switch(channel)
  138.     {
  139.         case 0:     //通道0
  140.             ADC0832_DODI = 1;   //SGL = 1;
  141.             _nop_();  _nop_();
  142.             ADC0832_CLK = 1;
  143.             _nop_();  _nop_();
  144.             ADC0832_CLK = 0;
  145.             _nop_();  _nop_();

  146.             ADC0832_DODI = 0;   //ODD = 0;
  147.             _nop_();  _nop_();
  148.             ADC0832_CLK = 1;
  149.             _nop_();  _nop_();
  150.             ADC0832_CLK = 0;
  151.             _nop_();  _nop_();
  152.             break;

  153.         case 1:     //通道1
  154.             ADC0832_DODI = 1;   //SGL = 1;
  155.             _nop_();  _nop_();
  156.             ADC0832_CLK = 1;
  157.             _nop_();  _nop_();
  158.             ADC0832_CLK = 0;
  159.             _nop_();  _nop_();

  160.             ADC0832_DODI = 1;   //ODD = 1;
  161.             _nop_();  _nop_();
  162.             ADC0832_CLK = 1;
  163.             _nop_();  _nop_();
  164.             ADC0832_CLK = 0;
  165.             _nop_();  _nop_();
  166.             break;
  167.          
  168.         default:
  169.             break;   
  170.     }

  171.     ADC0832_DODI = 1;
  172.     _nop_();  _nop_();

  173.     //读取8位转换数值
  174.     for(i=0;i<8;i++)
  175.     {
  176.         ADC0832_CLK = 1;
  177.         _nop_();  _nop_();
  178.         ADC0832_CLK = 0;
  179.         _nop_();  _nop_();

  180.         if(ADC0832_DODI)
  181.         {
  182.             tmp |= 0x01;   
  183.         }
  184.         else
  185.         {
  186.             tmp &= 0xfe;
  187.         }
  188.         if(i<7)
  189.         {
  190.             tmp <<= 1;
  191.         }         
  192.     }

  193.     tmp1 =  tmp & 0x01;
  194.     tmp1 <<= 6;

  195.     for(i=0;i<7;i++)
  196.     {
  197.         ADC0832_CLK = 1;
  198.         _nop_();  _nop_();
  199.         ADC0832_CLK = 0;
  200.         _nop_();  _nop_();

  201.         if(ADC0832_DODI)
  202.         {
  203.             tmp1 |= 0x80;
  204.         }
  205.         else
  206.         {
  207.             tmp1 &= 0x7f;
  208.         }
  209.         if(i<6)
  210.         {
  211.             tmp1 >>= 1;
  212.         }   
  213.     }

  214.     ADC0832_CS = 1;

  215.     if(tmp == tmp1) //当高字节与低字节相同时,该值有效
  216.     {
  217.         return tmp; //返回数值
  218.     }
  219. }

  220. void DisPlayValue(uint volts,uint amps)
  221. {
  222.     DisplayOneChar(0,0,'U');
  223.     DisplayOneChar(1,0,'=');
  224.     if(volts/10000 == 0)
  225.     {
  226.         DisplayOneChar(2,0,'0' + (volts/1000%10));
  227.         DisplayOneChar(3,0,'.');
  228.         DisplayOneChar(4,0,'0' + (volts/100%10));
  229.         DisplayOneChar(5,0,'0' + (volts/10%10));
  230.         DisplayOneChar(6,0,'0' + (volts%10));
  231.         DisplayOneChar(7,0,' ');
  232.         DisplayOneChar(8,0,'V');
  233.         DisplayOneChar(9,0,' ');
  234.     }
  235.     else
  236.     {
  237.         DisplayOneChar(2,0,'0' + (volts/10000));
  238.         DisplayOneChar(3,0,'0' + (volts/1000%10));
  239.         DisplayOneChar(4,0,'.');
  240.         DisplayOneChar(5,0,'0' + (volts/100%10));
  241.         DisplayOneChar(6,0,'0' + (volts/10%10));
  242.         DisplayOneChar(7,0,'0' + (volts%10));
  243.         DisplayOneChar(8,0,' ');
  244.         DisplayOneChar(9,0,'V');
  245.     }
  246.      
  247.     DisplayOneChar(0,1,'I');
  248.     DisplayOneChar(1,1,'=');
  249.     DisplayOneChar(2,1,'0' + (amps/1000));
  250.     DisplayOneChar(3,1,'.');
  251.     DisplayOneChar(4,1,'0' + (amps/100%10));
  252.     DisplayOneChar(5,1,'0' + (amps/10%10));
  253.     DisplayOneChar(6,1,'0' + (amps/1%10));
  254.     DisplayOneChar(7,1,' ');
  255.     DisplayOneChar(8,1,'A');         
  256. }

  257. void GetValue(void)
  258. {
  259.     uchar tmp,i;
  260.     uint ntmp;

  261.     for(i=0;i<10;i++)
  262.     {
  263.         tmp = ADC0832_Read(0);
  264.         ntmp += tmp;
  265.     }

  266.     volts = (ntmp/10)*0.1137*1000;
  267.     Delay5Ms();
  268.     ntmp = 0;

  269.     for(i=0;i<20;i++)
  270.     {
  271.         tmp = ADC0832_Read(1);
  272.         ntmp += tmp;
  273.     }

  274.     amps = (ntmp/20)*0.0196*1000;
  275.     Delay5Ms();

  276.     DisPlayValue(volts,amps);

  277. }

  278. void main(void)
  279. {
  280.     Delay400Ms(); //启动等待,等LCD讲入工作状态
  281.     LCDInit(); //LCM初始化
  282.     Delay5Ms(); //延时片刻(可不要)

  283.     ReadDataLCD();//测试用句无意义

  284.     while(1)
  285.     {
  286.         GetValue();
  287.     }
  288. }
复制代码



作者: bb24242424    时间: 2016-10-12 16:31
没原理图?
作者: 小白吕    时间: 2016-10-12 21:34
没原理图?

作者: shuijingyuice    时间: 2016-10-19 11:59
不错 学习学习
作者: Jodelin    时间: 2016-11-3 18:48
为什么我的币总是不够的?
作者: 5swords    时间: 2016-12-20 13:33
原理图在此http://www.51hei.com/bbs/dpj-56592-1.html
作者: 随易而安    时间: 2016-12-20 16:17
51黑有你更精彩
作者: 山东临沂    时间: 2016-12-21 16:04
正需要啊。学习中
作者: 说过的挺好    时间: 2016-12-21 22:26
挺好哒~~~
作者: xiaoer    时间: 2016-12-22 07:58
前一段时间购买了XL4016,做大功率数控电源,原理同上,
作者: 龙少11    时间: 2017-1-25 09:27
一直在寻找这个,终于找到了 ,下载学习中...........
作者: 13373092669    时间: 2017-4-5 22:04
怎么不能生成HEX
作者: Chandler1983    时间: 2017-4-6 13:22
没原理图,没什么意思!!!
作者: Hitto    时间: 2017-5-10 20:55
理论电流输出是多少?还有U2的那两个集成运放是干什么的?
作者: xuanbaoren    时间: 2017-8-16 22:29
厉害,学习学习!
作者: ruanhua    时间: 2017-11-18 11:30
一直在寻找此类作品,正好学习一下知识
作者: aishininmen    时间: 2017-12-9 17:52
厉害,学习学习!
作者: 独战2011    时间: 2018-3-9 09:56
谢谢分享,急需
这样的例程

作者: tthappy    时间: 2018-6-11 07:58
谢谢分享,收藏了
作者: MIkeS    时间: 2018-6-26 23:11
只有电压采集 ,没有调整输出的功能啊
作者: ab560    时间: 2018-6-27 08:12
正需要,谢谢楼主分享
作者: bh2030693    时间: 2018-7-5 22:35
电压显示,没有单片机调压,想做一个调压的
作者: bh2030693    时间: 2018-7-5 22:48
5swords 发表于 2016-12-20 13:33
原理图在此http://www.51hei.com/bbs/dpj-56592-1.html

不配套,可互补;
这个是显示,那个是调压。
作者: anyway132    时间: 2018-7-9 22:33
挺好的,学习下
作者: 2387806    时间: 2018-9-4 17:40
正需要,学习下
作者: 2387806    时间: 2018-9-4 17:42
正需要,谢谢楼主分享
作者: 色拉油    时间: 2018-10-8 14:11
参考一下,谢谢楼主
作者: 586486    时间: 2018-11-4 23:24
谢谢分享。
作者: ZUOJIANKUN    时间: 2018-11-21 18:16
感谢,非常感谢,号
作者: find_all    时间: 2019-3-8 17:31
学习一下。
作者: 真的见证1991    时间: 2019-6-3 16:05
学习了,谢谢楼主分享
作者: MIkeS    时间: 2019-6-12 02:30
恩,这个代码,是纯ADC采样显示,没有数控的功能.
作者: 18239311863    时间: 2019-7-16 23:10
坑了呗,就一个点c文件
作者: yifeid    时间: 2019-11-18 22:25
坑了呗,就一个点c文件
作者: Hope2    时间: 2019-11-24 20:57
有图吗?
作者: wy_l    时间: 2019-11-24 22:41
受益匪浅
作者: wuxiandianzi    时间: 2019-12-11 21:24
非常感谢提供 这个!
作者: yhgwork    时间: 2021-5-1 09:25
不错的数控电源
作者: Liangkan    时间: 2021-6-13 13:01
xiaoer 发表于 2016-12-22 07:58
前一段时间购买了XL4016,做大功率数控电源,原理同上,

可以分享一下吗?谢谢你
作者: yyzf998    时间: 2023-3-26 16:10

楼主这里有个LM2596数控电源的程序希望能帮到你:http://www.51hei.com/bbs/dpj-56600-1.html




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1