- /*
- * NTC测温,10位AD分辨率0.1度
- * 硬件说明:IAP15W4K58S4
- * 第一位数码管 位引脚-->P41 *
- * 第二位数码管 位引脚-->P42 *
- * 第三位数码管 位引脚-->P44 *
- * 第四位数码管 位引脚-->P45 *
- * 所有的数码管 段引脚-->P2 *
- *******************************************************************************/
- #define MAIN_Fosc 22118400L //定义主时钟
- #include <STC15.H>
- #include <intrins.H>
- #define Timer0_Reload (65536UL -(MAIN_Fosc / 1000)) //Timer 0 中断频率, 1000次/秒
- //#define uchar unsigned char
- //#define uint unsigned int
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
- #define DIS_DOT 0x20
- #define DIS_BLACK 0x10
- #define DIS_ 0x11
- u8 code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数字编码 0.1.2.3.4....9
- u8 qian,bai,shi,ge;
- bit B_1ms; //1ms标志
- u16 msecond;
- u8 flag0; //正负温度标志位
- u8 flag1; //温度超过100度,千位数正常显示
- u16 Get_ADC10bitResult(u8 channel); //AD转换函数声明,channl输入通道选择
- u16 get_temperature(u16 adc); //温度转换函数声明
- /********************************************************************
- * 名称 : Delay()
- * 功能 : 延时
- * 输入 : i
- * 输出 : 无
- ***********************************************************************/
- void delay(u8 i) //延时函数
- {
- u16 j,k;
- for(j=i;j>0;j--)
- for(k=500;k>0;k--);
- }
- /********************************************************************
- * 名称 : display()
- * 功能 : 数码管显示函数
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void display(u8 qian,u8 bai,u8 shi,u8 ge) //显示函数
- {
- if(flag0) //温度低于0度千位数码管显示-
- {
- P2=0XBF;
- P41 = 0;
- delay(5);
- P41 = 1;
- }
- if(flag1) //温度超过100度,千位显示
- {
- P2=table[qian];
- P41 = 0;
- delay(5);
- P41 = 1;
- }
- P2=table[bai];
- P42 = 0;
- delay(5);
- P42 = 1;
- P2=table[shi]&0X7F; //十位显示小数点
- P44 = 0;
- delay(5);
- P44 = 1;
- P2=table[ge];
- P45 = 0;
- delay(5);
- P45 = 1;
- }
- /********************************************************************
- * 名称 : main()
- * 功能 : 主函数
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void main(void)
- {
- long int j;
- P0M1 = 0; P0M0 = 0; //设置为准双向口
- P1M1 = 0; P1M0 = 0; //设置为准双向口
- P2M1 = 0; P2M0 = 0; //设置为准双向口
- P3M1 = 0; P3M0 = 0; //设置为准双向口
- P4M1 = 0; P4M0 = 0; //设置为准双向口
- P5M1 = 0; P5M0 = 0; //设置为准双向口
- P6M1 = 0; P6M0 = 0; //设置为准双向口
- P7M1 = 0; P7M0 = 0; //设置为准双向口
- P1ASF = 0xff; //P1口全部做ADC
- P1 &= 0x00; //设置P1.0口输出低电平确保能采集到外部电平信号
- ADC_CONTR = 0xE0; //90T, ADC power on
- AUXR = 0x80; //定时器0,1T ,16位自动重装
- TH0 = (u8)(Timer0_Reload / 256);//1ms中断一次
- TL0 = (u8)(Timer0_Reload % 256);
- ET0 = 1; //开定时器0中断
- TR0 = 1; //打开定时器0
- EA = 1; //打开总中断
- while(1)
- {
- if(B_1ms) //1ms到
- {
- B_1ms = 0; //清0标志位
- if(++msecond >= 300) //300ms到
- {
- msecond = 0;
- j = Get_ADC10bitResult(2);
- j = get_temperature(j); //计算温度值
- if(j >= 400) flag0 = 0, j -= 400; //温度 >= 0度
- else flag0 = 1, j = 400 - j; //温度 < 0度
- if(j>=1000) flag1=1;
- else flag1=0;//温度超过100度标志位,千位数正常显示
- }
- }
- qian=j/1000;
- bai=j%1000/100;
- shi=j%100/10;
- ge=j%10;
- display(qian,bai,shi,ge);
- }
- }
- //========================================================================
- // 函数: u16 Get_ADC10bitResult(u8 channel)
- // 描述: 查询法读一次ADC结果.
- // 参数: channel: 选择要转换的ADC.
- // 返回: 10位ADC结果.
- // 版本: V1.0, 2012-10-22
- //========================================================================
- u16 Get_ADC10bitResult(u8 channel) //channel = 0~7
- {
- u8 status=0; //判断AD转换结束标志位
- u16 AD_dat=0; //转换结果10位ADC值
- ADC_RES = 0;
- ADC_RESL = 0;
- ADC_CONTR|=0x80; ////开启ADC电源
- _nop_(); _nop_();
- _nop_(); _nop_(); //等待ADC电源稳定
- //开启ADC电源,转换速度300k。启动ADC转换。选择转换通道
- ADC_CONTR = (ADC_CONTR | 0xe0) | 0x08 | channel;
- //while((ADC_CONTR & 0x10) == 0) ; //ADC_CONTR寄存器ADC_FLAG==1
- //ADC_CONTR &= ~0x10; //清零ADC结束标志
- while(status==0) //等待AD转换结束
- {
- status=ADC_CONTR & 0X10;//判断ADC_FLAG转换结束标志位,转换结束硬件置1,必须软件清零
- }
- ADC_CONTR&=0xe7; // 清零ADC_FLAG标志位关闭ADC转换1110 0111
- AD_dat = (ADC_RES << 2)|(ADC_RESL&0X03);//高低字节拼接成一个10位结果
- return AD_dat;
- }
- // MF52E 10K at 25, B = 3950, ADC = 12 bits
- u16 code temp_table[]=
- {
- 25, //-40 0
- 27, //-39 1
- 29, //-38 2
- 31, //-37 3
- 33, //-36 4
- 35, //-35 5
- 38, //-34 6
- 40, //-33 7
- 43, //-32 8
- 46, //-31 9
- 49, //-30 10
- 52, //-29 11
- 55, //-28 12
- 59, //-27 13
- 62, //-26 14
- 66, //-25 15
- 70, //-24 16
- 75, //-23 17
- 79, //-22 18
- 84, //-21 19
- 89, //-20 20
- 94, //-19 21
- 99, //-18 22
- 105, //-17 23
- 110, //-16 24
- 116, //-15 25
- 123, //-14 26
- 129, //-13 27
- 136, //-12 28
- 143, //-11 29
- 150, //-10 30
- 157, //-9 31
- 165, //-8 32
- 173, //-7 33
- 181, //-6 34
- 190, //-5 35
- 198, //-4 36
- 207, //-3 37
- 216, //-2 38
- 225, //-1 39
- 235, //0 40
- 244, //1 41
- 254, //2 42
- 264, //3 43
- 275, //4 44
- 285, //5 45
- 296, //6 46
- 306, //7 47
- 317, //8 48
- 328, //9 49
- 339, //10 50
- 351, //11 51
- 362, //12 52
- 373, //13 53
- 385, //14 54
- 396, //15 55
- 408, //16 56
- 420, //17 57
- 431, //18 58
- 443, //19 59
- 454, //20 60
- 466, //21 61
- 478, //22 62
- 489, //23 63
- 501, //24 64
- 512, //25 65
- 523, //26 66
- 535, //27 67
- 546, //28 68
- 557, //29 69
- 568, //30 70
- 579, //31 71
- 589, //32 72
- 600, //33 73
- 610, //34 74
- 620, //35 75
- 630, //36 76
- 640, //37 77
- 650, //38 78
- 660, //39 79
- 669, //40 80
- 678, //41 81
- 688, //42 82
- 696, //43 83
- 705, //44 84
- 714, //45 85
- 722, //46 86
- 730, //47 87
- 738, //48 88
- 746, //49 89
- 754, //50 90
- 761, //51 91
- 768, //52 92
- 775, //53 93
- 782, //54 94
- 789, //55 95
- 796, //56 96
- 802, //57 97
- 808, //58 98
- 814, //59 99
- 820, //60 100
- 826, //61 101
- 831, //62 102
- 837, //63 103
- 842, //64 104
- 847, //65 105
- 852, //66 106
- 857, //67 107
- 862, //68 108
- 866, //69 109
- 871, //70 110
- 875, //71 111
- 879, //72 112
- 883, //73 113
- 887, //74 114
- 891, //75 115
- 895, //76 116
- 898, //77 117
- 902, //78 118
- 905, //79 119
- 909, //80 120
- 912, //81 121
- 915, //82 122
- 918, //83 123
- 921, //84 124
- 924, //85 125
- 926, //86 126
- 929, //87 127
- 932, //88 128
- 934, //89 129
- 937, //90 130
- 939, //91 131
- 941, //92 132
- 943, //93 133
- 946, //94 134
- 948, //95 135
- 950, //96 136
- 952, //97 137
- 954, //98 138
- 955, //99 139
- 957, //100 140
- 959, //101 141
- 961, //102 142
- 962, //103 143
- 964, //104 144
- 965, //105 145
- 967, //106 146
- 968, //107 147
- 970, //108 148
- 971, //109 149
- 973, //110 150
- 974, //111 151
- 975, //112 152
- 976, //113 153
- 978, //114 154
- 979, //115 155
- 980, //116 156
- 981, //117 157
- 982, //118 158
- 983, //119 159
- 984, //120 160
- };
- /******************** 计算温度 ***********************************************/
- // 计算结果: 0对应-40.0度, 400对应0度, 625对应25.0度, 最大1600对应120.0度.
- // 为了通用, ADC输入为12bit的ADC值.
- // 电路和软件算法设计: Coody
- /**********************************************/
- /******************** 计算温度 ***********************************************/
- // 计算结果: 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; //定义局部变量j,k,min最小值,max最大值;
-
- adc = 1023 - adc; //Rt接地时启用//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标志
- }
复制代码
|