原创 一个简易的数控电源DVCS(digital control voltage source)的实现

2007-8-9 19:02 5232 5 8 分类: MCU/ 嵌入式

pdf一个简易的数控电源DVCS(digital control voltage source)的实现。


一、基本功能:


1、输入电压: DC18V,输出电压: 1.3V——16.0V,电压调整精度0.1V


2、负载能力: 400mA


3、动态三位数码管显示输出电压


4、按键调整输出电压,SW1——1V/0.1V步进电压调整键;SW2——递增调整键;SW3——递减调整键


二、功能模块实现:


1、单片机与按键接口部分:


点击看大图



<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


2 单片机与数码管显示接口电路:


采用动态扫描三位数码管,共阳极接法,每段驱动电流约为4mA.


点击看大图



3 DAC与单片机接口电路和DA参考电压电路:


IC<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />6A,IC6B两个运放用来将R-2R DAC 的电路变换为电压并反相放大来驱动LM317的电压调整端,IC1B用来产生一个较为稳定的电压给DAC的转换参考电压来供电.运放选用LM358.


点击看大图



4,电压调整与输出电路:


供电电路采用有中心抽头的变压器双15V,经整流,滤波得到正负18V的电压给LM317供电,Rp1Rp2用来保护LM317,防止输出电流过高而烧坏芯片.运放IC1ALM317一起构成负反馈,使IC1AV-V+电压相等.DAC输出的电压加到运放的输入端,单片机控制DAC的输出电压变化,那么LM317的输出电压由于负反馈的原因而跟随DAC的输出变化.从而实现了数控的作用.Rc用来保证输出电压最小能达到1.3V,如果没有这个下拉电阻分流,LM317adjust current会流进运放使运放输出电压升高,进而导致317输出升高.R25取值是由317load regulation current 决定的,317必须有一个最小的负载电流来维持内部的regulation  来实现输出电压的稳定.C3用来防止震荡,稳定负反馈环,其取值由调试时确定.


单片机和DAC的供电电路有LM7805来产生.


点击看大图



, 程序原码:


//***************************程序说明*************************************


//1 使用小模式编译时,不可把变量定义在PDATA区,KEIL 默认的是


//  小模式下的编译。因此,如果使用uchar pdata arry[],则必须


//  将编译器设在compact 模式下编译。数码管显示乱码就是因为编译器


//  没有设置好。


//2 处理按键扫描时,一定要去抖动。由于人按键时间较长,为了实现每


//  按一次键,输出电压增加0.1V。在判断到按下键时,先不去刷新DA的


//  寄存器,在程序里仍然调用动态扫描程序,直到按键释放时,在去刷新


//  DA的寄存器,刷新后仍然调用显示程序。这样就实现了按一次键"+" 1


//  的动作


//3 动态扫描时间为每位10毫秒比较适宜,再慢的话,屏幕会抖动.


//4 为了防止按一下键,程序被中断了多次,可以把中断设为边沿触发方式,


//  这样每按一下键只中断了一次.(把中断方式 IT0 设置为"1")


//**************************************************************************


#include  "reg51.h"


#include  "math.h"


#define   uint      unsigned int


#define   uchar     unsigned char 


//#include  "intrins.h"


#define   led_sec   P1


#define   dac_adr   0x7fff     //DAC0832的地址


sbit      inc_key = P3^0;      //"+"


sbit      dec_key = P3^1;       //"-"


sbit      step_key = P3^2;      //调整键


sbit      ten = P3^3;          //数码管的十位


sbit      one = P3^4;           //数码管的个位


sbit      point  = P3^5;        //数码管的小数位


char xdata  dacreg  _at_  dac_adr;  //define the dac0832's address


bit  flag0 = 0;


uchar   arry10[10] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};


uchar   arry1[10] = { 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};


uchar   arry0[10] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};


uchar * ptr10 = arry10;


uchar * ptr1 = arry1;


uchar * ptr0 = arry0;


//arry10[10] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};


//arry1[10] = { 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};


//arry0[10] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};


//**************************initial function**********************************


//中断初始化


void  ini_int(void)


{


  inc_key = 1;


  dec_key = 1;


  EA = 1;


  EX0 = 1;


  IT0 = 1;  //边沿触发方式      


}


//**************************delay function************************************


//延时动态扫描


 


void  delay(uint i)  //delay cycle is 20us


{


  uint j="0";


  for (;j<?xml:namespace prefix = i;j++);


}


//**************************buffer**************************************


//根据地址查表得出要显示的电压值


buffer(uchar led10,uchar led1,uchar led0)


{


  ten = 0;


  led_sec = *(led10 + ptr10);      


  delay(500);        // delay 10ms


  ten = 1;


  one = 0;


  led_sec = *(led1 + ptr1);


  delay(500);


  one = 1;


  point = 0;


  led_sec = *(led0 + ptr0);


  delay(500);


  point = 1;


 


}


//**************************display the output voltage******************


//BCD码到十进制的转换


 


void disp_out(unsigned char dat)


{ 


  uchar dig_10,dig_1,dig_0,temp,temp1;


  temp = dat;


  dig_10 = temp/100;


  temp1 = temp%100;


  dig_1 = temp1/10;


  dig_0 = temp%10;


  buffer(dig_10,dig_1,dig_0);


  


}


//**********************main function***********************************


void  main()


{


  unsigned char dac_dat,dac_temp;


  uchar    inc_key_temp = 1;


  uchar    dec_key_temp = 1;


  dac_dat = 0xd;


  //flag0 = 0;            // initialising the flag bit


  dac_temp = dac_dat;


  dacreg = dac_temp;    //set the output voltage to 1.3V


  ini_int();          //interrupt initialising


  disp_out(dac_temp);


  while (1 /*~dec_key | ~inc_key*/)


  {


//判断有没有键按下


    if ( inc_key == 0 )


      {


        delay(600);


        inc_key_temp = (inc_key == 0) ? 0 : 1;


//按键释放前一直扫描显示,如果按键释放则跳出并 "+" 1


       do


          {


            disp_out(dac_temp);


          }


        while (inc_key == 0);


       


      }


    else if( dec_key == 0 )


      {


        delay(600);


        dec_key_temp = (dec_key == 0) ? 0 : 1;


        do


          {


            disp_out(dac_temp);


          }


        while (dec_key == 0);


      }


    else


      {


         ;


      }


         if ( ~flag0 & ~dec_key_temp & (dac_temp>13))       // decrease and step is 0.1V


         {


            dec_key_temp = 1;


            dac_dat = dac_dat - 1;


            dac_temp = dac_dat;


            dacreg = dac_temp;


            disp_out(dac_temp);


         }


         else if ( ~flag0 & ~inc_key_temp & (dac_dat<161)) // increase and step is 0.1V


         {


            inc_key_temp = 1;


            dac_dat = dac_dat + 1;


            dac_temp = dac_dat;


            dacreg = dac_temp;


            disp_out(dac_temp);


         }


         else if ( flag0 & ~dec_key_temp & (dac_dat>23))  //decrease and step is 1V


         {  


            dec_key_temp = 1;


            dac_dat = dac_dat - 10;


            dac_temp = dac_dat;


            dacreg = dac_temp;


            disp_out(dac_temp);


         }


         else if (flag0 & ~inc_key_temp & (dac_dat<151))   // increase and step is 1V


         {


            inc_key_temp = 1;


            dac_dat = dac_dat + 10;


            dac_temp = dac_dat;


            dacreg = dac_temp;


            disp_out(dac_temp);


         }


         else


         {


            disp_out(dac_temp);


         }


  }


 


}


//*************************interrupt function**************************


void int0() interrupt 0 using 1


{


  flag0 = ~flag0;


}

;j++);

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1381193 2010-1-8 22:08

电压电流都没检测 哪来的精度?

用户740664 2009-6-25 14:23

谢谢啊

用户740664 2009-5-19 19:29

相关推荐阅读
用户97533 2008-06-20 18:34
还有几块空板,想送给有意用LPC2368的网友,交个朋友
还有几块空板,想送给有意用LPC2368的网友,交个朋友,优先考虑南京的朋友, 因为本人现在南京, 让俺们共同努力, 一齐进步! ...
用户97533 2008-06-14 10:07
上传已调试好的源程序,原理图
上传源程序和板子原理图请点击下载。原理图是POWERLOIGC格式的。...
用户97533 2008-06-13 19:01
LPC2368网络板DIY——RTC 调试记录(七)
       RTC的使用,首先要设置RTC的时钟源,2368可以有两种方式,1 使用PLL 分频得到32.768K的时钟,2 直接用外部32.768的晶体,不知NXP为何搞这两种方式,个人认为可能是...
用户97533 2008-06-13 18:51
LPC2368网络板DIY——CSTN 调试记录(六)
        CSTN屏的大小是 162X132,6.5K色,我用的是8位并行的传输模式,点亮一个点需要两个发送周期。先送高字节,再送低字节。在调试的时候发现,图片的颜色老是不对,CSTN的驱动时序...
用户97533 2008-06-13 18:43
LPC2368网络板DIY——I2C PCF8574 调试记录(五)
调试完了FAST GPIO,开始进入I2C接口调试,主要实现对PCF8574的控制,整个程序是个状态机,I2C 中断服务程序根据不同的状态确定下一步要做的事情。首先确定8574的地址,由于原理图上我接...
用户97533 2008-06-13 18:31
LPC2368网络板DIY——FastGPIO 调试记录(四)
LPC2368的GPIO可以配置为low speed 和high speed 两种模式,PORT0,PORT1默认为low speed模式,PORT2,PORT3, PORT4只能工作在high sp...
EE直播间
更多
我要评论
3
5
关闭 站长推荐上一条 /3 下一条