找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 873|回复: 9
打印 上一主题 下一主题
收起左侧

用STC8G1K08单片机的P1.1口采集NTC温度显示000 还请大佬抽空帮忙看看问题所在

[复制链接]
跳转到指定楼层
楼主



原理图如上,测试STC8G1K08的NTC温度采样,3位数码管始终显示000。P5.4口接LED测试发现ADC转换函数未采样出数值。
单片机代码如下:
#include    "STC8xxxx.h"       //包含此头文件后,里面声明的寄存器不需要再手动输入,避免重复定义
#include    "intrins.h"
#include    "math.h"
#define     MAIN_Fosc       24000000L   //定义主时钟
#define    Timer0_Reload    (MAIN_Fosc / 1000)        //Timer 0 中断频率, 1000次/秒
#define    Timer1_Reload    (MAIN_Fosc / 1000)        //Timer 1 中断频率, 1000次/秒
#define     Vref     5


/****************************** 用户定义宏 ***********************************/

#define ADCTIM (*(unsigned char volatile xdata *)0xfea8)

/*****************************************************************************/


#define DIS_DOT     0x20
#define DIS_BLACK   0x10
#define DIS_        0x11

sbit DS = P1^7;                //串行输入
sbit ST = P1^6;                //锁存时钟
sbit SH = P1^5;                //串行输入时钟
sbit COM1 = P1^2;            //数码管公共端COM1
sbit COM2 = P1^3;            //数码管公共端COM2
sbit COM3 = P1^4;            //数码管公共端COM3
sbit LED = P5^4;
u16 temperature;

            //         0    1    2    3     4      5       6    7    8    9   0.   1.   2.   3.   4.   5.   6.   7.   8.   9.    A    B    C    D    E    F     
u8 SEG_Code[29] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x88,0x83,0xc6,0xa1,0x86,0x8e,        //共阳数码管段码:0~F,   
                                        0xFF,0xBF,0x00};    //数码管全灭(17),横杆-(18),数码管全亮(19)

void  delayms(u16 ms)        //简单延时函数,自适应主频,1毫秒*ms
{
    u16 i;
    do{
            i = MAIN_Fosc / 15000;
            while(--i);
        }while(--ms);
}


/*************  本地变量声明    **************/

bit B_1ms;          //1ms标志
u16 msecond;

/*************  本地函数声明    **************/
u16 get_temperature(u16 adc);
u16 Get_ADC10bitResult(u8 channel); //channel = 0~15
void Write595();
void DisplayScan();


/**********************************************/
void main(void)
{
    u16 j;
    P1M1 = 0x03;P1M0 = 0x1C;        //设置P1口模式 00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
    P3M1 = 0x14;P3M0 = 0x28;        //设置P3口模式 00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出  0001 0100      
    P5M1 = 0x00;P5M0 = 0x10;        //设置P5口模式 00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出  0010 1000

        ADC_CONTR = 0x81;
    P_SW2 |= 0x80;
        ADCTIM = 0x3f;                //设置 ADC 内部时序,ADC采样时间建议设最大值
        P_SW2 &= 0x7f;
        ADCCFG = 0x2f;                //设置 ADC 时钟为系统时钟/2/16/16
        ADC_CONTR |= 0x80; //使能 ADC 模块

    AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,
    TH0 = (u8)(Timer0_Reload / 256);
    TL0 = (u8)(Timer0_Reload % 256);
    ET0 = 1;    //Timer0 interrupt enable
    TR0 = 1;    //Tiner0 run
    EA = 1;     //打开总中断
    LED = 0;

    while(1)
    {
        if(B_1ms)   //1ms到
        {
            B_1ms = 0;
            if(++msecond >= 300)    //300ms到
            {
                msecond = 0;

                j = Get_ADC10bitResult(1);  //参数0~15,查询方式做一次ADC, 返回值就是结果, == 1024 为错误

                if(j < 1024)
                    temperature = get_temperature(j); //计算温度值
            }
        }

    }
}
/**********************************************/

//========================================================================
// 函数: u16 Get_ADC10bitResult(u8 channel)
// 描述: 查询法读一次ADC结果.
// 参数: channel: 选择要转换的ADC.
// 返回: 10位ADC结果.
// 版本: V1.0, 2012-10-22
//========================================================================
u16 Get_ADC10bitResult(u8 channel)  //channel = 0~15
{  
    u16 ADC_Data = 0;
    ADC_RES = 0;
    ADC_RESL = 0;

    ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel;    //启动 AD 转换
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    ADC_CONTR|=0x01;
    while((ADC_CONTR & 0x20) == 0)  ;   //wait for ADC finish
    ADC_CONTR &= ~0x20;     //清除ADC结束标志
    ADC_Data = ((u16)(ADC_RES << 8) | ADC_RESL);
    if(ADC_Data != 0)
        LED = 1;
    return ADC_Data;
}

void Write595(u8 dat)                  //向595写数据函数
{
    u16 i;
    u8 datcode;
    datcode = SEG_Code[dat];           //十进制数转段码
    for(i = 0;i < 8;i++)               //写数据
    {
        SH = 0;                        //拉低串行输入时钟SCLK
        DS = datcode & 0x80;           //取最高位
        SH = 1;                        //SCKL时钟上升沿,数据存移位寄存器
     datcode <<= 1;                    //每次一位
    }
    ST = 0;                            //拉低ST时钟
    ST = 1;                            //ST时钟上升沿,更新输出存储器数据
}

//显示扫描函数
void DisplayScan(void)
{   
    while(1)
    {
        Write595((u8)(temperature%1000/100));     //显示00-999计数百位
        COM1 = 0;
        COM2 = 0;
        COM3 = 1;                    //共阳极数码管,公共端给高电平点亮,点亮数码管左起第1位
        delayms(3);                                    //延时3毫秒

        Write595((u8)(temperature%100/10)+10);    //显示00-999计数十位
        COM1 = 0;
        COM2 = 1;
        COM3 = 0;                    //共阳极数码管,公共端给高电平点亮,点亮数码管左起第2位
        delayms(3);                                    //延时3毫秒

        Write595((u8)(temperature%10));           //显示00-999计数个位
        COM1 = 1;
        COM2 = 0;
        COM3 = 0;                    //共阳极数码管,公共端给高电平点亮,点亮数码管左起第3位
        delayms(3);                                    //延时3毫秒        
    }
}

//  MF52E 10K at 25, B = 3950, ADC = 12 bits
u16 code temp_table[]={
        140,    //;-40  0
        149,    //;-39  1
        159,    //;-38  2
        168,    //;-37  3
        178,    //;-36  4
        188,    //;-35  5
        199,    //;-34  6
        210,    //;-33  7
        222,    //;-32  8
        233,    //;-31  9
        246,    //;-30  10
        259,    //;-29  11
        272,    //;-28  12
        286,    //;-27  13
        301,    //;-26  14
        317,    //;-25  15
        333,    //;-24  16
        349,    //;-23  17
        367,    //;-22  18
        385,    //;-21  19
        403,    //;-20  20
        423,    //;-19  21
        443,    //;-18  22
        464,    //;-17  23
        486,    //;-16  24
        509,    //;-15  25
        533,    //;-14  26
        558,    //;-13  27
        583,    //;-12  28
        610,    //;-11  29
        638,    //;-10  30
        667,    //;-9   31
        696,    //;-8   32
        727,    //;-7   33
        758,    //;-6   34
        791,    //;-5   35
        824,    //;-4   36
        858,    //;-3   37
        893,    //;-2   38
        929,    //;-1   39
        965,    //;0    40
        1003,   //;1    41
        1041,   //;2    42
        1080,   //;3    43
        1119,   //;4    44
        1160,   //;5    45
        1201,   //;6    46
        1243,   //;7    47
        1285,   //;8    48
        1328,   //;9    49
        1371,   //;10   50
        1414,   //;11   51
        1459,   //;12   52
        1503,   //;13   53
        1548,   //;14   54
        1593,   //;15   55
        1638,   //;16   56
        1684,   //;17   57
        1730,   //;18   58
        1775,   //;19   59
        1821,   //;20   60
        1867,   //;21   61
        1912,   //;22   62
        1958,   //;23   63
        2003,   //;24   64
        2048,   //;25   65
        2093,   //;26   66
        2137,   //;27   67
        2182,   //;28   68
        2225,   //;29   69
        2269,   //;30   70
        2312,   //;31   71
        2354,   //;32   72
        2397,   //;33   73
        2438,   //;34   74
        2479,   //;35   75
        2519,   //;36   76
        2559,   //;37   77
        2598,   //;38   78
        2637,   //;39   79
        2675,   //;40   80
        2712,   //;41   81
        2748,   //;42   82
        2784,   //;43   83
        2819,   //;44   84
        2853,   //;45   85
        2887,   //;46   86
        2920,   //;47   87
        2952,   //;48   88
        2984,   //;49   89
        3014,   //;50   90
        3044,   //;51   91
        3073,   //;52   92
        3102,   //;53   93
        3130,   //;54   94
        3157,   //;55   95
        3183,   //;56   96
        3209,   //;57   97
        3234,   //;58   98
        3259,   //;59   99
        3283,   //;60   100
        3306,   //;61   101
        3328,   //;62   102
        3351,   //;63   103
        3372,   //;64   104
        3393,   //;65   105
        3413,   //;66   106
        3432,   //;67   107
        3452,   //;68   108
        3470,   //;69   109
        3488,   //;70   110
        3506,   //;71   111
        3523,   //;72   112
        3539,   //;73   113
        3555,   //;74   114
        3571,   //;75   115
        3586,   //;76   116
        3601,   //;77   117
        3615,   //;78   118
        3628,   //;79   119
        3642,   //;80   120
        3655,   //;81   121
        3667,   //;82   122
        3679,   //;83   123
        3691,   //;84   124
        3702,   //;85   125
        3714,   //;86   126
        3724,   //;87   127
        3735,   //;88   128
        3745,   //;89   129
        3754,   //;90   130
        3764,   //;91   131
        3773,   //;92   132
        3782,   //;93   133
        3791,   //;94   134
        3799,   //;95   135
        3807,   //;96   136
        3815,   //;97   137
        3822,   //;98   138
        3830,   //;99   139
        3837,   //;100  140
        3844,   //;101  141
        3850,   //;102  142
        3857,   //;103  143
        3863,   //;104  144
        3869,   //;105  145
        3875,   //;106  146
        3881,   //;107  147
        3887,   //;108  148
        3892,   //;109  149
        3897,   //;110  150
        3902,   //;111  151
        3907,   //;112  152
        3912,   //;113  153
        3917,   //;114  154
        3921,   //;115  155
        3926,   //;116  156
        3930,   //;117  157
        3934,   //;118  158
        3938,   //;119  159
        3942    //;120  160
};

/********************  计算温度 ***********************************************/
// 计算结果: 0对应-40.0度, 400对应0度, 625对应25.0度, 最大1600对应120.0度.
// 为了通用, ADC输入为12bit的ADC值.
// 电路和软件算法设计: Coody
/**********************************************/

#define     D_SCALE     10      //结果放大倍数, 放大10倍就是保留一位小数
u16 get_temperature(u16 adc)
{
    u16 code *p;
    u16 i;
    u8  j,k,min,max;

    adc = 1024 - adc;   //Rt接地
    p = temp_table;
    if(adc < p[0])      return (0xfffe);
    if(adc > p[160])    return (0xffff);

    min = 0;        //-40度
    max = 160;      //120度

    for(j=0; j<5; j++)  //对分查表
    {
        k = min / 2 + max / 2;
        if(adc <= p[k]) max = k;
        else            min = k;
    }
         if(adc == p[min])  i = min * D_SCALE;
    else if(adc == p[max])  i = max * D_SCALE;
    else    // min < temp < max
    {
        while(min <= max)
        {
            min++;
            if(adc == p[min])   {i = min * D_SCALE; break;}
            else if(adc < p[min])
            {
                min--;
                i = p[min]; //min
                j = (adc - i) * D_SCALE / (p[min+1] - i);
                i = min;
                i *= D_SCALE;
                i += j;
                break;
            }
        }
    }
    return i;
}




/********************** Timer0 1ms中断函数 ************************/
void timer0 (void) interrupt 1
{
    DisplayScan();  //1ms扫描显示一位
    B_1ms = 1;      //1ms标志
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2023-4-27 06:05 | 只看该作者
由于你DisplayScan函数中用了死循环while(1)并放在中断中运行,一旦进入中断就再也出不来。
回复

使用道具 举报

板凳
ID:155507 发表于 2023-4-27 08:27 | 只看该作者
你的显示扫描函数有问题。


//显示扫描函数
void DisplayScan(void)
{   
    while(1) <---------------- 进了中断,就不出来了。
    {
        Write595((u8)(temperature%1000/100));     //显示00-999计数百位
        COM1 = 0;
        COM2 = 0;
        COM3 = 1;                    //共阳极数码管,公共端给高电平点亮,点亮数码管左起第1位
        delayms(3);                                    //延时3毫秒
/********************** Timer0 1ms中断函数 ************************/
void timer0 (void) interrupt 1
{
    DisplayScan();  //1ms扫描显示一位
    B_1ms = 1;      //1ms标志
}
回复

使用道具 举报

地板
ID:1034262 发表于 2023-4-27 10:10 | 只看该作者
因为你的程序永远在中断里调用的 DisplayScan(),不退出,根本就没有运行其余程序。
回复

使用道具 举报

5#
ID:883242 发表于 2023-4-27 15:09 | 只看该作者
运算放主循环里面,中断只负责显示好了,最基本的编程思路都不对。
回复

使用道具 举报

6#
ID:608427 发表于 2023-4-27 22:47 | 只看该作者
wulin 发表于 2023-4-27 06:05
由于你DisplayScan函数中用了死循环while(1)并放在中断中运行,一旦进入中断就再也出不来。

大佬 感激不尽 把扫描显示调用从中断揪到主函数 并且去掉其中的while(1)完美解决问题
回复

使用道具 举报

7#
ID:608427 发表于 2023-4-27 22:48 | 只看该作者
angmall 发表于 2023-4-27 08:27
你的显示扫描函数有问题。

大佬 感激不尽 问题解决了
回复

使用道具 举报

8#
ID:608427 发表于 2023-4-27 22:48 | 只看该作者
coody_sz 发表于 2023-4-27 10:10
因为你的程序永远在中断里调用的 DisplayScan(),不退出,根本就没有运行其余程序。

大佬 感激不尽 问题解决了
回复

使用道具 举报

9#
ID:608427 发表于 2023-4-27 22:49 | 只看该作者
Hephaestus 发表于 2023-4-27 15:09
运算放主循环里面,中断只负责显示好了,最基本的编程思路都不对。

感谢大佬提点 问题已经解决了
回复

使用道具 举报

10#
ID:1056945 发表于 2023-9-20 20:19 | 只看该作者
兄弟,求完整程序包
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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