在嵌入式电源管理系统中,模数转换器(ADC)和充电状态机是实现精准控制的两大核心模块。Microchip PIC系列微控制器凭借其丰富的外设资源和高效的指令集,成为电池管理系统(BMS)开发的理想选择。本文将基于实际工程代码,深入剖析ADC服务例程的实现细节和充电状态机的设计逻辑。
该电源管理系统采用分层设计:
关键性能指标:
ADC服务例程adc_svc()采用状态机设计,主要处理流程如下:
assembly复制adc_svc:
btfss r_adc_control, 7 ; 检测转换启动标志
goto adc_svc_x ; 未启动则退出
btfsc r_adcon0, GO ; 检查转换完成标志
goto adc_svc_x ; 未完成则退出
; 读取ADC结果寄存器
bsf r_status, RP0 ; 切换存储体
movf r_adresl, w ; 读取低字节
bcf r_status, RP0 ; 恢复存储体
movwf r_adc_raw_L ; 存储原始数据低字节
movf r_adresh, w ; 读取高字节
movwf r_adc_raw_H ; 存储原始数据高字节
关键技术要点:
r_adc_control寄存器管理转换状态,避免数据竞争r_adc_accum_count判断)原始ADC值需经过校准转换才具有物理意义。以电压通道处理为例:
assembly复制adc_svc_2:
movlw EE_CAL_ADC_2 ; 加载EEPROM中的校准系数
call load_A_ee
call math_mul_16_prep_ ; 16位乘法准备
movlw .2
call math_shift_BC ; 右移2位等效除以4
movf r_accC_H, w
movwf r_adc_2_L ; 存储转换结果低字节
movf r_accB_L, w
movwf r_adc_2_H ; 存储转换结果高字节
校准公式解析:
code复制V_actual = (ADC_raw × Calibration_Factor) / 4
其中:
Calibration_Factor存储在EEPROM中,通过EE_CAL_ADC_2地址访问系统支持5个检测通道:
通道调度采用轮询机制,由r_adc_control寄存器的位域控制:
关键技巧:在电流检测通道(通道1)中特别加入了偏移校准逻辑,可消除硬件零点漂移:
assembly复制adc_svc_1_cofs: clrf r_accB_L clrf r_accB_H btfsc flag0_mode_cofs_dis ; 检查偏移校准使能标志 goto adc_svc_1_cofs_x_ movlw r_adc_1_ofs ; 加载偏移量 call math_load_B call math_neg_B ; 取负值
系统定义7个充电状态(State 0-7),构成有限状态机:
code复制STATE-0: 充电待机
STATE-1: 充电资格验证
STATE-3: 恒流充电(CC)
STATE-4: 恒压充电(CV)
STATE-5: 充电结束(EOC)
STATE-6: 充电暂停
STATE-7: 浮充(Float)
状态转移条件由以下参数决定:
BP*:电池在位检测V > VCHG:电压阈值C < CMIN:电流阈值TI1 > TICC:恒流计时器TI2 > TISUSPEND:暂停计时器chg_state_svc()作为状态机引擎,主要实现以下功能:
assembly复制chg_state_svc:
btfss flag_chg_state_timer ; 状态定时器检查
goto chg_state_svc_x_ ; 未到期则退出
bcf flag_chg_state_timer
; 电池在位检测
bcf flag_battpres
btfss flag0_mode_bpres_v ; 电压检测模式
goto chg_state_svc_bpv_x
movlw EE_CHG_V_MIN_BP ; 加载最小电压阈值
call check_voltage
btfss r_status, C ; 比较结果判断
bsf flag_battpres ; 设置电池在位标志
状态转移通过跳转表实现,提升执行效率:
assembly复制chg_state_svc_jumptable:
movlw high $
movwf r_pclath
movf r_chg_state, w ; 加载当前状态
andlw 0x0f
addwf r_pcl, f ; 计算跳转偏移
goto chg_state_0 ; 状态0处理
goto chg_state_1 ; 状态1处理
...
状态3(CC)到状态4(CV)的转换是充电管理的核心:
assembly复制chg_state_3:
btfss flag_reg_on ; 调节器使能检查
goto chg_state_0_init ; 异常则复位
btfsc flag_chg_ti1_done ; 定时器检查
goto chg_state_6_init ; 超时转暂停
btfsc flag_vreg ; 电压调节标志
goto chg_state_4_init ; 达到电压转CV
goto chg_state_x
关键技术参数:
EE_CHG_TI_CC:恒流阶段超时阈值(EEPROM可配置)flag_vreg:由电压调节算法设置,表示达到目标电压regulate()函数实现电压电流双闭环控制:
assembly复制regulate:
; 电压比较
movlw r_adc_2_L
call math_load_B ; 加载电压值
call math_neg_B
movlw r_reg_v
call math_add_16_load_A ; 计算ΔV=Vreg-Vactual
btfss r_accB_H, 7 ; 判断差值符号
goto regulate_v_lo ; ΔV≥0
regulate_v_hi: ; ΔV<0(实际电压偏高)
bsf flag_vreg
movlw EE_REG_VH ; 加载一级阈值
call ee_read_waddr
call math_add_8b
btfss r_accB_H, 7 ; 比较阈值
goto regulate_v_x
bsf flag_vreg_1 ; 触发一级调节
控制策略采用多级响应:
PWM占空比计算采用增量式PID简化算法:
assembly复制pwm_adj:
btfsc flag_neg ; 判断调节方向
goto pwm_adj_down
pwm_adj_up:
addwf r_pwm_L, f ; 增加PWM值
btfsc r_status, C
incf r_pwm_H, f
goto pwm_adj_x
pwm_adj_down:
subwf r_pwm_L, f ; 减小PWM值
btfss r_status, C
decf r_pwm_H, f
pwm_adj_x:
; 限幅处理
movlw PWM_MAX
subwf r_pwm_L, w
btfss r_status, C
goto pwm_limit_high
...
参数整定建议:
REG_ADJ_P1:20-30(大偏差调节步长)REG_ADJ_P4:5-10(小偏差调节步长)PWM_MAX:根据功率器件特性设置由于PIC16系列无硬件乘法器,需软件实现16位运算:
乘法算法(math_mul_16):
assembly复制math_mul_16:
movwf r_count_1 ; 初始化计数器(16次)
clrf r_accB_H ; 清空结果寄存器
clrf r_accB_L
math_mul_16_loop:
rrf r_accD_H, F ; 右移乘数
rrf r_accD_L, F
btfss r_status, C ; 检查最低位
goto math_mul_16_shift
call math_add_16 ; 加被乘数
math_mul_16_shift:
rrf r_accB_H, F ; 右移结果
rrf r_accB_L, F
decfsz r_count_1, F
goto math_mul_16_loop
运算时间分析:
温度检测采用分段线性化处理,结合LUT提升精度:
assembly复制therm_index:
addlw EE_T_LUT_MB ; 计算LUT基地址
call ee_read_ia ; 读取斜率参数
movwf r_accB_L
call ee_read_ia
movwf r_accB_H
call math_mul_16_prep_ ; 计算TSCALE'×M
movlw .5
call math_shift_BC ; 规格化处理
call ee_read_ia
movwf r_accA_L ; 加载截距参数
call math_add_16 ; 最终温度=斜率×ADC值+截距
LUT配置建议:
ADC采样优化:
adc_start中插入固定延时(ADC_TAQ)保证采样保持时间软件滤波:
EE_REG_CNULL零区阈值状态机调度:
assembly复制chg_state_svc:
btfss flag_chg_state_timer
goto chg_state_svc_x_ ; 未到处理周期时跳过
... ; 减少不必要的运算
外设管理:
reg_off)三点校准法:
在线调试接口:
c复制// 通过UART输出关键参数(伪代码)
printf("V=%.2f I=%.3f State=%d",
adc_2*V_SCALE,
adc_1*I_SCALE,
chg_state);
现象:采样值跳动大或固定为0/1023
解决方案:
assembly复制; 增加采样保持时间示例
adc_start:
movlw ADC_TAQ+5 ; 原基础值+5个周期
movwf r_temp_1
现象:充电过程停滞在某一状态
flag_chg_state_timer是否正常翻转flag_adcset_0_rdyADC就绪标志修复示例:
assembly复制; 增加看门狗复位
chg_state_svc:
clrwdt ; 清除看门狗
btfsc flag_timeout ; 自定义超时标志
goto chg_state_0_init ; 强制复位状态机
现象:输出波动或无法调节
配置建议:
assembly复制pwm_set:
bsf STATUS, RP1 ; 访问Bank2
movf r_pwm_L, w
movwf PWM_DUTY_L ; 写入占空比低字节
bcf STATUS, RP1 ; 恢复Bank0
通过上述深度解析可见,PIC微控制器的ADC服务和充电状态管理需要硬件外设、算法实现和系统设计的紧密配合。实际项目中建议:
这种设计方案已成功应用于多款工业电池管理设备,实测充电效率可达92%以上,电压控制精度±0.5%。开发者可根据具体需求调整状态转移阈值和PID参数,适配不同电池类型和应用场景。