一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
楼主: 无锡风
收起左侧

M8 数控电源 测试版

  [复制链接]
 楼主| 发表于 2009-5-18 18:20 | 显示全部楼层
原帖由 fat 于 2009-5-18 12:01 发表 https://www.yleee.com.cn/images/common/back.gif
另:老冯您的意思是让我改变电压采样电阻的分压比为4:1模拟出您当初实验条件是吗?然后拿万用表交流档测?没有示波器我觉得不太靠谱吧,也可能是表笔引线上感应电压呢?


可以看看
电源的输出阻抗,是很低的——会“可能是表笔引线上感应电压”吗?
发表于 2009-5-21 15:36 | 显示全部楼层
FAT老兄:
刚刚看了原版的电流控制的算法,仅仅使用了逐次比较法,受速度的影响比较严重,我简单的处理了一下,不知道是否是这里,没有进一步做,麻烦您试试看
// update file:analog.c
// update by:fujiachun
// update date:090521

//修改了限流的ADC控制,这个是临时的,没有使用任何算法

// the control loop changes the dac:
static void control_loop(unsigned char channel){
        int tmp;
        tmp=target_val[0] - analog_result[0];// 电流检测 目标(设定值)-ADC结果
        if (tmp < 1){
                voltagecontrol=0; // I control
        }else{
                voltagecontrol=1; // U control
                tmp=target_val[1] - analog_result[1];
        }
        if (conversioncount>2){
                // go only once in a while close
                // to prevent permanent lsb toggle
                if (tmp > -2 && tmp < 2){
                        tmp=0;
                }
        }
        // slowly up:
        if (tmp >1){
                tmp=1;
        }
        if (tmp <-1){
                tmp=-1;
        }

        //这里是我加的
        if (tmp <-10){
                tmp=-10;
        }
        if (tmp <-100){
                tmp=-100;
        }
        //这里是我加的---END
        dac_val=dac_val + tmp;   //逐次比较
        if (dac_val<0){
                dac_val=0;
        }
        dac(dac_val);
}
/* the following function will be called when analog conversion is done.
* It will be called every 13th cycle of the converson clock. At 4Mhz
* and a ADPS factor of 32 this is: ((4000 kHz/ 32) / 13)= 9.6KHz intervalls
*/
SIGNAL(SIG_ADC) {
        adlow=inp(ADCL); /* read low first !! */
        adhigh=inp(ADCH); /* read low first !! */
        // toggel the channel between 0 an 1. This will however
        // not effect the next conversion as that one is already
        // ongoing.
        channel++;
        if (channel>1){
                channel=0;
        }
        // 2.56V ref
        ADMUX=(1<<REFS1)|(1<<REFS0)|(channel & 0x07);
        // channel=1 = U, channel=0 = I
        analog_result[channel]=((adhigh<<8)|(adlow & 0xFF));

        // short circuit protection:
        if (analog_result[0] > SH_CIR_PROT){        //短路保护
                dac(20);
                dac_val=20;
                goto ENDSIG;
        }
        if (channel == 1){
                // only when we have new current measurements
                goto ENDSIG;
        }
        control_loop(voltagecontrol);
        // end of interrupt handler
ENDSIG:
        conversioncount++;
}
发表于 2009-5-21 15:49 | 显示全部楼层
哈哈,傅老师,我们想到一块了,我刚才受您的启发也回去读程序了,也是找到这里,我的想法是直接把下面短路保护这一段加个条件(比如实际电流值>3倍设定值则执行)添到上面DAC修正的程序段里,就是如果>3倍设定值,则先进入低压保护,如果没达到3倍(当然这个可以设定),就还是按原来的逐次比较来修正。

至于DAC值修正这里,要快速的话可以用二分法,将当前值与设定值相减,取差值一半作为增量,这样对于10位的AD值,仅几次修正就可以达到要求值,只是这个控制循环是在中断里调用的,怕会程序长了会有其它不良影响。

可我又想到,这样一来这电源的“启动性能”可能就不好了,就象前面有朋友说拿电动机作试验就启动不了,一开始就保护了,这也是个两难选择的问题。
发表于 2009-5-21 15:59 | 显示全部楼层
原来我只粗读一遍程序,没注意电流优先还是电压优先的控制,细读之下才理解到作者想法的细节,唉,不得不说一句,winavr的IDE实在不咋的,要在整个项目目录内查找一个函数的定义真是累啊,得一个个文件打开再搜索,如果有个智能点的IDE就好了,目录里那一大堆的文件,要一个个打开来查找函数定义真是麻烦死了。


不知道比如象晶体管收音机这样的东西,能承受过压过流多长时间呢?保护要做到多快才能保得住它?
发表于 2009-5-21 19:10 | 显示全部楼层
傅老师,control_loop函数我改成这样了,您看行不行?
static void control_loop(unsigned char channel){
int tmp,ttmp;
tmp=target_val[0] - analog_result[0];
if (tmp < 1){
  voltagecontrol=0; // I control
}else{
  voltagecontrol=1; // U control
  tmp=target_val[1] - analog_result[1];
}
if (conversioncount>2){
  // go only once in a while close
  // to prevent permanent lsb toggle
  if (tmp > -2 && tmp < 2){
   tmp=0;
  }
}
ttmp=tmp&0x8000;
tmp=tmp>>1;
tmp=tmp|ttmp;
dac_val=dac_val + tmp;
if (dac_val<0){
  dac_val=0;
}
dac(dac_val);
}

我正在值班,没办法试验,如果哪位朋友焊好了硬件的麻烦重新编译一试。
发表于 2009-5-22 07:19 | 显示全部楼层
我上面的就是想确定控制的位置,按您说的,电流控制直接用折半算法就可以了,类似的电源在重载下开机,就是软启动了,我一位这个付作用刚好保护负载
发表于 2009-5-22 07:26 | 显示全部楼层
好像不对头(我是菜鸟的),应该是 dac_val/2吧就是如果超过电流控制的阀值,电压就循环折半,回升的时候在逐次比较,我不会编译,没法试,电流控制常用有两种算法(我自己以为),一种是目标回归,一种是折半查找,目标回归就是先根据当前的电压和电流计算负载电阻,然后根据负载电阻和设定的电流计算目标电压,然后直接拉到目标电压再进入逐次比较,另外就是电压循环折半,知道电流复合要求为止
发表于 2009-5-22 08:55 | 显示全部楼层
从变量名看,target_val是控制目标值, analog_result是实际AD值,数组的[0]单元保存电压,[1]单元保存电流值,那么tmp=target_val[1] - analog_result[1]就是实际的差值,折半就是取其一半,好象没有错啊,dac_val是实际输出值,后面用dac(dac_val)直接输出了。我下班回家先编译试试。

另外,编译不难啊,您是否已经安装了winavr?如果还没有,请从这里下载:
http://sourceforge.net/project/d ... l.exe&a=9477815
然后安装,只需指定一下安装目录位置,其它的不用设。
安装完后,就可以使用了。winavr程序组中的“Programmers Notepad[Winavr]”,就打开了一个相当于IDE的窗口了,在这里可以编辑、编译、保存C程序。
发表于 2009-5-22 09:33 | 显示全部楼层

试验结果

我修改的部分编译后试用通过,灯泡再也没有突然闪亮一下后面暗黄的情况,但由于修正的步进值增大到差值的1/2,所以电压跳动值太大,这个似乎又有违“稳压”电源的目标了。也许是要用2倍值作为阀值,超过的就用折半调整,一量电流<2倍设定值,就用原来的步进值,或者还要再想其它办法
发表于 2009-5-22 10:16 | 显示全部楼层
数组的[0]单元保存电压,
[1]单元保存电流值,这里麻烦您在看看,我的眼神不好,至少我是看成了0保存电流,1保存电压
     if (analog_result[0] > SH_CIR_PROT){        //短路保护
                dac(20);
                dac_val=20;
                goto ENDSIG;
        }
折半:我的理解不是差值折半,是直接把输出电压折半。如果当前1000MA,设定500MA,差值
折半以后是750
一个ICC已经头晕眼花了,WINAVR还想稍后在看看,高考临近,一堆的事,坐不住

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-4-25 14:38 , Processed in 0.047561 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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