数字恒流源(LM324运放+三极管+pid反馈采集) |
您所在的位置:网站首页 › 反馈电路采样点 › 数字恒流源(LM324运放+三极管+pid反馈采集) |
最近,在做课程设计了一款数字恒流源电路,其要求如下:
a)利用DA转换芯片输出200-1000mA电流信号 b)可设置并显示输出电流给定值 c)系统工作符合一般恒流源要求 d)可步进输出电流,步进值10mA e)保护电路 一、设计原理 (硬件部分)通过STM32F103C8T6驱动MCP4725模块,产生模拟电压,模拟电压输入由LM324和S8050三极管构成的压控型恒流源,再通过采样电阻与恒流源电路串联进行差分运放电压采样,实现对电流的检测。将电流的检测结果送入STM32F103C8T6,进行PID运算,实现200-1000mA恒流源控制。 其Multism电路图如下: 差分运放:如图,电阻R1,R5分别接入到正向输入端和反向输入端,采集的电压信号分别从两端输入,输出端接入R6到反向输入端,同时正向输入端与地之间接入平衡电阻R8,其中R1=R5,反馈电阻为平衡电阻R8,从而构成对称电路。运放输出端为R6/(R8*(V1-V2
链接: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; } |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |