发作品签到
专业版

多功能触屏焊台

工程标签

1.7w
0
0
66

简介

基于gd32f470设计的多功能表以及基于at32f403a设计的多合一焊台,两者可通过磁吸插座进行连接,实现触屏焊台功能。

简介:基于gd32f470设计的多功能表以及基于at32f403a设计的多合一焊台,两者可通过磁吸插座进行连接,实现触屏焊台功能。
星火计划2024

开源协议

CC BY-NC-SA 4.0

创建时间:2024-06-21 02:59:51更新时间:2024-10-24 04:27:33

描述

【MFT】多功能触屏焊台

实物1.jpg

该工程是一个集多功能与一体的实验工具,实际可分为多功能焊台和多功能表2块,内容较多所以单独分为2章篇幅来讲。

视频链接:【开源】4寸触摸屏焊台,有点奇怪的设计!!!

通过本工程,我巩固了(你可以学到)哪些知识?

  • Arm核CortexM4相关外设的使用,GD32F470系列以及AT32F403A系列基础库的使用。
  • 嵌入式系统软件分层设计框架
  • FreeRTOS的实际使用。
  • LVGL的类Android界面的设计。
  • 常用的硬件电路(运放、MOS、DCDC等)。

警告】本项目有涉及到220V市电请谨慎操作!!!提醒想复刻的同学,没有相关基础知识的不建议复刻该项目!!!

开源协议

本工程依据“CC-BY-NC-SA 4.0”知识共享许可协议,请勿用于商用,转载时请标明出处。

开源代码:https://gitee.com/yllff/fl_aio_welding_station 【后续代码更新可查看该链接】

项目属性

本项目为首次公开,为本人原创项目。项目未曾在别的比赛中获奖。

项目更新

2024/10/03 发布工程。
2024/10/06 修复已知硬件问题,发布V2版本,未打板验证
2024/10/24 V2版本已验证,IO引脚有变化,最新的适配代码https://gitee.com/yllff/fl_aio_welding_station

项目待更新

- 修复已知硬件问题,【当前硬件通过飞线解决,待下版本更新,想复刻的同学不要着急打板!!】

  • 多功能表UI优化
  • SD卡 读卡器功能
  • 加热台多段可调模式

【多功能表】

项目介绍

多功能表集成了示波器、万用表以及信号发生器这四个功能,主控采用GD32F470ZGT6,配备了一块4寸电容触摸屏,分辨率480X480,内置一块1100MAH锂电池。整体尺寸为86mmx86mmx15mm(长x宽x高)。

项目参数

交互方式:4寸TFT液晶屏,480x480分辨率、3颗轻触开关
电源输入接口:Type-C座、5V1A,磁吸插座
示波器参数:MCX接口,采样率2MSa/s,带宽10MHz
信号发生器参数:MCX接口,输出频率 1KHz-100KHz(50K以上软件有冲突,待解决),峰峰值0-10V,支持正弦波/方波/三角波/锯齿波
万用表参数:XT30*2,电阻挡0-40MΩ ±1%,电压V挡±200V ±1%,电压mV挡±2000mV ±1%,电流挡±10A ±1%,支持通断和二极管测量

1.硬件

为了多功能表(以下简称表)尽可能的薄,设计成只有一块PCB板,接口也用了比较扁的插件。主控采用GD32F470ZGT6,因为要驱动4寸的RGB屏,所以添加了一片sdram,型号为W9825G6KH-6I,32MB16bit。屏幕通过FPC座连接。电压电流等测量通过继电器切换,经过运放后传入到CS1237芯片,CS1237是一颗高精度、低功耗、24-bit Sigma-Delta模数转换芯片,常用于电子秤、便携式设备等场合。CS1237与GD32F470ZGT6通过SPI接口进行通讯。固件烧录口在背面,标有V[VCC]D[DIO]C[CLK]G[GND]

3d-core.jpg

1.1框架

电源可以通过Type-C口或者磁吸插座接入,锂电池充电芯片采用tp4056,支持最大1A电流。
示波器框架.jpg

内部电源框架如下图所示,将电池电压升压到6V后再转成多路电压供测量电路使用。
示波器电源框架.jpg

1.2结构

该表结构比较简单,电容屏直接粘在上框中,后盖四颗M2螺丝固定。示波器以及信号发生器探头都是XMC型,电压电流测量接口是XT30型,用这两种类型的接口能一定程度降低整机的厚度。

3d-表结构.jpg
背面有一个4p磁吸式连接器(pogo pin),用来和焊台通讯,同时能通过焊台给表充电。除了磁吸连接器,我还分别在背面盖板以及焊台侧面内部加了两片直径10mm的磁吸片,用来加强吸力,背面盖板上的凸起部分与焊台侧面散热孔可以卡住,承受部分重力。

表磁吸位置.jpg

1.3原理分析

1.3.1 电源

表内置一块电池,在不使用的时候需要关机,MOS管Q2用于断开电源,图中可看到MOS管由PWEON标识的IO引脚控制,当SW1按键按下时,Q2导通MCU上电,MCU会将PWRON引脚拉低,松开SW1键后Q2仍处于导通状态。在运行过程中,长按SW1键进入关机界面,MCU控制PWRON引脚拉高,断开Q2。需要注意的是Vbat的电压一般在3.7-4.2V,PWRON引脚必需设置为开漏输出,并且要选择耐压5V的IO引脚。
开关机电路.jpg
电池电压通过SX1308升压到6V,再分别转出5V,2.5V,-5V,-2.5V用于测量电路用,转出3.3V用于核心电路供电。

表电源1.jpg
表电源2.jpg

1.3.2 示波器原理

示波器这块参考了官方示波器扩展板,里面有详细原理讲解。

1.3.2 信号发生器原理

信号发生器通过MCU的DAC先产生周期性模拟信号,比如“三角波”、“正弦波”、“矩形波”等,此时信号在0-3.3V之间,再通过一个仪表放大电路放大到-5V~+5V,信号最大幅值为10V。S_VREF_PWM是一路PWM转DAC,用来做偏压将信号下拉。U25可用来选择1倍和1/20衰减通道。

信号发生器.jpg

1.3.3 电阻电压电流测量切换

使用了2个继电器来切换测量通道,电压和电阻测量使用同一接口,电流测量单独一个接口。通道选择如下:

  • 电压V档 【RLY4】的[2,3]接通,【RLY3】的[6,7]接通
  • 电压mV档 【RLY4】的[2,3]、[6,7]接通,【RLY3】的[6,5]接通
  • 电压A档 【RLY4】的[6,5]接通,【RLY3】的[6,5]接通
  • 电压R档 【RLY4】的[4,3]接通
    测量通道切换.jpg

1.3.4 CS1237通讯

cs1237与MCU之间通过SPI接口通讯,CS1237的是5V供电,需要设计电平转换电路。CLK引脚设置为开漏输出,并上拉电阻到5V。DOUT引脚也设置为开漏输出,DIN引脚设置为下拉,当DOUT输出电平低时CS1237的DOUT引脚被拉高,当输出电平高时CS1237的DOUT引脚被DIN引脚的下拉电阻拉低。当需要读取CS1237的DOUT引脚时,将DOUT拉高开漏,从DIN引脚读入数据。同样的这些IO要求5V耐压。
cs1237.jpg

2.软件

按照惯例,这里使用的是FreeRTOS+LVGL,IDE使用Keil5.38

2.1 GUI设计

推荐大家使用SquareLine Studio+CodeBlocks来开发GUI界面,先用SquareLine Studio来快速设计出原始UI界面,再导入到CodeBlocks在PC端模拟调试,最后再导入到keil中编译下载到MCU调式。这样能够节省大量时间。
squareline.jpg
我们可以将多个界面先大致设置好,如果你是免费用户,要设计的界面超过5个,可以多创建几个工程。【另外有些函数或者动画不知道怎么用可以在这里设置好生成.c文件查看】

codeblocks.jpg
CodeBlocks可以直接模拟代码,如果稍微有些代码需要调整可以先用CodeBlocks模拟调整,节省编译时间。

2.1.1 UI框架交互

表用了一块电容触摸屏,我准备设计一个类似android系统的UI框架,目前只实现app点击跳转进入应用。这个屏幕分为了3部分:主体、状态栏、消息框,为了节约ram,界面切换的更新都在主体中,当进入新应用时会delete之前主体里的控件。状态栏包含一个返回按键,点击会退出应用到主界面。
ui框架.jpg

//--ui_statusbar.c
static void btn_homeback_click(lv_event_t *e)
{
    if(ui_main_screen.app_close!=NULL) {
        ui_main_screen.app_close();
        ui_main_screen.app_close = NULL;
    }
    lv_obj_del(ui_main_screen.current_desktop);
    ui_main_screen.current_desktop = lv_homepage_load();
}

//-- ui_homepage.c
static void homepage_icons_click(lv_event_t *e)
{
    lv_obj_t *screen;
    ui->page_select = lv_tabview_get_tab_act(ui->tabview);
    app_icons_data_t * app = (app_icons_data_t *)(e->user_data);
    if(app->open!=NULL) {
        lv_obj_del(ui->screen);
        ui_main_screen.current_desktop = app->open();
        ui_main_screen.app_close = app->close;
    }
}

2.1.2 app应用

目前只设计了4个应用,分别为焊台示波器万用表信号发生器。各应用界面如下:

应用1.jpg
应用2.jpg
焊台应用在连接上焊台后才能有效操作,初始进入应用显示烙铁等加热装置的一些参数状态,左滑可以到数控电源界面。其他一些操作可查看附件测试视频。
应用3.jpg

2.2 分层设计框架

为了提高代码的可维护性可复用性以及稳定性,我们需要对代码进行架构分层设计。这里的复用不是说复制一段代码到另一个应用中,而是不修改整个源文件。 像官方提供的基础库,我们基本是不会修改它的,一个源文件只有在不被修改的情况下才能最大限度的保证稳定性。在设计中我们遵循低耦合高内聚,调用尽量由上层调用下层,不越层调用。当然实际编写过程中也要考虑复杂程度,不要过于分层导致代码更加繁琐。这里我将整个工程分为了应用层、板级层、中间件层、设备层、MCU驱动层。其中设备层我又分为了设备应用层和设备驱动层。图中为了方便观看,有些层不是上下级,像设备应用层和中间件层有相互调用。
分层设计.jpg
按照可复用性我将这些层归类成3部分,中间件层和MCU驱动层属于第三方库,应用层和设备应用层不依赖于特定硬件,板级层和设备io驱动层依赖于特定硬件和板卡。如果MCU或者外设更改了一般只需更换设备io驱动层和板级层。
代码文件结构.jpg
一个设备可以分为硬件相关驱动和应用驱动,可以将硬件相关驱动部分单独划分出来,这部分跟具体的MCU驱动相关。比如CS1237驱动,将硬件相关的函数设计成一个结构体:

typedef struct
{
    void (*init)(void *base);
    void (*clock)(void *base, uint16_t time);
    void (*set_dir)(void *base, uint8_t dir);
    void (*write_bit)(void *base, uint8_t bit);
    uint8_t (*read_bit)(void *base);
    void (*int_enable)(void *base, uint8_t enable);
}cs1237_bus_t;

在cs1234_t结构体中声明一个cs1237_bus_t指针以及一个void *句柄指针,在使用前绑定对应的驱动即可。这样在device应用代码中就可以不关心具体硬件实现。如果更换了MCU,只需要重新编写一份cs1237_bus.c实现cs1237_bus_t内的函数即可。

typedef struct
{
    void *bus_handle;
    cs1237_bus_t *bus;
    CS1237_REG reg;
    uint8_t initial;
    int32_t data;
}cs1237_t;

//--board.c, void board_init(void)
    cs1237_handle.io_clk.port = hal_port(PB, 3);
    cs1237_handle.io_in.port = hal_port(PB, 4);
    cs1237_handle.io_out.port = hal_port(PB, 5);
    cs1237_handle.irqn = EXTI4_IRQn;
    dev_connect(&board.adc_dev, &cs1237_handle, &cs1237_3line_bus);
    cs1237_init(&board.adc_dev, kCS1237_SPEED_40Hz, kCS1237_PGA_1);

3.1 使用说明

表配备了3颗按键:电源键上键下键,按下电源键表开机,点击界面图标进入应用。按下电源键3S弹出关机界面,可选择“关机”、“重启”。在万用表应用中,按下键可归零。具体使用查看附件视频。


【多合一焊台篇】

项目介绍

焊台集成了电烙铁(T12|JBC210|JBC245)热风枪加热台以及数控电源这四个功能,采用220VAC供电,内置了一个200W开关电源。电烙铁和热风枪通过航插连接,加热台通过XT30PW(2+2)-M接口连接。数控电源通过3mm香蕉插座接出。整体结构为立式,带一个易更换底座。整体尺寸为92mmx52mmx132mm(长x宽x高)。

项目参数

交互方式:1.54寸TFT液晶屏,240x240分辨率、3颗轻触开关,4颗带灯按键
电源输入接口:品字形三插 【220VAC】
电源输出接口:香蕉座(可调电源输出),Typec座(5V1A输出)
控温接口:5芯航插(电烙铁)、8芯航插(热风枪)、XT30PW(2+2)-M(加热台)
可调电源输出范围:1-36V,0-7A

1.硬件

焊台共有2块PCB板,我分别称其为显示板和功率板。主控使用AT32F403ARGT7,数控电源控制ic使用sc8701。电路原理比较简单基本是以前设计过的,也有很多开源的项目。这里我主要是把这些电路整合起来,然后在结构上做一些新的设计,使得内部紧凑和接线简洁。PCB板3D图如下:

3d-power.png

3d-panel.png

1.1框架

因为需要使用到24VDC以及220VAC电源,就内置了一个200多W的开关电源,这里没有使用PD供电这种方案。电源我买的成品,某宝链接(无广告成分):24V8A9A225W宽电压开关电源板PFC+LLC医疗工控稳降压模块H225S24
选这个主要是考虑了功率以及尺寸因素,该店铺还有一款180W的电源尺寸兼容,如果不在使用电烙铁的同时打开数控电源输出大功率电可以选择那款。

焊台框架.jpg

1.2结构

作为星火项目,外壳我还是倾向于cnc,开关电源贴在侧面安装也有利于散热。底座选择了3D树脂打印(因为面板上带有一颗蓝牙芯片,功能后续开发)。顶部盖板采用亚克力材料设计。

焊台3d2.jpg
整体为立式结构,为了合理利用内部空间,我将所有接口通过前后下三面引出,接口都为板上插件这样就节省了内部接线。
3d-接口.png
底座主要起了固定、配重以及接口转接的作用。从上图可以看到电烙铁和热风枪接口其实是通过板上的3.5mm间距端子排引出,然后在底座内部做转接到航插座上。你可以根据个人爱好来设计底座,把航插位置移动到其他几面,或者直接使用板上的端子插头,这样可以减低底座高度。

焊台仰视图.jpg
电烙铁航插定义

引脚定义
1加热 V-
2ID
3睡眠 sleep
4温感 temp
5加热 V+

热风枪航插定义

引脚定义
1温感 temp+
2温感 gnd
3风扇 Fan+
4风扇 Fan-
5磁控 sleep
6加热 L
7加热 N
8大地 EGND

1.3原理分析

1.3.1 供电设计

接入功率板的电源有两路分别为24VDC和220VAC,24VDC用来给整个电路板供电以及几路风扇和电烙铁的输出,220VAC用来做加热台和热风枪的输出。24V电源从板上的焊接端子接入,可以看到内部设计的结构里电源线从开关电源到板上端子的距离很近,不过设计的时有点失误,VCC和GND有交叉。

power-电源接线.png
另外还有1对220VAC电源线需要接到开关电源上,所以可以说内部需要接线的一共只有6根线

power-电源设计.png
上图为功率板部分电源电路,U7是TVS管放在电源输入口用于抑制瞬态过电压,Q6是一只PMos管做反接保护用,当电源正接入时VGS有整偏MOS导通,反接时断开。相对于直接使用二极管能有效降低功耗。这里因为知道接入的电压不会超过27V所以没有加稳压管防止MOS栅极电压过高损坏。U6是一颗降压DCDC芯片,可持续输出3.5A电流,将24VDC电压转换为5V后用于给整个核心供电,外接Type-c口输出以及通过磁吸接口给触屏多功能表充电。充电电流最高可有1A,type-c口输出限制1A,其余容量用作内部核心用。

panel-5V输出.jpg
5V电源通过FPC软排线接到面板上,再通过SY6280AAC输出到Type-c口。当检测到外部有受电设备接入时,Q6导通输出使能。R47用于输出电流限制,Ia=6800/R47Ia=6800/R47

1.3.2 PWM输出

单独写一段PWM是因为这个工程运用了大量的PWM IO引脚,PWM英文全称Pulse-Width Modulation也叫脉冲宽度调制,是一路周期性的方波,主要参数有频率占空比。在AT32F403A中,标有TMRX_CHX的引脚都可作为PWM输出,但你要注意与其他外设的冲突,比如使能了SPI4外设,并设置了复用为SPI4_GMUX_0010,那么PB6将被复用为SPI4_CS而不能作为TMR4_CH1来使用。另外当你使用同一个TIMER里的多个通道输出PWM时,它们的频率是指向同一个寄存器的。

pwm向上计数模式A.jpg
一般常用的ARM核MCU的PWM输出基本都有AB两种模式以及向上向下两种计数方式,通过组合可以设计出不同的PWM输出逻辑,我这里使用的是模式A向上计数,当CXDTT>CVAL时输出高电平,否则输出低电平。在使用时你会发现PWM输出在占空比为0或100时并没有完全关断导通,这是因为选择模式和内部逻辑的因素。可以在代码中判断若占空比为0或者100时把IO引脚设置为普通GPIO模式来输出高电平或低电平。或者使用AT32F403A的强制输出模式,直接设置对应寄存器来输出高低电平。

强制输出模式.jpg
PWM是TIMER中一种常用的功能,还有很多有意思的用法像编码器模式、输入捕获等可以查看对应的用户手册了解。在本项目中PWM用来驱动蜂鸣器、LED、模拟DAC以及驱动MOS管等。

  • 驱动LED
    一般我们直接用IO口驱动LED,设计逻辑当IO输出0时LED亮,反之LED灭。如果想改变LED亮度可以通过PWM来驱动,调解PWM的占空比,相当于控制了功率输出,在一定的频率下人眼看到的就是LED的亮度变化。如果将占空比定时由低变高再变低,表现出来的就是常见的呼吸灯模式。相对于简单的亮灭表现,PWM控制的LED可以表示更多的参数比如烙铁的输出占空比,温度的高低情况等。板上配备了3颗用PWM控制的LED分别对应了电烙铁、热风枪和加热台。
  • 驱动蜂鸣器
    板上用的是贴片式外部驱动蜂鸣器,需要用PWM驱动三极管进而来驱动蜂鸣器,可以参考手册一般是4KHz的频率,改变频率可以调节蜂鸣器音调,改变占空比可以调节蜂鸣器响声。
  • 模拟DAC
    当你需要输出一路模拟信号并且变化频率极低的时候,可以通过PWM IO引脚来模拟,将PWM转为幅值比较精确的PWM后再通过二阶低通滤波,输出的信号等效为一定的模拟量,再通过跟随器降低输出阻抗。
    power-dac.jpg
  • 驱动MOS管
    通过PWM来控制输出功率,需要注意VGS的电压不要超过MOS管的工作电压,图中R2、R6通过分压使得Q1的VGS在13V左右。
    驱动MOS.jpg

1.3.3 ADC采集

采集烙铁、风枪以及加热台的温度,是将温度通过热电偶转换成小电压信号,再将小信号通过运放电路放大传入到MCU的ADC引脚进行采样。需要注意的是如果使用T12电烙铁,其测温元件是串在加热芯上的,需要先停止加热并等待信号稳定后再进行采集,并且需要D1来限制加热时的24V电压传入运放。
烙铁温度采样.jpg
烙铁接线添加了ID引脚用来检测烙铁类型,可以在不同类型的烙铁手柄上接入不同的电阻,由MCU采集ID引脚上的电压来识别烙铁。
烙铁ID.jpg

1.3.4 数控电源

原理与之前的迷你数控电源项目类似,这里不再细讲。相对于之前的修改了输出反馈电阻和电容耐压,将输出上限改到了36V。

1.3.5 加热电路

如上。

2.软件

按照惯例,这里使用的是FreeRTOS+LVGL,IDE使用Keil5.38,上位机工具用的qt 5.14.1编写。

2.1 GUI设计

查看【多功能表篇】。

2.2 分层设计框架

查看【多功能表篇】。

2.3 PID控制调节

PID控制就是根据系统的误差,利用比例P、 积分I、微分D计算出新控制值再进行控制,周期性的计算误差值更新控制值。加热装置一般使用增量式PID,也就是每次根据误差值来计算出需要增加的控制量叠加到上次的控制量上。
公式:Δu=Kp((e0e1)+Kie0+Kd(e02e1+e2)Δu = Kp*((e0-e1)+Ki*e0+Kd*(e0-2*e1+e2)
网上有很多参考资料,推荐大家看看这位UP的视频讲的特别详细,PID零基础入门教程
如果你和我一样不是特别了解如何计算PID参数,那么就根据实际情况一步一步调整。我编写了一个上位机软件用来查看实时波形和各路误差量以及PID值调整,首先将I值D值设为0只设置P值,调整到接近设定值并且不会往上飘,这时候你会看到实际温度可能低于目标值,下图是P=30,I=0,D=0时的温度波形图。
p30id0.jpg
再设置I值消除稳态误差让其稳定到目标值,再稍微给点D值。重新降温再上升,看看有没过冲,能不能接受。不能在稍微调整下PID,下图是P=30,I=0.015,D=0.05时的温度波形图。
p30i0.015.jpg
当波形不稳定时可参考各路误差值波形,下图是P=30,I=0.008,D=0.05时的温度波形图。
p30i0.08.jpg

2.4 FreeRTOS任务

FreeRTOS在嵌入式操作系统中算是比较常用的一种,作为一个轻量级操作系统,它包含了任务调度、时间管理、内存管理、信号量传递等基本功能。目前大部分的MCU主频和ROM都能够充足的运行FreeRTOS。
我建立了几个任务,其中GUI任务优先级最低,将空闲时间都用来刷新GUI。
焊台任务.jpg
此外电烙铁和热风枪输出控制放在了一个中断里,后续会介绍。
代码中使用事件组来触发一些事件,任务等待事件时会挂起,调度会运行其他任务,避免浪费时间。比如Task_Comm任务中,我们可以等待接收到串口数据完毕事件发生,再进行下一步。

void task_comm(void * para)
{
    int32_t received = 0;
    int32_t result; 
    commApplyInit(&commApply, tx_master_data);
    commApply.send = task_comm_send;
    while(1)
    {
        board_uart_IdleReceive(0, rx_master_data, 280, &received, pdMS_TO_TICKS(50));
        if(received>0) //处理数据
        {
            result = protocol_decode(&commApply, rx_master_data, received);
        }
    }
}

任务调用board_uart_IdleReceive()函数,该函数会调用xEventGroupWaitBits()来等待事件发生,而在串口中断函数里会将事件置位。

int board_uart_IdleReceive(uint8_t com_num, uint8_t *buffer, uint32_t length, int32_t *received, TickType_t xTicksToWait)
{
	EventBits_t ev;
    uint32_t bytesCurrentReceived = 0;
    board_uart_handle_t *handle = &board.serial[com_num];
    if (NULL == handle->base)
    {
    	*received = 0;
        /* Invalid handle. */
        return kHalStatus_Fail;
    }

	ev = xEventGroupWaitBits(handle->rxEvent, RTOS_UART_IDLELINE, pdTRUE, pdFALSE, xTicksToWait);
	if(ev&RTOS_UART_IDLELINE)
	{
        bytesCurrentReceived = ring_buff_read(&handle->rx_ring_buff, buffer, length);

        if(bytesCurrentReceived>0)
        {
            *received = bytesCurrentReceived;
            return kHalStatus_Success;
        }
	}
	*received = 0;
	return kHalStatus_Fail;
}

2.5 ADC采集

项目需要采集多路ADC通道,我使用顺序模式单次采样,软件触发,即手动触发一次进行一次顺序采集就停止。因为T12烙铁在采集温度ADC时需要提前关闭输出,如果使用死等方式就显得浪费MCU时间,所以我用TIM4以及DMA配合使用,当TIM4_OC4计数溢出时关闭烙铁,当TIM4溢出中断时使能ADC,当DMA传输完成中断表示ADC已经采集完毕,就可以调用相关计算函数。不使用定时器触发ADC是因为可触发的定时器全被用做PWM输出了。逻辑顺序图如下:

焊台ADC时序.png
这种中断方式可以尽可能的节约出MCU的时间,继而用来做其他任务。

void TMR4_GLOBAL_IRQHandler(void)
{
    if(tmr_interrupt_flag_get(TMR4, TMR_C4_FLAG) != RESET)
    {
        /* clear tmr2 channel1 interrupt pending bit */
        tmr_flag_clear(TMR4, TMR_C4_FLAG);
        board_pwm_out(kBoardPWM_Solder, 0);//关闭烙铁电源
    }
    else if(tmr_interrupt_flag_get(TMR4, TMR_OVF_FLAG) != RESET)
    {
        /* clear tmr2 channel1 interrupt pending bit */
        tmr_flag_clear(TMR4, TMR_OVF_FLAG);
        adc_ordinary_software_trigger_enable(ADC1, TRUE);//启动ADC采样
    }
}

//ADC DMA
void DMA1_Channel1_IRQHandler(void)
{
    if(dma_interrupt_flag_get(DMA1_FDT1_FLAG) != RESET)
    {
        dma_flag_clear(DMA1_FDT1_FLAG);
        board_pwm_out(kBoardPWM_Solder, app_dev.out.solder.value);//恢复烙铁PWM输出
        task_solder(10);
        task_gun(10);
        device_wave_cnt();
    }
}

2.6 模拟EEPROM

有一些数据需要断电后仍保存,一般是外置一个EEPROM或者flash。如果要保存的数据比较少并且不是特别频繁的擦写,我们可以将MCU内部的Flash中的一部分模拟成EEPROM来操作。一般我们取Flash的末尾段来模拟,读取的代码比较简单对绝对地址的指针进行读就行。

void board_memory_read(uint32_t read_addr, uint8_t *p_buffer, uint16_t num_read)
{
    uint16_t i;
    for(i = 0; i < num_read; i++) {
        p_buffer[i] = *(uint8_t*)(read_addr+BOARD_EEPROM_BASE);
        read_addr++;
    }
}

擦写时需要先解锁Flash,再将地址所在段读出,如果是0xff可以直接写入,否则先擦除再写。

hal_status_t board_memory_write(uint32_t write_addr, uint8_t *p_buffer, uint16_t num_write)
{
  uint32_t offset_addr;
  uint32_t sector_position;
  uint16_t sector_offset;
  uint16_t sector_remain;
  uint16_t i;
  flash_status_type status = FLASH_OPERATE_DONE;
 
  flash_unlock();
  offset_addr = write_addr;
  sector_position = offset_addr / BSP_FLASH_SECTOR_SIZE;
  sector_offset = offset_addr % BSP_FLASH_SECTOR_SIZE;
  sector_remain = BSP_FLASH_SECTOR_SIZE - sector_offset;
  if(num_write <= sector_remain)
    sector_remain = num_write;
  while(1)
  {
    board_memory_read(sector_position * BSP_FLASH_SECTOR_SIZE, flash_buf, BSP_FLASH_SECTOR_SIZE);
    for(i = 0; i < sector_remain; i++)
    {
      if(flash_buf[sector_offset + i] != 0xFF)
        break;
    }
    if(i < sector_remain)
    {
      /* wait for operation to be completed */
      status = flash_operation_wait_for(ERASE_TIMEOUT);
     
      if((status == FLASH_PROGRAM_ERROR) || (status == FLASH_EPP_ERROR))
        flash_flag_clear(FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
      else if(status == FLASH_OPERATE_TIMEOUT)
        return kHalStatus_Fail;
      status = flash_sector_erase(sector_position * BSP_FLASH_SECTOR_SIZE + BOARD_EEPROM_BASE);
      if(status != FLASH_OPERATE_DONE)
        return kHalStatus_Fail;
      for(i = 0; i < sector_remain; i++)
      {
        flash_buf[i + sector_offset] = p_buffer[i];
      }
      if(memory_write_nocheck(sector_position * BSP_FLASH_SECTOR_SIZE, flash_buf, BSP_FLASH_SECTOR_SIZE) != kHalStatus_Success)
        return kHalStatus_Fail;
    }
    else
    {
      if(memory_write_nocheck(write_addr, p_buffer, sector_remain) != kHalStatus_Success)
        return kHalStatus_Fail;
    }
    if(num_write == sector_remain)
      break;
    else
    {
      sector_position++;
      sector_offset = 0;
      p_buffer += sector_remain;
      write_addr += sector_remain;
      num_write -= sector_remain;
      if(num_write > BSP_FLASH_SECTOR_SIZE)
        sector_remain = BSP_FLASH_SECTOR_SIZE;
      else
        sector_remain = num_write;
    }
  }
  flash_lock();
  return kHalStatus_Success;
}

2.7 上位机软件

我用qt编写了一个上位机软件,主要用来设置参数以及校准,也可以读取测量值和绘制实时波形。
目前上位机通过串口方式通讯,焊台正面有一个type-c口用来提供5V1A的电源,我复用了这个type-c口,在MCU侧代码里通过USB虚拟出一个串口与上位机进行通讯。然后自定义了一套通讯协议,用来收发数据,这样之后的一些设备如果套用这个通讯协议也可以直接使用这个上位机软件。

上位机主界面.jpg
选择好串口号后点击连接即可进行后续操作,以下是波形界面和校准界面。

上位机波形界面.jpg

上位机校准界面.jpg
这个上位机软件也提供了完整的源码,不过C++不是特别熟练,写法偏面向过程。如果感兴趣的同学多我再仔细写个使用文档。

上位机代码界面.jpg

3.1 使用说明

焊台带有4颗带灯按键,分别对应电烙铁、热风枪、加热台、数控电源。点击一次开启对应功能,再点击一次关闭对应功能。焊台保留了波轮开关以及按键,可以单独进行参数设置操作,不过这块代码我没写。目前我是将多功能表吸在焊台上,打开焊台app应用在上面操作。

整机.jpg


项目参考

项目中参考了以下资料,非常感谢以下作者!可能有些看过忘了,若有看到请务必私信我添上,再次感谢!
开源作者硬木课堂 AFE03示波器信号源扩展板
开源作者zyqsdv 【立创*梁山派】便携式多功能示波器/仪表
开源作者立创开发板 【示波器扩展板】
csdn博主PegasusYu STM32配置读取双路24位模数转换(24bit ADC)芯片CS1238数据
B站UP等角螺线 PID零基础入门教程

其他

第一版硬件有点问题,自己飞线,第二版已发布但未打板验证,想复刻的可以尝试打V2版本!!!
主代码后续更新会提交到gitee,会不定期维护该工程。
开源代码:https://gitee.com/yllff/fl_aio_welding_station
QQ讨论群:334607120

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
squareline stdio工程.zip
449
2
codeblocks-v8.3-工程.zip
582
3
表-3d源文件.zip
483
4
上位机源代码-HeaterAssist.zip
345
5
焊台-3d源文件.zip
641
6
电流挡位.mp4
153
7
电压挡位.mp4
186
8
示波器测信号发生器波形.mp4
118
9
开关机各应用界面.mp4
163
10
信号发生器.mp4
92
11
电阻挡位.mp4
161
12
调压.mp4
103
13
限流.mp4
84
14
热风枪.mp4
112
15
加热台烙铁.mp4
177
16
多功能触屏焊台整机Bom清单.rar
430
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

全部评论(1)
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航