标题:
stc15w单片机内部自带ADC采集热敏电阻温度数据显示
[打印本页]
作者:
dabing89
时间:
2018-10-13 14:32
标题:
stc15w单片机内部自带ADC采集热敏电阻温度数据显示
利用STC15W内部自带的ADC采集热敏电阻的数据,热敏电阻的型号是50K,MF58-503-3950数据手册上传
MF58+503J3950.pdf
(170.65 KB, 下载次数: 90)
2018-10-13 14:26 上传
点击文件名下载附件
下载积分: 黑币 -5
这个程序在开发板上的现象如下图所示:
温度显示.JPG
(94.26 KB, 下载次数: 95)
下载附件
2018-10-13 14:31 上传
代码如下:
/*******************************************************************************
* 文件名: ADC转换器使用
* 描 述: 实用的温度测试---热敏电阻
* 功 能:中断方式
* 作 者:大核桃QQ597627977
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
#include "stc15w.h"//头文件
#include "intrins.h"
/*******************************************************************************
* 文件名: 重定义
* 描 述:
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
//#define ADC_SPEEDL 0x20 //360个时钟
//#define ADC_SPEEDH 0x40 //180个时钟
//#define ADC_SPEEDHH 0x60 //90个时钟
/*******************************************************************************
* 文件名:全局变量定义区域
* 描 述:
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2015.03.03)
*******************************************************************************/
bit flag_ad1 = 0;//温度采集完成标志
bit flag_coll1 = 0;//数据采集间隔
uint16 Adresult_temp1 = 0;//采集的AD数值xx
uint8 ad_count = 0; //采集AD的次数计数器
uint16 ResTemp;//温度临时结果
uint16 Temper;//温度最终结果
uint16 temp1,temp2,Sensor;//临时结果存放
uint16 Adresult1; //最终结果存放
/*******************************************************************************
* 文件名:共阳数码管真值表
* 描 述:
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2015.03.03)
*******************************************************************************/
code uint8 LedChar[] = {
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0X1C,0x46,0x23,0x48,0xc1
};
uint16 code TempTab0_15[][2] = {//温度转换表,此表为 0~40 度
{962,0},{959,10},{956,20},{953,30},{950,40},{947,50},{944,60},{940,70},{937,80},{933,90},{929,100},
{925,113},{924,115},{923,117},{922,119},
{921,123},{920,125},{919,127},{918,129},
{917,131},{916,133},{915,135},{914,137},{913,139},
{912,143},{911,145},{910,147},{909,149},
};
uint16 code TempTab16_20[][2] = {//温度转换表,此表为 0~40 度
{908,151},{907,153},{906,155},{905,157},{904,159},
{903,161},{902,163},{901,165},{900,167},{899,169},
{898,171},{897,173},{896,175},{895,177},{894,179},
{893,181},{892,183},{891,185},{890,187},{889,189},
{888,191},{887,193},{886,195},{885,197},{884,199},
{883,201},{882,203},{881,205},{880,207},{879,208},{878,209},
};
uint16 code TempTab21_25[][2] = {//温度转换表,此表为 0~40 度
{877,210},{876,211},{875,213},{874,215},{873,217},{872,219},
{871,221},{870,223},{869,225},{868,227},{867,229},
{866,230},{865,231},{864,233},{863,235},{862,237},{861,239},
{860,240},{859,241},{858,243},{857,245},{856,247},{855,248},{854,249},
{853,250},{852,251},{851,253},{850,255},{849,257},{848,259},
};
uint16 code TempTab26_30[][2] = {//温度转换表,此表为 0~40 度
{847,260},{846,261},{845,263},{844,265},{843,267},{842,269},
{841,270},{840,271},{839,273},{838,275},{837,277},{836,279},
{835,280},{834,281},{833,283},{832,285},{831,287},{830,288},{829,289},
{828,290},{827,291},{826,293},{825,295},{824,297},{823,298},{822,299},
{821,300},{820,301},{819,303},{818,305},{817,307},{816,308},{815,309},
};
uint16 code TempTab31_35[][2] = {//温度转换表,此表为 0~40 度
{814,310},{813,311},{812,313},{811,315},{810,317},{809,318},{808,319},
{807,320},{806,321},{805,323},{804,325},{803,327},{802,328},{801,329},
{800,330},{799,331},{798,332},{797,334},{796,335},{795,337},{794,338},{793,339},
{792,340},{791,341},{790,343},{789,345},{788,347},{787,348},{786,349},
{785,350},{784,351},{783,352},{782,353},{781,355},{780,357},{779,358},{778,359},
};
uint16 code TempTab36_40[][2] = {//温度转换表,此表为 0~40 度
{777,360},{776,361},{775,362},{774,363},{773,365},{772,367},{771,368},{770,369},
{769,370},{768,371},{767,372},{766,373},{765,375},{764,377},{763,378},{762,379},
{761,380},{760,381},{759,382},{758,383},{757,385},{756,387},{755,388},{754,389},
{753,390},{752,391},{751,392},{750,393},{749,395},{748,397},{747,398},{746,399},
{745,400},{744,401},{743,402},{742,403},{741,405},{740,407},{739,408},{738,409},
};
/*******************************************************************************
* 文件名:单独位定义
* 描 述:
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
sbit LED0 = P1^0;//第1组LED
sbit LED1 = P1^1;//第2组LED
sbit LED2 = P1^2;//第3组LED
sbit LED3 = P1^3;//第4组LED
sbit LED4 = P1^4;//第5组LED
sbit LED5 = P3^2;//第6组LED
sbit LED6 = P0^0;//第7组LED
sbit LED7 = P0^1;//第8组LED
sbit LEDS1 = P3^3;//数码管1
sbit LEDS2 = P3^4;//数码管2
sbit LEDS3 = P3^6;//数码管3
sbit LEDS4 = P3^7;//数码管4
/*******************************************************************************
* 文件名:函数前置声明
* 描 述:
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void Mcu_Port_Init();
void LedScan();
void Delay500ms(); //24MHZ
void Time0_Init();//定时器0
void InitADC(void);
uint16 Get_Adc_Temp(uint8 times); //AD转换与查表处理程序
void ADC_Refresh(void);
/*******************************************************************************
* 文件名
* 描 述: 主函数
* 功 能:入口
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void main(void)
{
Mcu_Port_Init();//IO上电初始化
Time0_Init();
InitADC();
while(1)
{
Get_Adc_Temp(16); //AD转换与查表处理程序
ADC_Refresh();
}
}
/*******************************************************************************
* 文件名:void LedScan()
* 描 述: LED刷新
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void LedScan()
{
static uint8 i = 0;
P2 = 0Xff;
switch(i)
{
case 0: LEDS4 = 0;LEDS1 = 1;P2 = LedChar[Temper / 100 % 10];i++;break;
case 1: LEDS1 = 0;LEDS2 = 1;P2 = LedChar[Temper / 10 % 10];i++;break;
case 2: LEDS2 = 0;LEDS3 = 1;P2 = LedChar[17];i++;break;
case 3: LEDS3 = 0;LEDS4 = 1;P2 = LedChar[18];i = 0;break;
default:break;
}
}
/*******************************************************************************
* 文件名:void InitADC(void)
* 描 述: //初始化 AD 转换
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2015.03.03)
*******************************************************************************/
void InitADC(void)
{
P1ASF = 0xE0; //设置 P1 口为模拟口
ADC_RES = 0; //清除结果寄存器
CLK_DIV |= 0x20; //ADRJ 为 1,ADC_RES 存放高两位结果,ADC_RESL 存放低 8 位结果
//ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START; //ADC上电并延时
}
/*******************************************************************************
* 文件名:void adc_isr() interrupt 5 using 1
* 描 述: 中断服务程序
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2015.03.03)
*******************************************************************************/
void adc_isr() interrupt 5 using 1
{
EADC = 1;//开ADC中断
ADC_CONTR &= !ADC_FLAG; //清除ADC中断标志
ResTemp = ADC_RES;
ResTemp <<= 8;
ResTemp |= ADC_RESL;
flag_ad1 = 1; //电压采集完成标志
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 6;
EADC = 0;//关闭中断
}
/*******************************************************************************
* 文件名:void Get_Adc_Temp(uint8 times)
* 描 述: 温度数据采集
* 功 能:模块化编程
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
uint16 Get_Adc_Temp(uint8 times) //AD转换与查表处理程序
{
if(flag_coll1) //每次采集AD的时间间隔标志位
{
if(ad_count < times)//连续采集16次后再把求总数据的平均值
{
if(flag_ad1 == 1) //完成一次AD采样
{
flag_ad1 = 0; //清除完成一次采样的标志位
Adresult_temp1 = Adresult_temp1 + ResTemp;
ad_count++;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 6;
}
} //右移动一位数据就相当于整除以2
else //已经采集完16次数据,这个时候把总累加数据除以16就可以求得平均值了
{
Adresult_temp1 >>= 4;
Adresult1 = Adresult_temp1;
Adresult_temp1 = 0;//AD暂存清零
ResTemp = 0; //把采集AD的结果清零
ad_count = 0; //把采集次数重新清零
}
}
return Adresult1;//返回采集的温度数值
}
/*******************************************************************************
* 文件名:void ADC_Refresh(void)
* 描 述: 刷新温度
* 功 能:模块化编程
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void ADC_Refresh(void)
{
static uint8 i = 0;
if((Adresult1 >= 909) && (Adresult1 < 962))
{
for (i = 0; i < sizeof(TempTab0_15); i++) //遍历映射表
{
if (Adresult1 >= TempTab0_15[i][0]) //在表中找到当前,
{
break;
}
}
Temper = TempTab0_15[i][1];
}
else if((Adresult1 >= 878) && (Adresult1 < 908))
{
for (i = 0; i < sizeof(TempTab16_20); i++) //遍历映射表
{
if (Adresult1 >= TempTab16_20[i][0]) //在表中找到当前,
{
break;
}
}
Temper = TempTab16_20[i][1];
}
else if((Adresult1 >= 848) && (Adresult1 < 877))
{
for (i = 0; i < sizeof(TempTab21_25); i++) //遍历映射表
{
if (Adresult1 >= TempTab21_25[i][0]) //在表中找到当前,
{
break;
}
}
Temper = TempTab21_25[i][1];
}
else if((Adresult1 >= 815) && (Adresult1 < 847))
{
for (i = 0; i < sizeof(TempTab26_30); i++) //遍历映射表
{
if (Adresult1 >= TempTab26_30[i][0]) //在表中找到当前,
{
break;
}
}
Temper = TempTab26_30[i][1];
}
else if((Adresult1 >= 778) && (Adresult1 < 814))
{
for (i = 0; i < sizeof(TempTab31_35); i++) //遍历映射表
{
if (Adresult1 >= TempTab31_35[i][0]) //在表中找到当前,
{
break;
}
}
Temper = TempTab31_35[i][1];
}
else if((Adresult1 >= 738) && (Adresult1 < 777))
{
for (i = 0; i < sizeof(TempTab36_40); i++) //遍历映射表
{
if (Adresult1 >= TempTab36_40[i][0]) //在表中找到当前,
{
break;
}
}
Temper = TempTab36_40[i][1];
}
}
/*******************************************************************************
* 文件名:void Time0_Init()
* 描 述: 定时器0初始化
* 功 能:10毫秒@11.0592MHz
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void Time0_Init(void)
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
ET0 = 1;
TR0 = 1; //定时器0开始计时
EA = 1;
}
/*******************************************************************************
* 文件名:
* 描 述: 中断函数
* 功 能:1毫秒@11.0592MHz
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void ET0_IRQHandler() interrupt 1
{
static uint8 tmrcoll1 = 0;//数据采集间隔
EADC = 0; //在定时中断中禁止AD中断
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
tmrcoll1++;//数据采集时间累加
if(tmrcoll1 >= 2) // 2 = 2ms 500HZ //166*100 =16.6MS
{
tmrcoll1 = 0;
flag_coll1 = 1;//数据采集间隔标志位 2ms读取一次数据
}
LedScan();
EADC = 1; //在定时中断中打开AD中断
}
/*******************************************************************************
* 文件名:void Mcu_Port_Init()
* 描 述: io初始化
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void Mcu_Port_Init()
{
IE = 0xa8;//允许AD转换
//将P0口低二位配置为推挽输出
//234567位配置位高阻输入
P0M1 = 0xFC;//1111 1100
P0M0 = 0X03;//0000 0011
//P0 = 0X01;//第6个
//P0 = 0X02;//第7个
//高3位配置高阻输入,用作模拟口
//其他配置推挽输出,驱动LED
P1M1 = 0xE0;//1110 0000
P1M0 = 0X1F;//0001 1111
//P2口配置准双向口
P2M1 = 0X00;
P2M0 = 0X00;
P2 = 0Xff; //上电为1111 1111
// //P54,P55口为推挽输出
P5M1 = 0X00;
P5M0 = 0X00;
P5 = 0xFF;
//P37,P36,3.2,P3.3 P3.4口为推挽输出
P3M1 = 0X00;
P3M0 = 0XFC;
P3 = 0X23; //0010 0111//第5个LED端口
LED0 = 0;//第1组LED,如果使能请置为1
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 0;
}
/*******************************************************************************
* 文件名:void Delay500ms() //@24.000MHz
* 描 述:Y5内核延时
* 功 能:
* 作 者:大核桃
* 版本号:1.0.1(2017.05.23)
*******************************************************************************/
void Delay500ms() //@24.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 46;
j = 153;
k = 245;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
复制代码
程序代码如下
012 热敏电阻测温.rar
(56.27 KB, 下载次数: 172)
2018-10-13 14:32 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
struct00
时间:
2019-2-20 17:29
有一点意思,收下
作者:
elec_hangzhou
时间:
2019-7-5 23:37
下下来看看先 主要是看一下 转换阻值表。 多谢!
作者:
滚回去上学
时间:
2019-7-6 17:22
很利好!
作者:
qxdqx
时间:
2019-7-7 06:06
太好啦.谢谢分享!!!!
作者:
hzw854025403
时间:
2019-7-25 16:04
写的超级好
,收i下了
作者:
cz288
时间:
2019-8-4 15:36
我先看看 学习下
作者:
zuiqf1978
时间:
2021-1-30 15:45
努力学习中!
作者:
wyl138
时间:
2022-10-31 19:50
楼主的帖子对初学者都有很好的参考价值.
作者:
hu2018y
时间:
2022-10-31 20:13
买到10几个都是10K的热敏电阻,怎么样修改温度曲线显示准确。
作者:
sdlyyy
时间:
2023-3-15 08:19
完美思路,值得学习。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1