找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的稳压直流电源程序

[复制链接]
跳转到指定楼层
楼主
ID:356705 发表于 2018-6-22 16:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
•它利用单片机STC89C51作为主控芯片。将家用电压经过稳压电路后,输入AD芯片,单片机控制数字/模拟转换器(PCF8591)的输出电压的大小,从而输出恒定可调电压。最后通过电位器分压将输出信号反馈到运算放大器(LM358)上,使输出电压达到标准,并且还可以进行过压过流检测,防止电压过高产生事故。此设计通过键盘电路与单片机连接,读入控制数据,利用软件进行判断,从而起到控制电源输出的作用。通过LCD1602显示数控电源的输出电压

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define PCF8591_ADDR        0x90                //PCF8591地址
  4. #define DACOUT_EN                0x40                //DAC输出使能
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. int a,b,c,t,s,w=0;
  8. uint AD_Value;        //存储AD转换回的数字量
  9. void delay(uint z)
  10. {
  11.         uint x,y;
  12.         for(x=z;x>0;x--)
  13.                 for(y=110;y>0;y--);
  14. }
  15. void delay_5us()
  16. {
  17.         _nop_();
  18. }
  19. void keyscan();
  20. sbit SDA = P2^0;   //I2C串行数据
  21. sbit SCL = P2^1;   //I2C串行时钟
  22. sbit dula  = P2^6;
  23. sbit wela  = P2^7;   
  24. sbit lcdrs=P3^7;
  25. sbit rw=P3^6;
  26. sbit lcden=P3^5;
  27. void write_com(uchar com)
  28. {
  29.         lcdrs=0;
  30.         P0=com;
  31.         delay(5);
  32.         lcden=1;
  33.         delay(5);
  34.         lcden=0;
  35. }
  36. void write_date(uchar date)
  37. {
  38.         lcdrs=1;
  39.         P0=date;
  40.         delay(5);
  41.         lcden=1;
  42.         delay(5);
  43.         lcden=0;
  44. }
  45. void init()
  46. {
  47.         rw=0;
  48.         dula=0;
  49.         wela=0;
  50.         lcden=0;
  51.         write_com(0x38);
  52.         write_com(0x0c);
  53.         write_com(0x06);
  54.         write_com(0x01);
  55. }

  56. /*I2C总线初始化*/
  57. void I2C_init()
  58. {
  59.         SDA = 1;   //数据总线高
  60.         _nop_();
  61.         SCL = 1;   //时钟总线高
  62.         _nop_();
  63. }

  64. /*I2C起始信号*/
  65. void I2C_Start()  
  66. {
  67.         SCL = 1;
  68.         _nop_();
  69.         SDA = 1;
  70.         delay_5us();
  71.         SDA = 0;
  72.         delay_5us();
  73. }

  74. /*I2C停止信号*/
  75. void I2C_Stop()
  76. {
  77.         SDA = 0;
  78.         _nop_();
  79.         SCL = 1;
  80.         delay_5us();
  81.         SDA = 1;
  82.         delay_5us();
  83. }

  84. /*I2C主机发送应答
  85. i为0时发送非应答 为1时发送应答*/
  86. void Master_ACK(bit i)       
  87. {
  88.         SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
  89.         _nop_(); // 让总线稳定
  90.         if (i)         //如果i = 1 那么拉低数据总线 表示主机应答
  91.         {
  92.                 SDA = 0;
  93.         }
  94.         else         
  95.         {
  96.                 SDA = 1;         //发送非应答
  97.         }
  98.         _nop_();//让总线稳定
  99.         SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
  100.         _nop_();
  101.         SCL = 0;//拉低时钟总线, 占用总线继续通信
  102.         _nop_();
  103.         SDA = 1;//释放SDA数据总线。
  104.         _nop_();
  105. }

  106. /*I2C检测从机应答
  107. 0为非应答 1为应答*/
  108. bit Test_ACK()         // 检测从机应答
  109. {
  110.         SCL = 1;//时钟总线为高电平期间可以读取从机应答信号
  111.         delay_5us();
  112.         if (SDA)
  113.         {
  114.                 SCL = 0;
  115.                 I2C_Stop();
  116.                 return(0);
  117.         }
  118.         else
  119.         {
  120.                 SCL = 0;
  121.                 return(1);
  122.         }
  123. }

  124. /*I2C发送一个字节
  125.   byte 要发送的字节*/
  126. void I2C_send_byte(uchar byte)
  127. {
  128.         uchar i;
  129.         for(i = 0 ; i < 8 ; i++)
  130.         {
  131.                 SCL = 0;
  132.                 _nop_();
  133.                 if (byte & 0x80)       
  134.                 {
  135.                         SDA = 1;
  136.                         _nop_();
  137.                 }
  138.                 else
  139.                 {
  140.                         SDA = 0;
  141.                         _nop_();
  142.                 }
  143.                 SCL = 1;
  144.                 _nop_();
  145.                 byte <<= 1;
  146.         }
  147.         SCL = 0;
  148.         _nop_();
  149.         SDA = 1;
  150.         _nop_();       
  151. }

  152. /*I2C读一个字节
  153. 读取的字节*/
  154. uchar I2C_read_byte()
  155. {
  156.         uchar i, dat;
  157.         SCL = 0 ;
  158.         _nop_();
  159.         SDA = 1;
  160.         _nop_();
  161.         for(i = 0 ; i < 8 ; i++)
  162.         {
  163.                 SCL = 1;
  164.                 _nop_();
  165.                 dat <<= 1;          
  166.                 if (SDA)
  167.                 {
  168.                         dat |= 0x01;  
  169.                 }
  170.                 _nop_();
  171.                 SCL = 0;
  172.                 _nop_();
  173.         }
  174.         return(dat);
  175. }

  176. /*DAC输出*/

  177. bit DAC_OUT(uchar DAT)
  178. {
  179.         I2C_Start();
  180.         I2C_send_byte(PCF8591_ADDR+0);
  181.         if (!Test_ACK())
  182.         {
  183.                 return(0);
  184.         }
  185.         I2C_send_byte(DACOUT_EN);        //DA输出使能
  186.         if (!Test_ACK())
  187.         {
  188.                 return(0);
  189.         }
  190.         I2C_send_byte(DAT);
  191.         if (!Test_ACK())
  192.         {
  193.                 return(0);
  194.         }
  195.         I2C_Stop();
  196.         return(1);       
  197. }                               

  198. /*读AD数据*/
  199. bit ADC_Read(uchar CON)
  200. {
  201.         I2C_Start();
  202.         I2C_send_byte(PCF8591_ADDR+0);
  203.         if (!Test_ACK())
  204.         {
  205.                 return(0);
  206.         }
  207.         I2C_send_byte(CON);
  208.         Master_ACK(0);
  209.         I2C_Start();
  210.         I2C_send_byte(PCF8591_ADDR+1);
  211.         if (!Test_ACK())
  212.         {
  213.                 return(0);
  214.         }
  215.         AD_Value = I2C_read_byte();
  216.         Master_ACK(0);
  217.         I2C_Stop();
  218.         return(1);       
  219. }

  220. void main()
  221. {
  222.         init();
  223.         I2C_init();
  224.         while(1)
  225.         {               
  226.                 ADC_Read(0x43);//外部       
  227.                 keyscan();
  228.                 DAC_OUT((double)s/3*5.12);               
  229.         }
  230.                
  231. }
  232. void keyscan()
  233. {
  234.         P1=0xfe;
  235.         t=P1;
  236.         t=t&0xf0;
  237.         while(t!=0xf0)
  238.         {
  239.                 delay(5);
  240.                 t=P1;
  241.                 t=t&0xf0;
  242.                 while(t!=0xf0)
  243.                 {
  244.                         t=P1;
  245.                         switch(t)
  246.                         {
  247.                                 case 0xee:a=0,w=0;break;
  248.                                 case 0xde:a=1,w=0;break;
  249.                                  case 0xbe:a=2,w=0;break;
  250.                                 case 0x7e:a=3,w=0;break;

  251.                         }
  252.                         while(t!=0xf0)
  253.                         {
  254.                                 t=P1;
  255.                                 t=t&0xf0;
  256.                         }               
  257.                 }
  258.         }

  259.         P1=0xfd;
  260.         t=P1;
  261.         t=t&0xf0;
  262.         while(t!=0xf0)
  263.         {
  264.                 delay(5);
  265.                 t=P1;
  266.                 t=t&0xf0;
  267.                 while(t!=0xf0)
  268.                 {
  269.                         t=P1;
  270.                         switch(t)
  271.                         {
  272.                                 case 0xed:a=4,w=0;break;
  273.                                 case 0xdd:a=5,w=0;break;
  274.                                  case 0xbd:a=6,w=0;break;
  275.                                 case 0x7d:a=7,w=0;break;

  276.                         }
  277.                         while(t!=0xf0)
  278.                         {
  279.                                 t=P1;
  280.                                 t=t&0xf0;
  281.                         }               
  282.                 }
  283.         }
  284.         P1=0xfb;
  285.         t=P1;
  286.         t=t&0xf0;
  287.         while(t!=0xf0)
  288.         {
  289.                 delay(5);
  290.                 t=P1;
  291.                 t=t&0xf0;
  292.                 while(t!=0xf0)
  293.                 {
  294.                         t=P1;
  295.                         switch(t)
  296.                         {
  297.                                 case 0xeb:a=8,w=0;break;
  298.                                 case 0xdb:a=9,w=0;break;
  299.                                  case 0xbb:b=a*10,w=0;break;
  300.                                 case 0x7b:c=a,w=0;break;

  301.                         }
  302.                         while(t!=0xf0)
  303.                         {
  304.                                 t=P1;
  305.                                 t=t&0xf0;
  306.                         }               
  307.                 }
  308.         }
  309.         P1=0xf7;
  310.         t=P1;
  311.         t=t&0xf0;
  312.         while(t!=0xf0)
  313.         {
  314.                 delay(5);
  315.                 t=P1;
  316.                 t=t&0xf0;
  317.                 while(t!=0xf0)
  318.                 {
  319.                         t=P1;
  320.                         switch(t)
  321.                         {
  322.                                 case 0xe7:s=s+1,w=1;break;
  323.                                 case 0xd7:s=s-1,w=2;break;
  324.                         }
  325.                         while(t!=0xf0)
  326.                         {
  327.                                 t=P1;
  328.                                 t=t&0xf0;
  329.                         }       
  330.                 }
  331.         }
  332.         if(w==0)
  333.         {
  334.                 s=b+c;
  335.                 write_com(0x80);
  336.                 write_date('D');
  337.                 write_date('C');
  338.                 write_date(':');
  339.                 write_date(s/10+0x30);
  340.                 write_date('.');
  341.                 write_date(s%10+0x30);
  342.                 write_date(0+0x30);
  343.                 write_date('V');
  344.         }
  345.         if(w==1)
  346.         {
  347.                 if(s>99)
  348.                 {
  349.                         s=0;
  350.                 }
  351.                 write_com(0x80);
  352.                 write_date('D');
  353.                 write_date('C');
  354.                 write_date(':');
  355.                 write_date(s/10+0x30);
  356.                 write_date('.');
  357.                 write_date(s%10+0x30);
  358.                 write_date(0+0x30);
  359.                 write_date('V');
  360.         }
  361.         if(w==2)
  362.         {
  363.                 if(s<0)
  364.                 {
  365.                         s=99;
  366.                 }
  367.                 write_com(0x80);
  368.                 write_date('D');
  369.                 write_date('C');
  370.                 write_date(':');
  371.                 write_date(s/10+0x30);
  372.                 write_date('.');
  373.                 write_date(s%10+0x30);
  374.                 write_date(0+0x30);
  375.                 write_date('V');       
  376.         }                       
  377. }

复制代码

所有资料51hei提供下载:
终极电源程序.rar (34.42 KB, 下载次数: 28)



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

使用道具 举报

沙发
ID:290402 发表于 2019-6-25 21:51 | 只看该作者
学习一下
回复

使用道具 举报

板凳
ID:698805 发表于 2020-2-28 15:24 | 只看该作者
有没有电路连接图可以分享一下?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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