数字恒流源(LM324运放+三极管+pid反馈采集)

文章讲述了使用STM32F103C8T6控制MCP4725模块设计数字恒流源,通过LM324和三极管构建恒流源,配合PID算法实现电流设置与监控。软件部分使用HAL库进行I2C通信和ADC采样,通过位置式PID实现电流控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



最近,在做课程设计了一款数字恒流源电路,其要求如下:

a)利用DA转换芯片输出200-1000mA电流信号
b)可设置并显示输出电流给定值
c)系统工作符合一般恒流源要求
d)可步进输出电流,步进值10mA
e)保护电路

一、设计原理 (硬件部分)

通过STM32F103C8T6驱动MCP4725模块,产生模拟电压,模拟电压输入由LM324和S8050三极管构成的压控型恒流源,再通过采样电阻与恒流源电路串联进行差分运放电压采样,实现对电流的检测。将电流的检测结果送入STM32F103C8T6,进行PID运算,实现200-1000mA恒流源控制。
其Multism电路图如下:
在这里插入图片描述
压控恒流:如原理图,输入的电压为DAC4725输出的模拟电压Vin,该恒流源系统由LM324AD和三极管以及外部电阻构成,三极管采用8050能够实现集电极最大电流1.5A输出。图中RL2为负载电阻,R2为采样电阻,流过负载电阻的电为Vin/R2,LM324采用负反馈电路从而工作在线性区,由此有Vin=Up=Un,则R2的电流为Vin/R2。三极管集电极电流近似等于发射极电流,当流过的电流增大,R2的电流也会随之增大,进而电压增大,导致Un增大,(Up-Un)减小,从而运放输出减小,三极管电流减小,负载电流也会减小,R2电流随之减小,正是因为负反馈从而达到恒流目的。

差分运放:如图,电阻R1,R5分别接入到正向输入端和反向输入端,采集的电压信号分别从两端输入,输出端接入R6到反向输入端,同时正向输入端与地之间接入平衡电阻R8,其中R1=R5,反馈电阻为平衡电阻R8,从而构成对称电路。运放输出端为R6/(R8*(V1-V2
这是立创画的原理图

绘制原理框图,描述各功能单元之间的逻辑关系

在这里插入图片描述

1.软件部分

  软件部分的代码使用的HAL 库编写的,原理如下:用iic驱动mcp4725模块,输出模拟电压,然后用c8t6自带的DA采集,采集电压,通过位置式pid计算,实现横流控制,  
   这里用的是HAL库,iic1和iic2分别驱动mcp4725芯片和oled屏幕;这里的mcp4725是一款集成的芯片,其实就是一个DA转换器,它用单片机输出的数字电压,产生一个模拟电压

这里是所需要的引脚配置,包括两个和IIC和一个串口(用于调试);KEY-1和KEY-2是外部中断,用来调节输出的电压 ADC1是用电电压采集的,目的是形成负反馈,pid闭环控制
这里是所需要的引脚配置,包括两个和IIC和一个串口(用于调试);KEY-1和KEY-2是外部中断,用来调节输出的电压 ADC1是用电电压采集的,目的是形成负反馈,pid闭环控制]
这里是两个IIC的配置,就是常规配置 标准模式100000HZ
这里是两个IIC的配置,就是常规配置 标准模式100000HZ]
这里是ADC 单通道 我选择的是IN0 加dma方式
[这里是ADC 单通道 我选择的是IN0 加dma方式](
在这里插入图片描述

这里是两个按键的外部中断,目的是用于调节电压,控制输出电流
这里是两个按键的外部中断,目的是用于调节电压,控制输出电流
这里一定要注意打开外部中断
这里一定要注意打开外部中断](

在这里插入图片描述
这里是实物图 其中pid需要自己调试

所有的工程文件在这,包括multisim仿真和代码

链接:https://pan.baidu.com/s/18zVFmSFzKUN2d6Jb-nQy8g?pwd=7777
提取码:7777
–来自百度网盘超级会员V4的分享

代码如下(示例):

MX_GPIO_Init();
MX_DMA_Init();
MX_I2C2_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
OLED_Init();
OLED_Clear();
PID_init();
HAL_ADCEx_Calibration_Start(&hadc1); // f1系列需要ADC校准,f4不需要
HAL_ADC_Start_DMA(&hadc1,(uint32_t )&ADC_DMA_Value,ADC_Channel_MAX); // 启动ADC的DMA转换
/
USER CODE END 2 /
/
Infinite loop /
/
USER CODE BEGIN WHILE /
while (1)
{
/
USER CODE END WHILE */

/* USER CODE BEGIN 3 */
	//  OLED_FullyClear ();

	
	sprintf(i1_1, "Set i:%.1f mA", i1);
	sprintf(i2_2, "Acutal i:%.1f mA", i2);
	sprintf(i3_3, "Acutal V:%.1f V", i3);
OLED_ShowString(4,2.,i1_1,1);//这个是oled驱动里面的,是显示位置的一个函数,
OLED_ShowString(4,4,i2_2,1);//这个是oled驱动里面的,是显示位置的一个函数,
	OLED_ShowString(4,8,i3_3,1);//这个是oled驱动里面的,是显示位置的一个函数
	ADC_Value = ADC_DMA_Value[0];
	//printf("实际电压%0.1f \n",ADC_Value*5.0/4096.0);//测试时,串口调试
  DAC_Value = DAC_Value + PID_realize((i1/1000)*RL, ADC_Value*5.0/4096.0);
  DAC_Value2 =   DAC_Value*1.5;//硬件山的设计,采样的电压和实际的电压为1.5倍的关系 	
	i3=ADC_Value*5.0/4096.0;

// /软件保护电路,如果计算出的输出电压过大,就关闭输出*******/
// if( DAC_Value2 >5.0)
// { DAC_Value2 =0;
// }

	  i2= (( ADC_Value*5.0/4096.0)*1000)/RL;//实际采集的电流 
                   
/***************************	//mcp4725的输出函数,当为5v接入时输出关系为 输入*1.2,当接入3.3v倍数为0.8 输入的单位为mV
                   比如输入3000 ,接入5v就输出3000*1.2=3600mV ;;	************************************/	

// MCP4725_Out(&hi2c1,( DAC_Value2/1.2)*1000,1);
MCP4725_Out(&hi2c1,3000,1);
HAL_Delay(50);
//printf(“输出电压%0.1d \n”, DAC_Value);

}
/* USER CODE END 3 */
}


## 2.读入数据

代码如下(示例):

#include "pid.h"
#include "stdio.h"
extern float i1 ;
pid_p pid;

//pid位置式
void PID_init()
{
   // printf("PID_init begin \n");
    pid.SetVoltage= 0.0;		  // 设定的预期电压值
    pid.ActualVoltage= 0.0;		// adc实际电压值
    pid.err= 0.0;				      // 当前次实际与理想的偏差
    pid.err_last=0.0;			    // 上一次的偏差
    pid.voltage= 0.0;			    // 控制电压值
    pid.integral= 0.0;			  // 积分值
    pid.Kp= 0.5;				      // 比例系数
    pid.Ki= 0.0;				      // 积分系数
    pid.Kd= 0.0;				      // 微分系数
  //  printf("PID_init end \n");
}

float PID_realize( float v, float v_r)
{  
	  printf("设定值%0.1f \n", i1);
    pid.SetVoltage = v;				// 固定电压值传入
    pid.ActualVoltage = v_r;	// 实际电压传入 = ADC_Value * 3.3f/ 4096
    pid.err = pid.SetVoltage - pid.ActualVoltage;	//计算偏差
    pid.integral += pid.err;					//积分求和
    pid.result = pid.Kp * pid.err + pid.Ki * pid.integral + pid.Kd * ( pid.err - pid.err_last);//位置式公式
    pid.err_last = pid.err;					//留住上一次误差
    //pid.ActualVoltage=pid.result*1.0;			//实际角度应该由角度传感器+ADC返回
    return pid.result;
}




### 回答1: Multisim是一款功能强大的电子电路仿真软件,而PID则是一种常用的控制系统算法。在Multisim中,可以使用PID控制模块进行电路的控制系统仿真。 PID代表比例-积分-微分控制,是一种经典的反馈控制算法,在工业自动化等领域广泛应用。通过计算当前测量值与设定值之间的差异,PID控制器可以自动调整控制输入,使得系统的输出稳定在期望值附近。 在Multisim中,PID控制模块可以模拟电路中的控制系统行为。用户可以设置控制器的比例、积分和微分增益来调整系统的响应速度、稳定性和抗干扰能力。模拟中,用户可以通过添加传感器、执行器和反馈系统来完整地建模一个控制系统。 例如,用户可以在Multisim中创建一个温控系统,使用PID控制模块控制加热装置的输出,使得温度稳定在设定值附近。通过调整PID控制器的参数,用户可以观察系统的响应特性,例如响应时间、超调量以及稳态误差。 使用Multisim进行PID控制仿真,能够帮助用户深入理解PID控制算法的原理和应用。通过观察和分析仿真结果,用户可以优化控制器的参数,改进系统的控制性能。此外,Multisim还提供了可视化工具,如波形图和频谱分析,方便用户对控制系统的性能进行评估和调试。 总而言之,Multisim通过提供PID控制模块,为用户提供了一个方便、直观的环境,来研究和分析控制系统的行为。在教学和学习过程中,Multisim的PID功能可以帮助学生更好地理解控制原理,而在工程实践中,它也是一个有用的工具,可以用于设计和优化各种控制系统。 ### 回答2: Multisim PID是一种在Multisim软件环境下进行PID控制的工具。PID控制是一种经典的控制算法,用于调节控制系统的输出以使其与期望的参考信号尽可能接近。 Multisim PID具有以下特点和功能:首先,它提供了PID控制算法的图形化界面,用户可以通过简单拖放的方式构建PID控制回路。其次,它具有参数调整的功能,可以根据实际应用需求对PID控制器的参数进行调整,以达到更精确的控制效果。 使用Multisim PID进行控制系统设计时,首先需要选择合适的传感器来获取所需的反馈信号。然后,将传感器的输出与期望的参考信号输入到PID控制器中进行比较,并根据比较结果调整控制输出。最后,将调整后的控制信号输入到执行器中,使得控制系统的输出逐渐趋向于期望的参考信号。 在Multisim PID中,可以对PID控制器的比例、积分和微分参数进行调整。比例参数决定了输出量与误差之间的比例关系,积分参数对积分误差进行补偿,微分参数对误差变化率进行补偿。通过合理调整这些参数,可以使控制系统具有快速响应、准确稳定的特性。 总之,Multisim PID是一款强大的PID控制工具,可以帮助工程师在Multisim软件环境下进行精确的控制系统设计和调试。它具有图形化界面、参数调整以及灵活的回路构建等特点,为控制系统的设计和优化提供了便利。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值