基于STM32的桌面数控电源项目连载

一个数控桌面电源项目


文章目录

    • 基于STM32的桌面数控电源项目连载
  • 前言
  • 一、尺寸与外观
  • 二、元器件选型
    • 1.升压芯片
    • 2.辅助电源
    • 3.参考电源
    • 4.电流检测
    • 4.温度检测
    • 5.MCU
    • 6.OLED
  • 三、原理图
    • 1.电源部分
    • 2.中控部分
    • 3.显示部分
  • 四、PCB部分
    • 1.电源部分
    • 2.控制部分
    • 3.显示部分
  • 五、说说原理
    • 1.电压控制部分
    • 2.传感器(电压、电流、温度)
    • 3.PID算法
  • 六、建模
  • 七、制造过程
    • 1.电源板
    • 2.主控板
    • 3.显示面板
  • 八、测试
    • 1.开机动画
    • 2.过温保护
    • 3.过流保护
    • 4.精度测试
    • 5.使用测试
  • 九、资料
    • 1.PCB
    • 2.源码
    • 3.外壳
  • 总结

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200823153042355.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1lWT05ORU9I,size_16,color_FFFFFF,t_70#pic_center)


前言

作为一个大学僧,成品可调电源笨重且占据桌面空间;而市售USB升压模块2、3W的功率是在不堪大用。于是,博主将从零开始,研发一款实用的桌面可调电源。


一、尺寸与外观

尺寸上,该桌面电源参考华为22.5WSCP充电器,与华为系列快充较好兼容。

二、元器件选型

1.升压芯片

为最大限度兼容PD/SCP/FCP/QC等协议,该电路模块需要有宽电压输入范围。主升压芯片选用XL6019。该芯片为TO263-5封装,最大电流5A,输出电压-0.3~60V,能够满足日常实用需求。

2.辅助电源

辅助电源供给STM32和OLED面板,要求并不高,选熟悉的3.3V线性稳压芯片即可。这里选用的是HT7333。

3.参考电源

参考电源输入STM32的Vbat引脚,作为基准电压使用,一定程度上决定了电源的精度。若要求不高,可直接并入辅助电源。这里使用一颗TL431,分压电阻为1.33K和4.22k。(TL431分压电阻的计算小工具放在下面链接中)

4.电流检测

由于本人不想搭模电电路,所以选用了德州仪器的电流检测芯片INA180A3IDBVR,该型号芯片可以将检流电阻上的微小电压放大100倍,使用十分方便。

4.温度检测

选用温度传感器TC1047AVNBTR,该型号芯片输出与温度呈线性关系的电压值,使用起来较为方便。

5.MCU

通过分析,MCU至少具备3路ADC(电流、电压、温度),一路DAC(控制电压),一路SPI(OLED),一路UART(扩展蓝牙)。事实上,许多单片机不具备DAC,而因为懒不想增加DAC芯片,所以选型比较受限制。最终选择STM32F103RCT6。(千万不要买RBT6,RBT6没有DAC!!!

6.OLED

没啥好说的,烂大街的0.91寸SPI OLED(中景园15脚),放个图,溜了。

三、原理图

1.电源部分

2.中控部分

3.显示部分

四、PCB部分

PCB分为三层,采用排针及FCP排线连接,方便不同模块升级及替换。

1.电源部分

2.控制部分

3.显示部分

五、说说原理

1.电压控制部分

事实上,任何一款市售的电源模块通过简单的改造均可实现数控。

5脚为电源的反馈引脚,查阅芯片手册,Vfb=1.25V,即该引脚上的电压高于1.25V,MOS管关闭,否则MOS导通,从而实现电压的控制。
分析电路可得公式:(Vo-Vfb)/R2 + ( Vdac-VF)/R6 = Vfb/R9(VF为二极管得压降)
即可得到输出电压。
在本方案中R2=4.7K,R9=91K,R6=5.6K,可实现4.5~25V的调压范围。

2.传感器(电压、电流、温度)

无非就是寻常的多通道ADC检测+多次采样平均+DMA传输。多通道ADC与DMA配置如下。


void  Adc_Init(void)
{    GPIO_InitTypeDef  GPIO_InitStructure;ADC_InitTypeDef  ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE );   //RCC_APB2Periph_GPIOx,x=GPIOxRCC_ADCCLKConfig(RCC_PCLK2_Div8);            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;   //PA0/1/2/3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                GPIO_Init(GPIOA, &GPIO_InitStructure);ADC_DeInit(ADC1);  //½«ÍâÉè ADC1 µÄÈ«²¿¼Ä´æÆ÷ÖØÉèΪȱʡֵADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC¹¤×÷ģʽ:ADC1ºÍADC2¹¤×÷ÔÚ¶ÀÁ¢Ä£Ê½ADC_InitStructure.ADC_ScanConvMode =ENABLE;        //¶àÐŵÀɨÃèģʽADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //Ä£Êýת»»¹¤×÷ÔÚÁ¬Ðøת»»Ä£Ê½ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;   //Íⲿ´¥·¢×ª»»¹Ø±ÕADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADCÊý¾ÝÓÒ¶ÔÆëADC_InitStructure.ADC_NbrOfChannel = 3;        //´Ë´¦¿ª6¸öÐŵÀ£¨¿É¿ªµÄΪ1~16£©ADC_Init(ADC1, &ADC_InitStructure);        //¸ù¾ÝADC_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèADCxµÄ¼Ä´æÆ÷//ADC³£¹æÐŵÀÅäÖÃ//ADC1,ADCͨµÀx,¹æÔò²ÉÑù˳ÐòֵΪy,²ÉÑùʱ¼äΪ239.5ÖÜÆÚADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_13Cycles5 );                ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_13Cycles5 );ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_13Cycles5 );                // ¿ªÆôADCµÄDMAÖ§³Ö£¨ÒªÊµÏÖDMA¹¦ÄÜ£¬»¹Ðè¶ÀÁ¢ÅäÖÃDMAͨµÀµÈ²ÎÊý£©ADC_DMACmd(ADC1, ENABLE);       //ʹÄÜADC1µÄDMA´«Êä         ADC_Cmd(ADC1, ENABLE);           //ʹÄÜÖ¸¶¨µÄADC1ADC_ResetCalibration(ADC1);        //¸´Î»Ö¸¶¨µÄADC1µÄУ׼¼Ä´æÆ÷while(ADC_GetResetCalibrationStatus(ADC1));        //»ñÈ¡ADC1¸´Î»Ð£×¼¼Ä´æÆ÷µÄ״̬,ÉèÖÃ״̬ÔòµÈ´ýADC_StartCalibration(ADC1);                //¿ªÊ¼Ö¸¶¨ADC1µÄУ׼״̬while(ADC_GetCalibrationStatus(ADC1));                //»ñÈ¡Ö¸¶¨ADC1µÄУ׼³ÌÐò,ÉèÖÃ״̬ÔòµÈ´ý
}                 
void DMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{   DMA_InitTypeDef DMA_InitStructure;    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA_CHx);   //½«DMAµÄͨµÀ1¼Ä´æÆ÷ÖØÉèΪȱʡֵDMA_InitStructure.DMA_PeripheralBaseAddr =  cpar;  //DMAÍâÉèADC»ùµØÖ·DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMAÄÚ´æ»ùµØÖ·DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //ÄÚ´æ×÷ΪÊý¾Ý´«ÊäµÄÄ¿µÄµØDMA_InitStructure.DMA_BufferSize = cndtr;  //DMAͨµÀµÄDMA»º´æµÄÊý¾Ýµ¥Ôª´óСDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //ÍâÉèµØÖ·¼Ä´æÆ÷²»±äDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //ÄÚ´æµØÖ·¼Ä´æÆ÷µÝÔöDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //Êý¾Ý¿í¶ÈΪ16λDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Êý¾Ý¿í¶ÈΪ16λDMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //Ñ­»·¹¤×÷ģʽDMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMAͨµÀ xÓµÓиßÓÅÏȼ¶ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMAͨµÀxûÓÐÉèÖÃΪÄÚ´æµ½ÄÚ´æ´«ÊäDMA_Init(DMA_CHx, &DMA_InitStructure);  //¸ù¾ÝDMA_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯DMAµÄͨµÀ
}

3.PID算法

算法没啥稀奇,普通PID,输入电压,调整DAC。直接放代码。

#ifndef _pid_
#define _pid_
#include "stm32f10x_conf.h"
#define     MODEL_P         1
#define     MODEL_PI         2
#define     MODEL_PID     3typedef struct
{u8 choose_model;    float curr;              float set;               //Óû§É趨ֵfloat En;                    //µ±Ç°Ê±¿Ìfloat En_1;                //ǰһʱ¿Ìfloat En_2;                //Ç°¶þʱ¿Ìfloat Kp;               //Pfloat T;                //²ÉÑùÖÜÆÚu16   Tdata;            //ÅжÏÊÇ·ñµ½²ÉÑùÖÜÆÚfloat Ti;               //ifloat Td;               //dfloat Dout;                //PIDÔöÁ¿float OUT0;                //άÎÈÊä³öu16 currdac;      //µ±Ç°dacÖµu16 daccycle;       //pwm??}PID;extern u8 STATUS;
extern PID pid;
void PIDParament_Init(void);
void pid_calc(void);                  #endif
#include "pid.h"
#include "dac.h"
#include "dac.h"
#include "led.h"PID pid;void PIDParament_Init()  //
{pid.choose_model = MODEL_PID;pid.T=50;                //¶¨Ê±Æ÷1ms ×îС²ÉÑùÖÜÆÚ330mspid.set =5.0;            //Óû§É趨ֵpid.Kp=0.4;                //±ÈÀýϵÊýpid.Ti=80;                //΢·ÖϵÊý³£Êýpid.Td=2;                //»ý·Öʱ¼ä³£Êýpid.OUT0=0;                //ά³ÖϵÊýpid.daccycle = 50;       //PWM pid.currdac=2000;
}void pid_calc()
{float dk1,dk2;float t1,t2,t3;u16 temp;
//
//    if(pid.Tdata < (pid.T))  //×îС¼ÆËãÖÜÆÚδµ½
//     {//            return ;
//     }
//    pid.Tdata = 0;pid.En=pid.set-pid.curr;  //±¾´ÎÎó²îdk1=pid.En-pid.En_1;   //±¾´ÎÎó²îÓëÉÏ´ÎÎó²îÖ®²îdk2=pid.En-2*pid.En_1+pid.En_2;t1=pid.Kp*dk1;                            //±ÈÀýt2=(pid.Kp*pid.T)/pid.Ti;      //»ý·Öt2=t2*pid.En;t3=(pid.Kp*pid.Td)/pid.T;        //΢·Öt3=t3*dk2;switch(pid.choose_model){case MODEL_P:     pid.Dout= t1;                   break;case MODEL_PI:  pid.Dout= t1+t2;               break;case MODEL_PID: pid.Dout= t1+t2+t3;        //¼ÆËãPIDÔöÁ¿break;} pid.currdac-=77.69*pid.Dout;  //Êä³ödacÖµif(pid.currdac>4090)            //УÑ鷶Χ{pid.currdac=4090;}if(pid.currdac<2000){pid.currdac=2000;}pid.En_2=pid.En_1;pid.En_1=pid.En;temp=pid.currdac;temp=(int)pid.currdac;temp=(short)temp;DAC_SetChannel1Data(DAC_Align_12b_R,temp );}

六、建模

开篇说了,要和手头华为快充配套,那自然是大小,材质一样咯。

话说立创EDA不能导出STEP是真蛋疼,三维模型折腾了好久,话说有兴趣可以开一贴,如何从立创EDA导出三维模型(很烦很烦)。

建模和渲染都是基于Solidworks.
壳体

效果图

七、制造过程

1.电源板



调压测试,最高25V.

2.主控板

平平无奇的STM32开发板

囊中羞涩的我并没有买蓝牙模块,蓝牙原计划选的是易佰特E14 BT05。

3.显示面板



显示面板焊接不要太久,我有个贼漂亮的橙色OLED被我焊的光衰了,基本看不出了字,谁有橙色0.91 SPI OLED的购买方式麻烦私我一下,谢谢啦。

八、测试

1.开机动画

2.过温保护


警报灯亮起,屏幕显示温度计图标。

3.过流保护

警报灯亮起,屏幕显示电流,输出切断。
看官老爷对不住,实在没抓拍到。

4.精度测试


输出10.10V,实测10.08~10.11浮动,可以接受,加个大电容会好一些。

5.使用测试

该表通过中键切换模式,有电流/电压、温度/功率、循环三档。
左右键选择电压,步进0.5v.

九、资料

1.PCB

https://download.csdn.net/download/YVONNEOH/12740947

2.源码

https://download.csdn.net/download/YVONNEOH/12740952

3.外壳

https://download.csdn.net/download/YVONNEOH/12740960

总结

外壳还没加工好,待更,勿催。。。
最后,在评论区评论+暗号awsl,抽一个人送一套PCB邮费自理,截止日期2020.9.10.

基于STM32的桌面数控电源项目连载相关推荐

  1. 项目篇 | 基于STM32单片机NBIOT定位实战项目

    前言 绘制基于 STM32 单片机的 NBIOT 实战项目. 文章目录 前言 一.原理图 1.绘制 1)电源供电 a.USB 转 TTL 电路 b.锂电池充电管理电路 c.3.3V电压转换电路 d.一 ...

  2. 基于STM32的四旋翼无人机项目(二):MPU6050姿态解算(含上位机3D姿态显示教学)

    前言:本文为手把手教学飞控核心知识点之一的姿态解算--MPU6050 姿态解算(飞控专栏第2篇).项目中飞行器使用 MPU6050 传感器对飞行器的姿态进行解算(四元数方法),搭配设计的卡尔曼滤波器与 ...

  3. 51单片机数控电源c语言设计,基于51单片机的数控电源

    <基于51单片机的数控电源>由会员分享,可在线阅读,更多相关<基于51单片机的数控电源(8页珍藏版)>请在人人文库网上搜索. 1.基于51单片机的数控电源摘要:学习如何以单片机 ...

  4. 基于STM32的开源简易示波器项目

    目录 ​一.前言 二.硬件接线 三.信号的采集 四.代码配置 五.数据的处理 六.模拟正弦波输出 七.模拟噪声或三角波输出 八.显示函数与按键控制 ​一.前言 该项目是基于正点原子精英板制作的一个简易 ...

  5. 基于STM32设计的校园一卡通项目

    1. 项目简介 信息时代的校园, 离不开信息化的管理, 数字化"校园一卡通"建设是校园信息化建设的重要组成部分, 是为信息化校园提供信息采集的基础工程也是获取学校信息化服务的主要方 ...

  6. 基于STM32的阿里云物联网项目实战

    引言:之前自学了一些关于阿里云物联网项目的开发,收获颇丰,但是总感觉网上的东西太散了,需要自己去不停的收集整理,于是在项目结束后决心自己写一篇比较具有实用性的指导文档,需要声明的是本文档只适合像我一样 ...

  7. 基于STM32的智能学习空调项目的定时器捕获驱动

    /*************************************************************************************************** ...

  8. 基于STM32与TB6600的机械臂项目(代码开源)

            前言:本文为手把手教学STM32的机械臂项目--Robot Arm,本次项目采用的是STM32作为MCU.该机械臂的基础模型为国外开源项目,诸多前辈经过长时间的验证与改进,其机械臂精度 ...

  9. 基于STM32与PCA9685制作四足机器人(代码开源)

            前言:本文为手把手教学基于STM32的四足机器人项目--JDY-31蓝牙控制,特别地,本次项目采用的是STM32作为MCU.四足机器人的支架为3D打印件,SG90舵机驱动机器人实现姿态 ...

最新文章

  1. Ascend Pytorch算子适配层开发
  2. 浅谈利用SQLite存储离散瓦片的思路和实现方法
  3. 线程常用方法,线程安全和同步锁
  4. Shell-实际业务操作01
  5. 【译】Writing a Simple Linux Kernel Module
  6. MxNet 模型转Tensorflow pb模型
  7. 枚举转中文,通过反射方法与描述的方式获取
  8. python twisted和flask_Python高效开发实战——Django、Tornado、Flask、Twisted(第2版)
  9. php 绘图 jpeg,PHP gd库增加jpeg支持
  10. python课程价格-python课程价格
  11. matlab蒙特卡洛法求概率,基于某MATLAB的蒙特卡洛方法对可靠度的计算.doc
  12. Linux SSH工具与wget、curl、scp命令详解
  13. 建筑工地人脸识别门禁通道闸机如何安装
  14. 太阳天顶角与太阳方位角计算
  15. carsin中创建相邻车道车辆插入场景设置
  16. office2021下载|office2021安装包配置过程图文教程
  17. 知名的网址导航网站及好用的网址导航分享
  18. UVa11134 - Fabled Rooks(贪心)
  19. 快手福虎迎春季短视频涨粉活动规则[快手获取商品详情]
  20. 常用英语食品词汇- 蔬菜类

热门文章

  1. 评测丨用数字带你综合体验海思Hi3519A开发板性能
  2. Vue 实现前端银行卡隐藏中间的数字,及隐藏姓名后两位
  3. 以计算机写一篇作文500字,有关电脑作文500字3篇
  4. 数码相框方案_索尼NEX5评测:具有视频功能的数码单反相机
  5. 佳能相机5D4死机后找不到视频文件的数据恢复案例
  6. Excel根据两个表中相同的列将其它列的数据合并在同一个表
  7. 【linux】free 命令显示 swap 信息异常处理
  8. “头腾大战”烽烟再起,飞书触犯了微信的隐私数据安全红线?
  9. 最赚钱岗位出炉,AI人才平均月薪3万;上海人才吸引力跌至第四
  10. 温故知新(十)——UART