发作品
专业版

基于PY32F002A单片机版电池內阻测试仪

5.0k
40
29
23
简介:PY32F002A单片机制作的电池內阻仪
星火计划2023
开源协议:GPL 3.0
创建时间:2023-07-31 17:10:14更新时间:2023-12-04 16:38:05

描述

在立创商城买了 一些PY32F002AF15P6TU,于是为了测试一下性能制作了一个简易电池內阻测试仪,测量范围分毫欧和欧两个档位,毫欧档测量范围显示00.00到60.00毫欧,最小分辨0.01毫欧,欧姆档位显示0.000到2.000欧,最小分辨1毫欧,测量电流20毫安。耐压主要针对单节锂电池,隔直电容选的耐压低,要测电压高点的电池要换功放输出隔直电容。

主要可以用来测电池內阻、电容ESR、电流采样电阻。

 

硬件部分

 

右边是常见的电源和显示部分就不讲了,主要介绍下左边信号部分,单片机输出一路1KHZ的PWM型号,经过RC滤波后变成正弦波,再通过c15隔直电容,电容后面抬高到VCC/2,在进入U2.1电压跟随器。

 

 

 

得到抬高到VCC/2正弦波后进入U2.2恒流电路,采样电阻为三个并联的100欧电阻,TVS保护运放,再通过四个并联的10uF电容把1KHZ交流信号注入到电池。

 

 

 

H3、H4、H5、H6端口接开尔文四线测试夹,H3、H5为电流激励端口、H4、H6为电压信号端口,通过C43、C44 100NF电容隔直电容隔离电池直流电压只取出1KHZ交流电压,电容后面抬高到1.65V,四个三极管这里当作二极管来用,漏电比二极管小。

 

接着进入三个运放组成的仪表放大器,放大倍数21倍。

 

 

 

接着进入U5模拟开关,采样先衰减后放大方式实现两个档位的切换,好处是两个档位相移一样只校准一个档位就行了,放大完直接进入单片机ADC。

 

 

 

单片机部分比较简单,PB3输出1KHZ正弦波,PA0和PA1为短接的ADC口,PB0、PA7、PA4为SPI口。 H8 SWDIO ,H9 SWCLK为SWD调试口用来调试和下载程序,PA2和PA3为按键输入口。

 

SWD调试口

H8 SWDIO ,H9 SWCLK,另外一个接GND

 

 

四线测试夹端口,功放输出+和信号想+一个夹子,负和负一个夹子。

 

软件部分

软件采用GNU ARM汇编编写,编译器ARM-NONE-EABI。

定时器输出1KHZ正弦波,PA0和PA1开两个通道的ADC采样,用另外一个定时器设置100KHZ的触发频率触发ADC采样,采样后通过DMA传输到内存,DMA采用循环模式采样1000点,SYSTICK定时器设置10毫秒中断一次,下面代码实现上面说的功能。

 

__adc_dma:
    ldr r0, = 0x40020000
    ldr r1, = 0x40012440    @外设地址
    str r1, [r0, # 0x10]
    ldr r1, = 0x20000160    @储存器地址
    str r1, [r0, # 0x14]
    ldr r1, = 1000          @传输数量
    str r1, [r0, # 0x0c]
    ldr r1, = 0x35a1 @  0x583        @ 5a1  @传输模式
    str r1, [r0, # 0x08]

_adcchushihua:
    ldr r0, = 0x40012400  @ adc基地址
    ldr r1, = 0x80000000
    str r1, [r0, # 0x08]  @ ADC 控制寄存器 (ADC_CR)  @adc校准
_dengadcjiaozhun:
    ldr r1, [r0, # 0x08]
    movs r1, r1
    bmi _dengadcjiaozhun   @ 等ADC校准
_tongdaoxuanze:
    ldr r1, = 0x20000000
    str r1, [r0, # 0x10]    @时钟分频
    movs r1, # 0x03
    str r1, [r0, # 0x28]    @ 通道选择寄存器 (ADC_CHSELR)
    ldr r1, = 0x8c3         @0x3003         @连续0x2003 @触发0x8c3 @ 0xc43         @TIM3 0x8c3 @0x2003 @0x8c3
    str r1, [r0, # 0x0c]    @ 配置寄存器 1 (ADC_CFGR1)
    movs r1, # 0
    str r1, [r0, # 0x14]    @ ADC 采样时间寄存器 (ADC_SMPR)
    ldr r1, = 0x05         @ 开始转换
    str r1, [r0, # 0x08]    @ 控制寄存器 (ADC_CR)
    str r1, [r0, # 0x08]

    @tim3chushihua:
    ldr r3, = 0x40000400 @ tim3_cr1
    ldr r2, = 0
    str r2, [r3, # 0x28] @ psc
    ldr r2, = 959
    str r2, [r3, # 0x2c] @ ARR
    movs r2, # 0x20
    str r2, [r3, # 0x04] @ TRGO

    @tim1chushiha:
    ldr r0, = 0x40012c00 @ tim1_cr1
    movs r1, # 0
    str r1, [r0, # 0x28] @ psc
    ldr r1, = 47999
    str r1, [r0, # 0x2c] @ ARR
    @       movs r1, # 0x20
    @       str r1, [r0, # 0x04] @ TRGO
    ldr r1, = 0x6800
    str r1, [r0, # 0x18] @ ccmr1  CC2
    ldr r1, = 0x10    @  CC2
    str r1, [r0, # 0x20] @ ccer
    ldr r1, = 0x8000
    str r1, [r0, # 0x44] @ BDTR
    @       ldr r1, = 0x100 @ CC2 DMA
    @       str r1, [r0, # 0x0c] @ DIER
    ldr r1, = 24000
    str r1, [r0, # 0x38]
    ldr r1, = 0x81
    str r1, [r0]
    str r1, [r3]
    ldr r4, = 0xe000e010
    ldr r3, = 479999
    str r3, [r4, # 4]
    str r3, [r4, # 8]
    movs r3, # 0x07
    str r3, [r4]    @systick 开

    ldr r0, = lvbo_changdu
    ldr r1, = lvbo_youyi
    movs r2, # 200
    str r2, [r0]
    movs r2, # 14
    str r2, [r1]

    ldr r0, = cossin
    ldr r1, = cos_sin_biao_1k
    str r1, [r0]

 

进入SYSTICK定时器中断后先用DFT算1000点数据的实部和虚部,接着各进入200点滑动滤波器

 

_systickzhongduan:        @syzd
    push {r0-r4,lr}
__suan_dft:
    bl __dft
    ldr r2, = shangbi_rr
    ldr r3, = shangbi_ii
    str r0, [r2]
    str r1, [r3]
    mov r4, r0
    ldr r2, = lvboqizhizhen1
    ldr r0, =lvboqihuanchong1
    bl __lv_bo_qi
    ldr r1, = shangbi_i
    str r0, [r1]
    mov r1, r4
    ldr r2, = lvboqizhizhen
    ldr r0, =lvboqihuanchong
    bl __lv_bo_qi
    ldr r1, = shangbi_r
    str r0, [r1]

    ldr r0, = shangbi_r
    ldr r1, = shangbi_i
    ldr r0, [r0]
    ldr r1, [r1]
    bl __ji_suan_fu_du
    ldr r2, = fudu
    str r0, [r2]

    ldr r0, = liangcheng
    ldr r2, = 0x50000400
    ldr r3, [r0]
    cmp r3, # 1
    beq __haoou_dang
__ou_dang:    
    movs r3, # 1
    lsls r3, r3, # 16
    str r3, [r2, # 0x18]
    b __systick_fanhui
__haoou_dang:    
    movs r3, # 1
    str r3, [r2, # 0x18]
    
__systick_fanhui:
    ldr r0, = 0xe0000d04
    ldr r1, = 0x02000000
    str r1, [r0]                 @ 清除SYSTICK中断
    pop {r0-r4,pc}

 

 

DFT程序采用尽量少循环写法,所以看着很长,不知道这样会不会更快,反正空间很大用不完。

 

到这里就得到了被测电池的实部和虚部两个数据,先夹住一个无感电阻,用ATAN2计算出相位,再把角度旋转到0度,只现实实部就可以了,这样就能不受到测试线电感的影响。

旋转相位方法,至于ATAN2和计算COS和SIN的方法见附件cordic.pdf

anjian3函数名到ting之间的程序就是校准程序,主要有三个校准项,短路清零、相位校准、标准电阻校准,比较长就不贴了。

 

校准方法
三个校准菜单,显示P-00是短路清零、显示P-01是相位校准、显示P-02是标准电阻校准。

按住切换档位的按键再同时按住另一个进入校准模式,数码管显示P-00,按档位加的按键会在P-00、P-01、P-02之间切换,两个按键一块按退出校准菜单显示END,按另外一个按键进入显示的菜单。

P-00 夹子短路,两个按键加减调到0,先调欧档,两个按键一块按进入毫欧档,调好后再两个按键一块按保存到FLASH 显示END

P-01 夹住1欧电阻,调到这个电阻真实相位,我也不知道就调到0了,调好后两个按键一块按保存到FLASH 显示END

P-02 夹住标准电阻把读数调到和电阻一样,也是先调欧档,两个按键一块按进入毫欧档,调好后再两个按键一块按保存到FLASH 显示END

家准演示视频,在家蹲了快16年语言能力很差还不会普通话。。。 听不懂可以点开字幕有自动生成的字幕。

毫欧档校准可以用10毫欧或者再大点的校准,校准完了后测0.1毫欧可能会偏大,再用短路清零调小就行了。

 

校准方法演示视频

https://www.bilibili.com/video/BV1g14y167Yy/?spm_id_from=333.999.0.0&vd_source=c212050d120d3457e1f6d0cd79c641de

 

实测0.1毫欧到1毫欧电阻

 

https://www.bilibili.com/video/BV1wX4y1E7tv/?spm_id_from=333.788&vd_source=c212050d120d3457e1f6d0cd79c641de

 

实物

 

 

 

 

测0.1毫欧电阻

 

测0.2毫欧电阻

 

测0.3毫欧电阻

 

测0.5毫欧电阻

 

 

 

测1毫欧电阻

 

 

 

 

 

设计图

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

BOM

暂无BOM

附件

序号文件名称下载次数
1
led_nei_zu_yi.zip
138
2
cordic.pdf
87
3
cordic ZH.pdf
91
4
测0.1毫欧到1毫欧.mp4
370
5
PY32F002A单片机版电池內阻测试仪校准方法_compressed.mp4
544
6
源代码和固件(修复一些芯片无法运行的BUG).zip
75
克隆工程
分享
0
0
添加到专辑
侵权投诉
工程成员
全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
换一批