找回密码
 立即注册
查看: 123|回复: 3

STC8G1K08单片机AD读取异常

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-05 19:49:18
已绑定手机

1

主题

1

回帖

11

积分

新手上路

积分
11
发表于 2026-2-3 10:47:20 | 显示全部楼层 |阅读模式
请教各位大神一下  STC8G1K08单片机为何在读取AD时会经常读取到0   使用的AD0  也设置了高祖输入   AD口也加了滤波   测试时就发现两路AD都会读取到0  后来就改成单独测试1个AD口  因为我的程序设置的是当温度高于xx度后 继电器动作   我下好程序放在哪经常听见继电器动作  然后我就把程序修改成了先AD转换温度 后串口发送   我就看到 经常性的  有时候20  30秒  有时候1分钟    温度数据就从 20-20-20-160-20-20就这样猛的一下160度   下一秒又20度  他这个漂移不是那种20-21-23-20-21  不是这种在附近漂移的是突然猛地一下就160   我这个是负温度系数的  也就是单片机读取到了0  才转换成了160度   温度采集的还好说可以程序滤波一下   主要是我程序稳定了后还有个高速的AD采集  我希望是滤波之前采集到的AD差不多的数据 别突然是0    之前用的是stc15w408as没有出过这种问题 最近用stc8g1k08就一直没搞好  有没有大神给看下哪里原因



#include "STC8G.h"                                       
#include "intrins.h"
#define uchar unsigned char
#define uint  unsigned int
#define SAMPLE_COUNT 16       // 0.2秒内采样16次(12.5ms间隔)
#define REMOVE_COUNT 4        // 去除4个最高和4个最低值


uint code adc_table[]={

994                        ,//                -40        0
992                        ,//                -39        1
990                        ,//                -38        2
988                        ,//                -37        3
985                        ,//                -36        4
983                        ,//                -35        5
980                        ,//                -34        6
977                        ,//                -33        7
974                        ,//                -32        8
971                        ,//                -31        9
968                        ,//                -30        10
964                        ,//                -29        11
961                        ,//                -28        12
957                        ,//                -27        13
953                        ,//                -26        14
949                        ,//                -25        15
945                        ,//                -24        16
940                        ,//                -23        17
936                        ,//                -22        18
931                        ,//                -21        19
926                        ,//                -20        20
921                        ,//                -19        21
915                        ,//                -18        22
910                        ,//                -17        23
904                        ,//                -16        24
898                        ,//                -15        25
892                        ,//                -14        26
885                        ,//                -13        27
878                        ,//                -12        28
872                        ,//                -11        29
864                        ,//                -10        30
857                        ,//                -9        31
850                        ,//                -8        32
842                        ,//                -7        33
834                        ,//                -6        34
826                        ,//                -5        35
817                        ,//                -4        36
809                        ,//                -3        37
800                        ,//                -2        38
791                        ,//                -1        39
782                        ,//                0        40
772                        ,//                1        41
763                        ,//                2        42
753                        ,//                3        43
743                        ,//                4        44
733                        ,//                5        45
722                        ,//                6        46
712                        ,//                7        47
701                        ,//                8        48
691                        ,//                9        49
680                        ,//                10        50
669                        ,//                11        51
658                        ,//                12        52
647                        ,//                13        53
636                        ,//                14        54
624                        ,//                15        55
613                        ,//                16        56
602                        ,//                17        57
590                        ,//                18        58
579                        ,//                19        59
568                        ,//                20        60
556                        ,//                21        61
545                        ,//                22        62
534                        ,//                23        63
522                        ,//                24        64
512                        ,//                25        65
500                        ,//                26        66
489                        ,//                27        67
478                        ,//                28        68
467                        ,//                29        69
456                        ,//                30        70
445                        ,//                31        71
435                        ,//                32        72
424                        ,//                33        73
414                        ,//                34        74
404                        ,//                35        75
394                        ,//                36        76
384                        ,//                37        77
374                        ,//                38        78
364                        ,//                39        79
355                        ,//                40        80
346                        ,//                41        81
337                        ,//                42        82
328                        ,//                43        83
319                        ,//                44        84
310                        ,//                45        85
302                        ,//                46        86
294                        ,//                47        87
286                        ,//                48        88
278                        ,//                49        89
270                        ,//                50        90
263                        ,//                51        91
255                        ,//                52        92
248                        ,//                53        93
241                        ,//                54        94
234                        ,//                55        95
228                        ,//                56        96
221                        ,//                57        97
215                        ,//                58        98
209                        ,//                59        99
203                        ,//                60        100
197                        ,//                61        101
191                        ,//                62        102
186                        ,//                63        103
181                        ,//                64        104
176                        ,//                65        105
170                        ,//                66        106
166                        ,//                67        107
161                        ,//                68        108
156                        ,//                69        109
152                        ,//                70        110
147                        ,//                71        111
143                        ,//                72        112
139                        ,//                73        113
135                        ,//                74        114
131                        ,//                75        115
127                        ,//                76        116
124                        ,//                77        117
120                        ,//                78        118
117                        ,//                79        119
114                        ,//                80        120
110                        ,//                81        121
107                        ,//                82        122
104                        ,//                83        123
101                        ,//                84        124
98                        ,//                85        125
96                        ,//                86        126
93                        ,//                87        127
90                        ,//                88        128
88                        ,//                89        129
85                        ,//                90        130
83                        ,//                91        131
81                        ,//                92        132
79                        ,//                93        133
76                        ,//                94        134
74                        ,//                95        135
72                        ,//                96        136
70                        ,//                97        137
68                        ,//                98        138
67                        ,//                99        139
65                        ,//                100        140
63                        ,//                101        141
61                        ,//                102        142
60                        ,//                103        143
58                        ,//                104        144
57                        ,//                105        145
55                        ,//                106        146
54                        ,//                107        147
52                        ,//                108        148
51                        ,//                109        149
50                        ,//                110        150
48                        ,//                111        151
47                        ,//                112        152
46                        ,//                113        153
45                        ,//                114        154
44                        ,//                115        155
43                        ,//                116        156
41                        ,//                117        157
40                        ,//                118        158
39                        ,//                119        159
38                        ,//                120        160
37                        ,//                121        161
37                        ,//                122        162
36                        ,//                123        163
35                        ,//                124        164
34                        ,//                125        165
33                        ,//                126        166
32                        ,//                127        167
32                        ,//                128        168
31                        ,//                129        169
30                        ,//                130        170
29                        ,//                131        171
29                        ,//                132        172
28                        ,//                133        173
27                        ,//                134        174
27                        ,//                135        175
26                        ,//                136        176
25                        ,//                137        177
25                        ,//                138        178
24                        ,//                139        179
24                        ,//                140        180
23                        ,//                141        181
23                        ,//                142        182
22                        ,//                143        183
22                        ,//                144        184
21                        ,//                145        185
21                        ,//                146        186
20                        ,//                147        187
20                        ,//                148        188
19                        ,//                149        189
19                        ,//                150        190
18                        ,//                151        191
18                        ,//                152        192
18                        ,//                153        193
17                        ,//                154        194
17                        ,//                155        195
17                        ,//                156        196
16                        ,//                157        197
16                        ,//                158        198
16                        ,//                159        199
15                        ,//                160        200
};


sbit k1        =        P5^4;        //        LED1也是继电器引脚  
sbit keyhx        =        P3^6;        //        换向
bit hx,js = 0, dqsc_bite = 0, xr = 0;

void Timer0_Init();
void InitUart();
void SendData(uchar dat);
void Delay(uint n);
void InitADC();
void sendNbyte(unsigned char * pmsg,unsigned int plen);
int Temp_Cal( uint adc );
void kzbf();//自动控制部分
void xieru();//寄存器写入
void  IapIdle();          //关闭IAP
uchar read_add(uint addr);         //读EEPROM
void write_add(uint addr,uchar ch);         //直接写EEPROM
void Sector_Erase(uint addr);         //扇区擦除
void system_start();//初始化
int wd,szwd;
uchar ch;  //ADC通道号
unsigned int szjgsj,szscsj,dqscsj,dqjgsj;        //int类型0到65535
unsigned char szjgsjh,szjgsjl,szscsjh,szscsjl,szwdh,szwdl,jsz,cnt,jsms,kzms,shoudong;//char类型0到255
uint AD_10dat;
unsigned char buf_reg=0;
unsigned char recivebuff[10];
unsigned char recive_cnt=0,start_flag=0;
bit ad_over_bit,sys_tt, hx_bite = 0;
unsigned int AD_TEMP;
idata unsigned char sbuff2[21];
// 使用IDATA存储大数组(内部间接寻址RAM,256字节空间)
static idata unsigned int adc_buf[SAMPLE_COUNT];  // 采样数据缓冲区,32字节




// ----------------------------
// 主函数
// ----------------------------
void main()
{
       
  // GPIO 模式初始化(推挽/高阻,根据你的硬件需求)
        P1M0 = 0x00; P1M1 = 0x01;
    P3M0 = 0x00; P3M1 = 0x00;
    P5M0 = 0x10; P5M1 = 0x00;  
                wd=-40;       
    k1 =0;
                system_start();
    Timer0_Init();      // 50ms 定时器中断
    InitUart();         // 初始化串口(UART1,定时器1做波特率)
    InitADC();          // 初始化ADC
    IE = 0xB2;          // 使能 ADC 中断
    EA = 1;             // 开总中断

    while (1)
    {
        if (sys_tt == 1)
        {       
//                                        unsigned int i;           // 外层循环变量
//                                        unsigned int j;           // 内层循环变量
//                                        unsigned int swap;        // 交换变量
//                                        unsigned long sum;        // 求和变量

                   uchar high_byte;
                                                uchar low_byte;
                                                unsigned char a;
                                                unsigned char checksum = 0;
                                                sys_tt=0;
//                                        // ========== 冒泡排序(从小到大) ==========
//        // 对最近16次采样进行排序
//        for(i = 0; i < SAMPLE_COUNT-1; i++)
//        {
//            for(j = i+1; j < SAMPLE_COUNT; j++)
//            {
//                if(adc_buf[i] > adc_buf[j])
//                {
//                    swap = adc_buf[i];
//                    adc_buf[i] = adc_buf[j];
//                    adc_buf[j] = swap;
//                }
//            }
//        }
//        // ========== 排序结束 ==========
//        
//        // ========== 去极值求平均 ==========
//        // 去除最大的4个值(索引12-15)和最小的4个值(索引0-3)
//        // 取中间8个值(索引4-11)求平均值
//        sum = 0;
//        for(i = REMOVE_COUNT; i < SAMPLE_COUNT - REMOVE_COUNT; i++)
//        {
//            sum += adc_buf[i];  // 累加中间8个值
//        }
//        AD_TEMP = sum / 8;  // 计算平均值(16-4-4=8个值)
//        // ========== 滤波完成 ==========
//                                                         // 数据范围校验
//                                        if(AD_TEMP > 1023)
//                                        {
//                                                        AD_TEMP = 1023;
//                                        }
//                                       
                                       
                                                wd=Temp_Cal( AD_TEMP );
            high_byte = (wd >> 8) & 0xFF;
            low_byte = wd & 0xFF;
            sbuff2[0] = 0xab;
            sbuff2[1] = 0xcd;
            sbuff2[2] = 0x01;
            sbuff2[3] = szwd / 256;
            sbuff2[4] = szwd % 256;
            sbuff2[5] = high_byte;
            sbuff2[6] = low_byte;
            sbuff2[7] = szscsj / 256;
            sbuff2[8] = szscsj % 256;
            sbuff2[9] = dqscsj / 256;
            sbuff2[10] = dqscsj % 256;
            sbuff2[11] = szjgsj / 256;
            sbuff2[12] = szjgsj % 256;
            sbuff2[13] = dqjgsj / 256;
            sbuff2[14] = dqjgsj % 256;
            sbuff2[15] = kzms;
            sbuff2[16] = jsms;
            sbuff2[17] = k1;
//                                                sbuff2[17] =         keyhx;
                                       
            for (a = 2; a < 18; a++)
                checksum += sbuff2[a];
            checksum &= 0xFF;
            sbuff2[18] = checksum;
            sbuff2[19] = 0xdc;
            sbuff2[20] = 0xba;
            sendNbyte(sbuff2, 21);

        }
                                kzbf();         // 你的功能函数
        if (xr == 1)
        {
            xr = 0;
            xieru();    // 你的写入函数
        }
                                        if (ad_over_bit == 1)
                                        {                                       
                                                        ad_over_bit = 0;  // 清除ADC完成标志                                                       
                                                       
                                                       
                                                 
                                        }
    }
}
/*----------------------------
控制部分
----------------------------*/
void kzbf(void)
{
       
       
                        if(dqsc_bite==1)  //如果当前的状态是输出状态
                {                
                                                        //输出计时--               
                        if(dqscsj==0)                        //如果输出计时到了0
                        {
                        k1=0;                                                        //将继电器关闭
                        dqsc_bite=0;                //复位输出模式
                        dqjgsj=szjgsj;                        //取读取值 赋值给等待时间       
                        }
                        else k1=1;
                }
               
                        else         //  当前的模式是等待间隔时间         
                {                                       
                        if(dqjgsj==0)                                //如果等待间隔时间到达0
                        {
                                if((kzms==1&&jsms==1)||(kzms==0&&wd>=szwd        ))                                        //如果控制模式是1(计时模式)需要当前为计时自动模式  或 //如果控制模式是0(控温模式) 需要当前的温度大于设置温度                       
                                {        if(wd>=szwd)sys_tt = 1;                       
                                        dqsc_bite=1;                                //置位输出模式                                       
                                        dqscsj=szscsj;                        //取内存数据  赋值给输出时间
                                        k1=1;                                                        //打开继电器
                                }       
                                        }
                                else k1=0;                               
                        }
               
       
                if ((shoudong==1)||(hx==1&&hx_bite==0))
                        {
                                if(hx==1)hx_bite=1;
                                shoudong=0;                                        //复位手动状态
                                k1=1;                                                        //打开继电器
                                dqsc_bite=1;                                //置位输出模式       
                                dqjgsj=0;                                                //清除等待时间
                                dqscsj=szscsj;                        //取内存数据  赋值给输出时间
                        }
                        if (shoudong==2)
                        {
                                shoudong=0;                                        //复位手动状态
                                k1=0;                                                        //关闭继电器
                                dqsc_bite=0;                                //复位输出模式       
                                dqjgsj=szjgsj;                        //取内存数据  赋值给输出时间               
                                dqscsj=0;                                //清除输出时间
                       
                        }
                       
                 if(hx==0&&hx_bite==1)//如果按键松开 且按过一次 并且没有暂停输出状态
                        {
                        hx_bite=0;
                        }
                       
                        if(dqjgsj>szjgsj)        dqjgsj=szjgsj;
                        if(dqscsj>szscsj)        dqscsj=szscsj;
       
}
// ----------------------------
// 定时器0 中断(5ms)
// ----------------------------
void Timer0_Isr(void) interrupt 1
{
        static unsigned char keybuf = 0xff;//按键扫描缓冲区
    TH0 = 0xEE;  // 5ms @11.0592MHz,定时器0,模式1,12T(请确认是否准确)
    TL0 = 0x00;
    cnt++;
    jsz++;
    if (jsz >= 50)//串口发送的间隔时间
    {
        jsz = 0;
        sys_tt = 1;
    }
    if (cnt >= 200)//每隔一秒钟执行一次倒计时
    {
        cnt = 0;
       if(dqsc_bite==1&&dqscsj>0)        dqscsj--;                        //输出时间--
                        else if(dqsc_bite==0&&dqjgsj>0)dqjgsj--;                                        //等待间隔时间--
    }
               
                keybuf = (keybuf<<1) | keyhx;//缓冲区左移一位并把当前扫描值保存到最后一位
    if(keybuf==0xff)//如果八次扫描值都为1,那么认为按键是按下状态
          hx=1;
else if(keybuf == 0x00) {  // 连续8次都是低电平  
        hx = 0;  // 按键松开
    }



}
void system_start()
{

                szwdh=read_add(0x0200);
                szwdl=read_add(0x0201);
                szscsjh=read_add(0x0202);
                szscsjl=read_add(0x0203);
                szjgsjh=read_add(0x0204);
                szjgsjl=read_add(0x0205);
               
                kzms=read_add(0x0230);
                jsms=read_add(0x0231);
                szjgsj=(szjgsjh<<8)|szjgsjl;
                szscsj=(szscsjh<<8)|szscsjl;
                szwd=(szwdh<<8)|szwdl;


                if( (szwd>160) || (szwd<=0) ||
    (szscsj>65000) || (szscsj==0) ||
    (szjgsj>65000) || (szjgsj==0) ||
    (kzms>1) || (jsms>1) )
                        {
                        szwd=90;
                        szscsj=6;
                        szjgsj=120;
                        kzms=0;
                        jsms=0;

                        xieru();
                        }
                        if(kzms==1&&jsms==1)
                                {
                        dqsc_bite=1;
                        dqscsj=szscsj;
                        }
                        else         dqsc_bite=0;
                       

}
// ----------------------------
// 定时器0 初始化(5ms)
// ----------------------------
void Timer0_Init(void)
{
    TMOD &= 0xF0;   // 清除定时器0模式位
    TMOD |= 0x01;   // 定时器0,模式1(16位定时器)
    TH0 = 0xEE;     // 请根据你的晶振和实际定时需求确认是否为5ms
    TL0 = 0x00;
    TF0 = 0;
    TR0 = 1;        // 启动定时器0
    ET0 = 1;        // 允许中断

}



// ----------------------------
// 发送一个字节
// ----------------------------
void SendData(unsigned char dat)
{
    SBUF = dat;
    while (!TI);
    TI = 0;
}

// ----------------------------
// 发送N字节
// ----------------------------
void sendNbyte(unsigned char *pmsg, unsigned int plen)
{
    unsigned int i;
    for (i = 0; i < plen; i++)
        SendData(pmsg[i]);
}

// ----------------------------
// ADC 中断服务程序
// ----------------------------
void adc_isr() interrupt 5 using 1
{
    ADC_CONTR &= ~0x20; // 清除ADC中断标志(STC8G可能是 0x10,请根据手册确认)
    ad_over_bit = 1;
        // 读取ADC转换结果
                                                        AD_10dat = ADC_RES & 0xFF;      // 获取高8位
                                                        AD_10dat = (AD_10dat << 2) | (ADC_RESL & 0x03);  // 拼接低2位                       
                                                        // 存储采样值到缓冲区(持续采样,不断更新)
                                                        AD_TEMP = AD_10dat;
                                                       
                                                        AD_10dat = 0;  // 清零临时变量
                                                        ADC_CONTR |= 0x40;  // 启动下一次ADC转换
}

// ----------------------------
// 初始化ADC(使用P5.5,通道5)
// ----------------------------
void InitADC(void)
{                P1M1 |= (1 << 0);     // P1.0高阻输入模式
    P1M0 &= ~(1 << 0);    // 确保P1.0为模拟输入   
//      ADC_CONTR = 0x8d;     // 使能ADC电源|低速模式|选择通道5
//                          // 0x80: ADC电源使能
//                          // 0x05: 通道5选择
//   
//    ADCCFG = 0x0F;        // 配置ADC时钟和结果格式
//                          // bit7-6: 00-结果右对齐
//                          // bit5-4: 11-ADC时钟=Fosc/16
//                          // bit3-0: 1111-保留
//   
//    Delay(3);            // 等待ADC电源稳定(至少1ms)
//                ADC_CONTR |= 0x40;                      //启动AD转换
       
    P_SW2 |= 0x80;
    ADCTIM = 0x3f;                              //设置ADC内部时序
    P_SW2 &= 0x7f;
    ADCCFG = 0x0f;                              //设置ADC时钟为系统时钟/2/16
    ADC_CONTR = 0x80;                           //使能ADC模块
    EADC = 1;                                   //使能ADC中断
                        Delay(3);            // 等待ADC电源稳定(至少1ms)
    ADC_CONTR |= 0x40;                          //启动AD转换


       
       
}
// ----------------------------
// 串口初始化(UART1,使用定时器1做波特率)
// ----------------------------
void InitUart(void)
{
                 // 切换串口引脚到P1.6/P1.7(TXD_3/RXD_3)
    P_SW1 |= 0x80;  // 设置P_SW1.6=1,选择P3.2/P3.3作为串口引脚
   // 2. 配置P1.6(RXD)为高阻输入
    P1M0 &= ~(1 << 6);  // P1M0.6 = 0
    P1M1 |=  (1 << 6);  // P1M1.6 = 1 → 高阻输入模式

    // 3. 配置P1.7(TXD)为推挽输出
    P1M0 |=  (1 << 7);  // P1M0.7 = 1
    P1M1 &= ~(1 << 7);  // P1M1.7 = 0 → 推挽输出模式
                SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器时钟1T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TL1 = 0xE0;                        //设置定时初始值
        TH1 = 0xFE;                        //设置定时初始值
        ET1 = 0;                        //禁止定时器中断
        TR1 = 1;                        //定时器1开始计时
    ES = 1;         // 允许串口中断

}

/*----------------------------
UART 中断服务程序
-----------------------------*/



void Uart() interrupt 4 using 1 {
    if (RI) {
        RI = 0;  // 清除接收中断标志
        buf_reg = SBUF;  // 读取接收到的数据

        // 如果接收到起始标志 0xEF,并且未开始接收数据帧
        if (buf_reg == 0xEF && start_flag == 0) {
            recive_cnt = 0;  // 重置接收计数器
            start_flag = 1;  // 开始接收数据帧
        }

        // 检查 recive_cnt 是否超出缓冲区大小
        if (recive_cnt < sizeof(recivebuff)) {
            recivebuff[recive_cnt] = buf_reg;  // 将数据存入缓冲区
            recive_cnt++;
        } else {
            // 缓冲区已满,丢弃数据并重置接收状态
            recive_cnt = 0;
            start_flag = 0;
        }

        // 检查是否接收到完整的数据帧
        if (buf_reg == 0xFE && recive_cnt == 6 && start_flag == 1) {
            // 数据帧格式:0xEF | 地址 | 数据1 | 数据2 | 校验和 | 0xFE
            unsigned char address = recivebuff[1];
            unsigned char data1 = recivebuff[2];
            unsigned char data2 = recivebuff[3];
            unsigned char received_checksum = recivebuff[4];

            // 计算校验和
            unsigned char calculated_checksum = (address + data1 + data2) & 0xFF;

            // 校验通过
            if (calculated_checksum == received_checksum) {
                // 处理接收到的数据
                if (address == 0x00) {  // 设置温度
                    uint linshi = data1 * 256 + data2;  // 声明 linshi
                    if (linshi <= 160 && linshi > 0) {
                        szwd = linshi;
                        xr = 1;
                    }
                }
                if (address == 0x01) {  // 设置反吹时间
                    uint linshi = data1 * 256 + data2;  // 声明 linshi
                    if (linshi <= 65000 && linshi > 0) {
                        szscsj = linshi;
                        xr = 1;
                    }
                }
                if (address == 0x02) {  // 设置间隔时间
                    uint linshi = data1 * 256 + data2;  // 声明 linshi
                    if (linshi <= 65000 && linshi > 0) {
                        szjgsj = linshi;
                        xr = 1;
                    }
                }
                if (address == 0x03) {  // 设置工作模式
                    unsigned char linshia = data2;  // 声明 linshia
                    if (linshia <= 1) {
                        kzms = linshia;
                        xr = 1;
                    }
                }
                if (address == 0x04) {  // 设置计时模式
                    unsigned char linshia = data2;  // 声明 linshia
                    if (linshia <= 1) {
                        jsms = linshia;
                        xr = 1;
                    }
                }
                if (address == 0x05) {  // 手动开关
                    unsigned char linshia = data2;  // 声明 linshia
                    if (linshia <= 2) {
                        if (k1 == 1) {
                                                                                                                        cnt=0;
                            shoudong = 2;
                        } else {
                                                                                                                        cnt=0;
                            shoudong = 1;
                        }
                    }
                }
            }

            // 重置接收状态
            recive_cnt = 0;
            start_flag = 0;
        }
    }
}


// ----------------------------
// 延时函数
// ----------------------------
void Delay(uint n)
{
    uint x;
    while (n--)
    {
        x = 5000;
        while (x--);
    }
}

// ----------------------------
// 温度计算函数(需用户提供 adc_table[])
// ----------------------------
int Temp_Cal(uint adc) {
         int low = 0, high = 200;
    if (adc > adc_table[0]) {
        return -40;  // 如果ADC值小于最小值,返回最低温度
    }
    if (adc < adc_table[200]) {
        return 160;  // 如果ADC值大于最大值,返回最高温度
    }


    while (low <= high) {
        int mid = (low + high) / 2;
        if (adc >= adc_table[mid]) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return (low - 1) - 40;
}
void xieru()//寄存器写入
{
       
                szscsjl = szscsj&0XFF;//低八位
    szscsjh = szscsj>>8;//高八位
                szjgsjl = szjgsj&0XFF;//低八位
    szjgsjh        = szjgsj>>8;//高八位
                szwdl = szwd&0XFF;//低八位
    szwdh = szwd>>8;//高八位
               
                                        Sector_Erase(0x200);                               
                                        write_add(0x0200,szwdh);
                                        write_add(0x0201,szwdl);
                                        write_add(0x0202,szscsjh);
                                        write_add(0x0203,szscsjl);
                                        write_add(0x0204,szjgsjh);                               
                                        write_add(0x0205,szjgsjl);
                                        write_add(0x0230,kzms);
                                        write_add(0x0231,jsms);
                               
                szwdh=read_add(0x0200);
                szwdl=read_add(0x0201);
                szscsjh=read_add(0x0202);
                szscsjl=read_add(0x0203);
                szjgsjh=read_add(0x0204);
                szjgsjl=read_add(0x0205);
                kzms=read_add(0x0230);
                jsms=read_add(0x0231);
                szjgsj=(szjgsjh<<8)|szjgsjl;
                szscsj=(szscsjh<<8)|szscsjl;
                szwd=(szwdh<<8)|szwdl;       
}

void  IapIdle()           //关闭IAP
{
    IAP_CONTR = 0;                              //关闭IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除触发寄存器
    IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
    IAP_ADDRL = 0;

}

//读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
uchar read_add(uint addr)         //读EEPROM
{
    char dat;
                EA = 0;
                IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //设置等待参数12MHz
    IAP_CMD = 1;                                //设置IAP读命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();
    dat = IAP_DATA;                             //读IAP数据
    IapIdle();                                  //关闭IAP功能
                EA = 1;
    return dat;

}


//字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
void write_add(uint addr,uchar dat)         //直接写EEPROM
{
                EA = 0;
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //设置等待参数12MHz
    IAP_CMD = 2;                                //设置IAP写命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_DATA = dat;                             //写IAP数据
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();
    IapIdle();                                  //关闭IAP功能
                EA = 1;

}
//擦除扇区, 入口:DPTR = 扇区地址
void Sector_Erase(uint addr)         //扇区擦除
{
                EA = 0;
   IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //设置等待参数12MHz
    IAP_CMD = 3;                                //设置IAP擦除命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();                                    //
    IapIdle();                                  //关闭IAP功能
                EA = 1;       

}


原理图

原理图

pcb图

pcb图
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:298
  • 最近打卡:2026-03-21 08:29:20
已绑定手机

4

主题

27

回帖

906

积分

高级会员

积分
906
发表于 2026-2-3 10:59:30 | 显示全部楼层
可能是继电器干扰吧,我用8H也遇见过偶发读0,最后发现问题是信号线距离电感太近。本来设计时电感的干扰是考虑在内的,以为是数值有波动,结果实测直接读0。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-05 19:49:18
已绑定手机

1

主题

1

回帖

11

积分

新手上路

积分
11
发表于 2026-2-3 11:02:29 | 显示全部楼层
李*** 发表于 2026-2-3 10:59
可能是继电器干扰吧,我用8H也遇见过偶发读0,最后发现问题是信号线距离电感太近。本来设计时电感的干扰是 ...

他这个肯定不是    继电器动作的前提是AD读取到0(也就是温度变为160度)    动作顺序是 先读到了0  后继电器动作  不是继电器动作了而后读到了0
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:82
  • 最近打卡:2026-03-20 20:44:49
已绑定手机

4

主题

222

回帖

818

积分

高级会员

积分
818
发表于 2026-2-3 14:36:42 | 显示全部楼层
代码过多,不便查看。
若怀疑ADC有问题,建议单独写一个读取ADC并发往串口的程序,用串口助手查看是否有异常数据(绘制曲线更方便查看)。
另外,AD_TEMP 在中断里采集、在主循环使用,可能会造成错位,因为它是16位数据,
如果主循环先读高8位后读低8位,然后在这两步之间发生了中断,就容易造成错位,
比如电压正在增长,中断中数据为:0x01FF,0x0200,0x0201,
主循环可能读到的是:0x01FF,0x0100,0x0200,0x0201 ,这里面的0x0100就是有错位。
建议主循环获取数据时关闭ADC中断。
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-22 03:27 , Processed in 0.107092 second(s), 65 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表