大学: 郑州轻工业学院 (1)增益可控运放——VCA810 (2)16位高精度DA——DAC8501 (3)16位高精度AD——ADS1115 (4)高精度基准电压芯片——REF2041 (5)高精度电流分流监视器——INA282 (6)高电压大电流运放——OPA547 (7)超低功耗MCU——MSP430 |
该恒流源是基于MSP430单片机所设计的,运用了硬件反馈和软件反馈的双重闭环控制策略。通过电压信号控制电流源输出。电流源最大输出功率在是 30W,最大输出电流可以达2A,输出频率可以在 40 至 100Hz 间变化。先进的直接数字频率合成芯片(DDS)AD9833 作为本文系统的信号发生芯片。滤波电路采用了二阶有源低通滤波电路加一阶高通滤波电路的形式,有效滤除了 AD9833 输出信号时的高频噪音和直流分量,提高了正弦频率信号的质量。16 位 D/A 芯片可以控制输出信号的增益,通过增益可控的放大器VCA810对正弦波进行调制,就可以实现对正弦波幅值的控制。通过Howland恒流源拓扑来组成电压电流转换电路。利用真有效值转换芯片AD637来转换交流电流。通过16位AD来采集最终输出的电流。从而进行软件闭环控制。
该工作过程如下:首先把通过按键和屏幕 以及MSP430单片机 设定的频率和电压增益数据分别送到 DDS 芯片(AD9833)和 DA 芯片(DAC8501) ,使 DDS 芯片输出一个设定的电压频率信号,此电压频率信号的幅值通过DA 芯片输出的电压控制增益可控放大器的输出,从而输出一个频率和幅值为设定值的电压信号,电压信号经过档位调整功放和硬件反馈电路输出具有一定带载能力的电流信号。在这个过程中,DDS 及 D/A 控制都是静态过程。在电流控制环节,电流传感器检测输出的电流,首先把电流信号转换成电压信号,使用真有效值转换芯片 AD637KD 把交流电压信号转换为与其有效值相等的直流电压信号,然后通过 16 位的 A/D 芯片 ADS11152进行模数转换,将检测到的数字量送入单片机,当检测到数字量不在预设范围内的时候,单片机就可以相应改变输出给 16 位的 D/A 芯片 DAC8501 控制数据,从而校正电压增益值,校正的电压增益值与交流信号通过VCA821进行调制,最终可以有效使电压信号在幅值上变化,从而改善输出的电流幅值,这是一个动态校正的过程。这与之前的硬件反馈电路一起实现双反馈。
- 利用软件闭环和硬件闭环实现高精度、宽范围调节恒流输出
#include"msp430g2253.h" //high or low level of the ctrl pin #define normal 0x00 //normal working mode #define out_1K 0x01 //output 1K ou #define out_100K 0x02 //output 100K ou #define HIGH_Z 0x03 //HIGH impedence output #define FSYNC_L P2OUT &= ~BIT5 #define FSYNC_H P2OUT |= BIT5 #define SCLK_L P2OUT &= ~BIT4 #define SCLK_H P2OUT |= BIT4 #define DIN_L P2OUT &= ~BIT3 #define DIN_H P2OUT |= BIT3 float vol = 0.5; //voltage of the dac output unsigned int vol_code; //voltage code of the output void cal_vol_code(float); //calculate the voltage code void set_8501(unsigned char,unsigned int); //set the data to the dac8501 shift register void main(void) { WDTCTL = WDTPW + WDTHOLD; //stop WDT P2DIR |= BIT3 + BIT4 +BIT5; //set p2.3 2.4 2.5 to output direction cal_vol_code(vol); set_8501(normal,vol_code); } void set_8501(unsigned char mode,unsigned int code) //send the working mode and the voltage code { FSYNC_L; //pull down the SYNC SCLK_H; //pull up the SCLK and ready to clock the data on the falling edge of the sclk unsigned char TEMP = 0x80; //send the first byte which include the working mode of the chip unsigned int TEMP1 = 0x8000; //send the next two byte which contains the voltage code unsigned char i; //loop value for(i=0;i<8;i++) { SCLK_H; if((mode & TEMP) == TEMP) DIN_H; //corresponding bit equals one else DIN_L; TEMP >>= 1; SCLK_L; } for(i=0;i<16;i++) { SCLK_H; if((code & TEMP1) == TEMP1) DIN_H; //corresponding bit equals one else DIN_L; TEMP1 >>= 1; SCLK_L; } SCLK_H; FSYNC_H; //pull up again } void cal_vol_code(float voltage) { vol_code = voltage * 65536 / 4.096; //voltage = Vref / 65536 * code }