基于 PIC16F676 的自动稳压器设计

基于 PIC16F676 的自动稳压器设计

一、系统总体设计

1.1 功能需求

1.2 系统框图

┌─────────────────────────────────────────────────────────────┐
│                    PIC16F676 自动稳压器系统                 │
├─────────────────────────────────────────────────────────────┤
│  输入电源    │  PIC16F676  │  调整电路    │  输出电源    │
│             │             │             │             │
│  AC 220V    │  • ADC采样   │  • PWM控制   │  • DC输出   │
│  ↓整流滤波  │  • 比较器    │  • 驱动电路  │  • 负载     │
│  DC输入     │  • PWM输出   │  • 开关管    │             │
│             │  • 保护逻辑  │             │             │
└─────────────────────────────────────────────────────────────┘

二、硬件设计

2.1 PIC16F676 引脚分配

PIC16F676 (8引脚 SOIC/DIP)
┌─────────────────────────────┐
│        VDD (Pin 1)          │ ← 5V电源
│        GP5/AN4 (Pin 2)      │ ← 输出电压采样
│        GP4/AN3 (Pin 3)      │ ← 输入电压采样  
│        GP3/MCLR/VPP (Pin 4) │ ← 复位/编程
│        GP2/T0CKI/INT/COUT   │ → PWM输出/比较器输出
│        GP1/AN1 (Pin 6)      │ ← 电流采样/按键输入
│        GP0/AN0 (Pin 7)      │ ← 参考电压/按键输入
│        VSS (Pin 8)          │ ← 地
└─────────────────────────────┘

2.2 硬件连接图

/******************** 硬件连接定义 ********************/
// 模拟输入引脚
#define VIN_SENSE_PIN   4       // GP3/AN3 - 输入电压采样
#define VOUT_SENSE_PIN  5       // GP4/AN4 - 输出电压采样
#define IOUT_SENSE_PIN  6       // GP1/AN1 - 输出电流采样
#define REF_VOLTAGE_PIN 7       // GP0/AN0 - 参考电压设置

// 输出控制引脚
#define PWM_OUTPUT_PIN   2       // GP2 - PWM输出到驱动电路
#define STATUS_LED_PIN   3       // GP4 - 状态指示LED

// 保护阈值定义(根据实际硬件调整)
#define OVER_VOLTAGE_THRESHOLD  260     // 过压阈值 26.0V
#define UNDER_VOLTAGE_THRESHOLD 90      // 欠压阈值 9.0V
#define OVER_CURRENT_THRESHOLD  100     // 过流阈值 10.0A
#define TARGET_VOLTAGE         120     // 目标输出电压 12.0V

2.3 关键电路设计

2.3.1 电压采样电路

输入电压采样:
Vin ── R1(100k) ──┬── GP3(AN3)
                   └── R2(10k) ── GND

输出电压采样:
Vout ── R3(100k) ──┬── GP4(AN4)  
                    └── R4(10k) ── GND

电流采样:
Io ── Rshunt(0.1Ω) ──┬── GP1(AN1)
                     └── GND

2.3.2 PWM驱动电路

PIC GP2 ── R10(1k) ──┬── Q1(2N3904) ── R11(100Ω) ── MOSFET栅极
                     └── GND

2.3.3 保护指示电路

GP4 ── R12(330Ω) ── LED ── GND

三、软件设计

3.1 系统配置

/**
 * @file main.c
 * @brief PIC16F676 自动稳压器主程序
 * @compiler XC8
 */

#include <xc.h>
#include <stdint.h>

// 配置字设置
#pragma config FOSC = INTRCIO   // 内部4MHz振荡器,IO功能
#pragma config WDTE = OFF       // 关闭看门狗
#pragma config PWRTE = ON       // 上电延时使能
#pragma config MCLRE = OFF      // GP3作为IO使用
#pragma config BOREN = ON       // 欠压复位使能
#pragma config CP = OFF         // 关闭代码保护

// 系统参数
#define _XTAL_FREQ 4000000      // 4MHz内部振荡器

// 全局变量
uint16_t vin_adc = 0;           // 输入电压ADC值
uint16_t vout_adc = 0;          // 输出电压ADC值
uint16_t iout_adc = 0;          // 输出电流ADC值
uint16_t target_voltage = TARGET_VOLTAGE; // 目标电压
uint8_t system_status = 0;      // 系统状态:0=正常,1=过压,2=欠压,3=过流
uint8_t pwm_duty = 50;          // PWM占空比 (0-100)

// 函数声明
void System_Init(void);
void ADC_Init(void);
void PWM_Init(void);
void Read_Sensors(void);
void Voltage_Control(void);
void Protection_Check(void);
void Update_Status_LED(void);

3.2 系统初始化

/**
 * @brief 系统初始化
 */
void System_Init(void) {
    // 配置振荡器为4MHz
    OSCCAL = 0x80;              // 使用出厂校准值
    
    // 配置GPIO
    TRISIO = 0b11111000;        // GP0-GP2为输出,GP3-GP5为输入
    GPIO = 0x00;                // 所有输出置低
    
    // 配置模拟引脚
    ANSEL = 0b01110000;         // GP3,GP4,GP5为模拟输入,其余为数字IO
    CMCON = 0x07;               // 关闭比较器
    
    // 初始化各模块
    ADC_Init();
    PWM_Init();
    
    // 延时等待系统稳定
    __delay_ms(100);
}

3.3 ADC模块配置

/**
 * @brief ADC初始化
 */
void ADC_Init(void) {
    ADCON0 = 0x81;              // 开启ADC,选择AN0,Fosc/8
    ANSEL = 0b01110000;         // 配置模拟引脚
    __delay_us(10);             // ADC稳定时间
}

/**
 * @brief 读取ADC值
 * @param channel ADC通道 (0-7)
 * @return ADC转换结果 (0-1023)
 */
uint16_t ADC_Read(uint8_t channel) {
    uint16_t adc_result;
    
    // 选择ADC通道
    ADCON0 &= 0xC7;             // 清除通道选择位
    ADCON0 |= (channel << 3);   // 设置新通道
    
    __delay_us(10);             // 通道切换稳定时间
    
    // 启动转换
    GO_nDONE = 1;
    while(GO_nDONE);            // 等待转换完成
    
    // 读取结果
    adc_result = (ADRESH << 8) | ADRESL;
    return adc_result;
}

/**
 * @brief 读取所有传感器
 */
void Read_Sensors(void) {
    vin_adc = ADC_Read(3);      // 读取输入电压 (AN3/GP4)
    vout_adc = ADC_Read(4);     // 读取输出电压 (AN4/GP5)  
    iout_adc = ADC_Read(1);     // 读取输出电流 (AN1/GP1)
}

3.4 PWM模块配置

/**
 * @brief PWM初始化
 */
void PWM_Init(void) {
    // 配置Timer2
    T2CON = 0x04;               // Timer2预分频1:1,后分频1:1
    PR2 = 0xFF;                 // PWM周期 = (PR2+1)*4*Tosc = 256*4/4MHz = 256μs
    
    // 配置CCP1为PWM模式
    CCP1CON = 0x0C;             // PWM模式
    CCPR1L = 128;               // 初始占空比50%
    
    // 启动Timer2
    TMR2ON = 1;
}

/**
 * @brief 设置PWM占空比
 * @param duty 占空比 (0-100)
 */
void PWM_SetDuty(uint8_t duty) {
    uint16_t pwm_value;
    
    if(duty > 100) duty = 100;
    if(duty < 5) duty = 5;      // 最小占空比限制
    
    pwm_value = (uint16_t)duty * 1023 / 100;  // 转换为10位PWM值
    CCPR1L = pwm_value >> 2;      // 高8位
    CCP1CONbits.DC1B = pwm_value & 0x03; // 低2位
}

3.5 电压控制算法

/**
 * @brief 电压控制主逻辑
 */
void Voltage_Control(void) {
    int16_t error;
    int16_t adjustment;
    static int16_t integral = 0;
    static int16_t last_error = 0;
    
    // 将ADC值转换为实际电压 (假设参考电压5V)
    uint16_t actual_voltage = (vout_adc * 500) / 1023;  // 单位:0.1V
    
    // 计算误差
    error = target_voltage - actual_voltage;
    
    // PID控制算法
    integral += error;
    if(integral > 1000) integral = 1000;    // 积分限幅
    if(integral < -1000) integral = -1000;
    
    adjustment = (error * 2) + (integral / 10) + ((error - last_error) * 1);
    
    // 调整PWM占空比
    if(adjustment > 0) {
        if(pwm_duty < 95) pwm_duty += 1;
    } else if(adjustment < 0) {
        if(pwm_duty > 5) pwm_duty -= 1;
    }
    
    // 更新PWM
    PWM_SetDuty(pwm_duty);
    last_error = error;
}

3.6 保护功能

/**
 * @brief 保护功能检查
 */
void Protection_Check(void) {
    uint16_t vin_voltage, vout_voltage, iout_current;
    
    // 转换ADC值为实际值 (单位:0.1V 或 0.1A)
    vin_voltage = (vin_adc * 500) / 1023;      // 输入电压 (0.1V)
    vout_voltage = (vout_adc * 500) / 1023;    // 输出电压 (0.1V)
    iout_current = (iout_adc * 500) / 1023;    // 输出电流 (0.1A)
    
    // 过压保护
    if(vin_voltage > OVER_VOLTAGE_THRESHOLD || 
       vout_voltage > OVER_VOLTAGE_THRESHOLD) {
        system_status = 1;  // 过压状态
        PWM_SetDuty(0);     // 关闭PWM输出
        return;
    }
    
    // 欠压保护
    if(vin_voltage < UNDER_VOLTAGE_THRESHOLD) {
        system_status = 2;  // 欠压状态
        PWM_SetDuty(0);     // 关闭PWM输出
        return;
    }
    
    // 过流保护
    if(iout_current > OVER_CURRENT_THRESHOLD) {
        system_status = 3;  // 过流状态
        PWM_SetDuty(0);     // 关闭PWM输出
        return;
    }
    
    // 恢复正常状态
    system_status = 0;
}

/**
 * @brief 更新状态LED
 */
void Update_Status_LED(void) {
    static uint8_t led_counter = 0;
    
    switch(system_status) {
        case 0:  // 正常状态 - LED常亮
            GP4 = 1;
            break;
        case 1:  // 过压 - LED快闪
            if(++led_counter >= 10) {
                GP4 = !GP4;
                led_counter = 0;
            }
            break;
        case 2:  // 欠压 - LED慢闪
            if(++led_counter >= 50) {
                GP4 = !GP4;
                led_counter = 0;
            }
            break;
        case 3:  // 过流 - LED灭
            GP4 = 0;
            break;
    }
}

3.7 按键处理(电压调整)

/**
 * @brief 按键扫描和处理
 */
void Key_Process(void) {
    static uint8_t key_pressed = 0;
    uint16_t key_adc;
    
    // 读取参考电压设置引脚
    key_adc = ADC_Read(0);  // AN0/GP0
    
    // 检测按键
    if(key_adc < 100) {      // 电压增加按键
        if(!key_pressed) {
            target_voltage += 5;  // 增加0.5V
            if(target_voltage > 240) target_voltage = 240;
            key_pressed = 1;
        }
    } else if(key_adc > 400 && key_adc < 600) {  // 电压减少按键
        if(!key_pressed) {
            target_voltage -= 5;  // 减少0.5V
            if(target_voltage < 50) target_voltage = 50;
            key_pressed = 1;
        }
    } else {
        key_pressed = 0;
    }
}

3.8 主程序

/**
 * @brief 主程序
 */
void main(void) {
    // 系统初始化
    System_Init();
    
    // 主循环
    while(1) {
        // 读取传感器数据
        Read_Sensors();
        
        // 检查保护状态
        Protection_Check();
        
        // 如果系统正常,执行电压控制
        if(system_status == 0) {
            Voltage_Control();
            Key_Process();    // 处理按键输入
        }
        
        // 更新状态指示
        Update_Status_LED();
        
        // 延时
        __delay_ms(10);
    }
}

参考代码 采用pic16f676的自动稳压器 www.youwenfan.com/contentcsu/60361.html

四、PCB设计要点

4.1 布局建议

  1. 功率回路:输入滤波→开关管→输出滤波,路径最短
  2. 模拟地数字地分离:单点接地,避免干扰
  3. 散热设计:开关管加散热片,PCB增加铜皮面积
  4. 高压隔离:输入高压部分与低压控制部分保持安全距离

4.2 关键元件选型

元件 规格 备注
开关管 IRF540N N沟道MOSFET,100V/33A
驱动电阻 100Ω 限制栅极电流
输入电容 470μF/400V 电解电容,滤波
输出电容 1000μF/25V 低ESR电解电容
续流二极管 MUR460 快恢复二极管
采样电阻 0.1Ω/5W 电流采样

五、调试与测试

5.1 测试步骤

  1. 静态测试:检查各点电压,确保无短路
  2. 空载测试:逐步增加输入电压,观察输出电压稳定性
  3. 带载测试:接入不同负载,测试稳压性能
  4. 保护测试:模拟过压、欠压、过流情况

5.2 性能参数

参数 指标
输入电压范围 15V-30V DC
输出电压范围 5V-24V DC可调
输出电流 最大5A
稳压精度 ±2%
纹波电压 <50mV
效率 >85%

六、功能扩展

6.1 可增加的功能

  1. 软启动:避免开机冲击电流
  2. 短路保护:输出短路自动保护
  3. 温度保护:过热自动降功率
  4. 数码管显示:显示电压电流值
  5. 远程控制:通过串口调整参数

6.2 软件优化

  1. 数字滤波:对ADC采样值进行滤波
  2. 自适应PID:根据负载调整PID参数
  3. 故障记录:记录保护事件
  4. 自诊断:定期检查系统状态

这个基于PIC16F676的自动稳压器设计具有成本低、性能可靠、易于制作的特点,非常适合DIY和小批量生产应用。通过合理的软硬件设计,可以实现专业级的稳压器产品。 ⚡

专注于matlab/simulink,电子电路,编程