You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Proteus中PIC18F4520带风扇温度传感器仿真异常排查

PIC18F4520温度风扇电路Proteus仿真异常排查

问题描述

基于PIC18F4520设计带风扇的温度传感器电路及配套代码,仿真时出现异常。电路设计参考条件:
电路设计参考
仿真错误截图:
仿真错误

已尝试网络搜索解决方案但未找到有效办法,完整代码如下:

// PIC18F4520 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1H
#pragma config OSC = HS         // Oscillator Selection bits (HS oscillator)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown Out Reset Voltage bits (Minimum setting)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = PORTC   // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include"LCD4b_EXSTO.h"
#include <stdio.h>
#define _XTAL_FREQ 8000000

#define FAN1 PORTCbits.RC0
#define FAN2 PORTCbits.RC1
#define RES PORTCbits.RC2
//botao
#define B1 PORTBbits.RB0  

unsigned int VdigADC;
float TENSAO, graus, porcen;

void config_IO()
{
TRISC = 0X00;
PORTC = 0XFF;
}

void config_ADC()
{// PARA O AN0
ADCON0 = 0X01; // Seleção dos canais analógicos; Estado da conversão e Habilitação do  Conversor A/D PADRAO
ADCON1 = 0X0E; // Tensão de referência; Seleção de entrada analógica | PORTA AN3 -> 1011
ADCON2 = 0X87; // Alinhamento dos Bits (ADRES); Tempo de aquisição; Fonte de Clock para o converesor A/D PADRAO
}

void config_FOSC()
{
OSCCON = 0X00;
OSCTUNE = 0X00;
}

void equacao(){
    
    TENSAO = VdigADC * 0.004887585532746823069403714565;
    graus = TENSAO / 0.01190476190476190476190476190476;
    porcen = (graus * 100) / 420;
}

void conv_AN0()
{
    __delay_ms(200);
    ADCON0bits.GO = 1;
    while(ADCON0bits.GO); 
    VdigADC = ADRESH; 
    VdigADC = (VdigADC << 8) + ADRESL;
    equacao();

}
void porc(){
    
    conv_AN0();
    if(porcen<25)
    {
        RES=0;
        FAN1=1;
        FAN2=1;
    }
    else if(porcen>25 && porcen<=50)
    {
        RES=0;
        FAN1=0;
        FAN2=1;
    }
    else if(porcen>50 && porcen<=75)
    {
        RES=0;
        FAN1 =0;
        FAN2=0;
    }
    else if(porcen>75)
    {
        RES=1;
        FAN1 =0;
        FAN2=0;
    }
    
}
void lcd(){//BLOCO DO LCD
    char temperatura[16];
    char percentual[16];
    char fan1[16];
    char fan2[16];
    char res[16];
    
    
    lcd_init();
    lcd_clear();
    __delay_ms(100);
    
    while(B1 == 1){
        lcd_clear();
        porc();
        lcd_write(1,1,"FAN 1:");//linha 1 fan1
        sprintf(fan1, "%d",FAN1);
        lcd_write(1,7,fan1);
        
        lcd_write(1,9,"FAN 2:");//linha 1 fan2
        sprintf(fan2, "%d",FAN2);
        lcd_write(1,16,fan2);
        
        lcd_write(2,1,"RES:");//linha 2 res
        sprintf(res, "%d          ",RES);
        lcd_write(2,6,res);
        __delay_ms(100);
    } 
    lcd_clear();

    __delay_ms(100);
    while(B1==0)// exibe temperatura e porcentagem
    {
        lcd_clear();
        __delay_ms(100);
        porc(); 
        //linha 1
        lcd_write(1,1,"Temp:");
        sprintf(temperatura, "%.1f%cC                     ", graus, 0XDF);
        lcd_write(1,9,temperatura);
        
        //linha 2
        lcd_write(2,1,"Percent:");
        sprintf(percentual, "%.1f%c                       ", porcen, 0X25);
        lcd_write(2,10,percentual);
        __delay_ms(100);
    }
}
void main()
{
    config_FOSC();
    config_ADC();
    config_IO();
    lcd();        
}

异常原因排查及解决方案

1. 振荡器配置不匹配

代码中配置OSC = HS(高速外部振荡器),需检查Proteus电路:

  • 为PIC18F4520添加8MHz外部晶振,与_XTAL_FREQ 8000000匹配
  • 晶振正确连接到OSC1(RA7)和OSC2(RA6)引脚
  • 若未添加晶振或参数错误,单片机无法正常运行,直接引发仿真异常

2. ADC配置与硬件冲突

  • PBADEN = ON将PORTB<4:0>设为模拟输入,但代码中把RB0作为数字按键输入,需在config_IO()中添加:
    ADCON1bits.PCFG3 = 1; // 将RB0配置为数字引脚
    TRISBbits.TRISB0 = 1; // 设置RB0为输入模式
    
  • conv_AN0()中ADC读数顺序错误,正确的10位ADC合并方式应为:
    VdigADC = (ADRESH << 8) | ADRESL;
    
    原代码先赋值VdigADC = ADRESH再移位,会导致高位数据被覆盖,读数错误

3. 端口初始化不完整

  • config_IO()仅配置了TRISC和PORTC,未配置TRISB,按键引脚RB0需设置为输入才能正确读取状态
  • 建议在config_IO()中补充PORTB的配置:
    TRISB = 0x01; // RB0为输入,其余PORTB引脚根据需求配置
    

4. LCD驱动兼容性问题

  • 确认LCD4b_EXSTO.h中的引脚定义与Proteus电路中LCD的连接一致
  • 驱动中的延时函数需与_XTAL_FREQ匹配,若延时参数错误会导致LCD无法初始化或显示异常
  • 尝试替换为标准LCD4位驱动代码,排除自定义驱动的问题

5. 仿真模型与代码配置冲突

  • 检查Proteus中PIC18F4520的配置是否与代码中的#pragma config一致,尤其是振荡器、MCLRE等关键配置
  • 更新Proteus的PIC器件库,旧模型可能存在配置兼容性bug

6. 代码逻辑死循环

  • lcd()函数中的两个while循环会导致程序卡在单一模式,无法响应按键切换,需添加防抖处理并优化循环逻辑:
    // 示例:添加按键防抖
    while(1){
        if(B1 == 1){
            __delay_ms(20); // 防抖延时
            if(B1 == 1){
                // 显示风扇状态逻辑
                while(B1 == 1); // 等待按键释放
                __delay_ms(20);
            }
        }else{
            // 显示温度和百分比逻辑
            __delay_ms(100);
        }
    }
    

内容的提问来源于stack exchange,提问作者AllryaLinez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:42:03