历史上的今天
返回首页

历史上的今天

今天是:2025年01月14日(星期二)

正在发生

2018年01月14日 | NTC热敏电阻高精度温度计程序

2018-01-14 来源:eefocus

STC12C5406AD 晶振频率为12MHz  

本程序已调试完成: 

功能说明:采用廉价的NTC热敏电阻设计高精度温度计的方案, 

根据NTC热敏电阻的温度特性,采用了较具新意程序算法;摆脱了传统的查表显示温度的方法, 

特点:程序中无须查表,打破了常规的查表显示温度的方法。 

//NTC敏电阻温度显示。 

//DS18B20温度显示。 


#include "stc12c5410ad.h"//头文件 
#include "intrins.h" 
#define uchar unsigned char//宏定义 
#define uint unsigned int//宏定义 

sbit RS=P3^4;//定义I/O的硬件接口 
sbit E=P3^7; 

sbit A_B=P3^2; 
sbit CP=P3^3; 

sbit RT=P1^3;//外接NTC 
sbit R_100K=P1^4;// 
sbit D_J=P1^6;//检测 

sbit DQ=P1^5;////定义I/O的硬件接口--温度 

uint Temperature;//温度暂存单元 
uint Negative_Temperature;//负温度暂存单元 
bit Negative_sign=1;//负温度标志 
unsigned long TEMP_1;//长整形单元 

float Time_RT,Time_R; 

uchar aa,CC,ee; 

uint bb[11]; 

float dd,temp5; 

uchar code DispTab_1[]={’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’A’,’B’,’C’,’D’,’E’,’F’};//1602:0-9 数字 
uchar code DispTab_2[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//温度符号 
uchar DispBuf[6]; //6字节的显示缓冲区 

void delay(uint z)//1ms延时 
{  
uchar x,x1; 
for(;z>0;z--) 

for(x=0;x<114;x++) 

for(x1=0;x1<1;x1++); 




void delay1(uchar x2)//经精准计算,该段程序1次延时时间为 19.53us;多次调用需要重新计算。 

while(x2>0) 

x2--; 




void write_Directive(uchar a)//写指令 
{  
uchar i,temp; 
for(i=0;i<8;i++) 

temp=a; 
temp&=0x80; 
if(temp==0x80) 
A_B=1;  
else  
A_B=0; 
a=a<<1; 
delay1(1); 
CP=0; 
delay1(1); 
CP=1; 
delay1(1); 
CP=0; 


RS=0; 
delay(3); 
E=0; 
delay(3); 
E=1; 
delay(3); 
E=0; 
delay(3); 


void write_Data(uchar a)//写数据 
{  
uchar i,temp; 
for(i=0;i<8;i++) 

temp=a; 
temp&=0x80; 
if(temp==0x80) 
A_B=1;  
else  
A_B=0; 
a=a<<1; 
delay1(1); 
CP=0; 
delay1(1); 
CP=1; 
delay1(1); 


RS=1; 
delay(3); 
E=0; 
delay(3); 
E=1; 
delay(3); 
E=0; 
delay(3); 



void init()//初始化 


TMOD=0x10;//定时器T1工作于方式1,16位计数器 

TH1=0x00; 
TL1=0x00; 

EA=1;//开总中断允许 
ET1=1;//开定时器T1允许控制 
//PT1=1;//开定时器T1中断为最高优先级 
TR1=0;//T1开始运行 

P1M1=0x80; 
P1M0=0x80; 

//aa=TH1; 
//aa=aa<<8; 
//aa|=TL1; 

//Time_RT=aa; 

//Time_RT=Time_RT|TL1; 

_nop_(); 

delay(15); 
write_Directive(0x38); 
delay(5); 
write_Directive(0x38); 
delay(5); 
write_Directive(0x38); 
write_Directive(0x01); 
write_Directive(0x02);///初始化后数据地址为0x80;即第一行,第一个位置 
write_Directive(0x0c); 


void Temperature_symbol()//温度符号 

uchar i; 
for(i=0;i<8;i++) 

write_Directive(0x40+i);//写入温度符号 
write_Data(DispTab_2[i]); 



void write_Data_String()//显示时间函数 
{  
uchar i; 
uint mm,mb; 
mb=temp5; 
// DispBuf[0]=temp/10000;//显示百位 
// mm=temp%10000; 

// DispBuf[1]=mm/1000;//显示十位 
// mm=mm%1000; 

// DispBuf[2]=mm/100;//显示个位 
// mm=mm%100; 

DispBuf[1]=mb/100;//显示小数点:0.001 
mm=mb%100;//显示小数点:0.0001 

DispBuf[2]=mm/10;//显示小数点:0.001 
DispBuf[3]=mm%10;//显示小数点:0.0001 

//i=DispBuf[0];//百位判断,如果为0,则消隐 
//if(i==0) 
// i=10; 

//DispBuf[0]=DispTab_1[i];//查表,取字符 
i=DispBuf[1]; 
DispBuf[1]=DispTab_1[i]; 
i=DispBuf[2]; 
DispBuf[2]=DispTab_1[i]; 
i=DispBuf[3]; 
DispBuf[3]=DispTab_1[i]; 
//i=DispBuf[4]; 
//DispBuf[4]=DispTab_1[i]; 

write_Directive(0x80+0x00);//第一行,第五个位置地址 
write_Data(’N’); 
write_Data(’T’); 
write_Data(’C’); 
//write_Data(’5’); 
//write_Data(’D’); 
//write_Data(’Z’); 
//write_Data(’ ’); 
write_Data(’:’); 

//write_Data(DispBuf[0]);//第一行,第五个位置 


write_Data(DispBuf[1]);//第一行,第七个位置  


write_Data(DispBuf[2]);//第一行,第八个位置 

write_Data(’.’);//第一行,第六个位置 

write_Data(DispBuf[3]);//第一行,第九个位置 

//write_Data(DispBuf[4]);//第一行,第十个位置 

//write_Data(0x00);//第一行,第十三个位置显示温度符号 



void DB18B20_init()//DB18B20复位 

DQ=1; 
delay1(1);//程序1次延时时间为 19.53us 
DQ=0; 
delay1(250);//程序110次延时时间为 965.71us 
DQ=1; 
delay1(10);//程序1次延时时间为 19.53us 
while(DQ==1); 
//if(DQ==0) 
_nop_(); 
// LED_7=~led_7;//led检测复位正常否,如果DB18B20存在,且正常;led闪烁。 
while(DQ==0); 
delay1(40);//程序20次延时时间为 197.32us 



void write_DB18B20(uchar m1)//写DB18B20 
{  
uchar i,m2; 

for(i=0;i<8;i++) 

m2=m1; 
m2=m2&0x01; 
DQ=0; 
_nop_(); 
DQ=1; 
if(m2==0x01) 
DQ=1; 
else  
DQ=0; 
delay1(50);//程序5次延时时间为 54.25us 
m1=m1>>1; 
DQ=1; 




read_DB18B20()//读DB18B20 
{  
uint 1; 
uchar i; 
for(i=0;i<16;i++) 

1=1>>1; 
DQ=1; 
_nop_(); 
DQ=0; 
_nop_(); 
DQ=1; 
_nop_(); 
_nop_(); 
_nop_(); 
_nop_(); 
if(DQ==1) 
1=1|0x8000; 
//else  
// 1=1|0x0000; 
delay1(50);//程序5次延时时间为 54.25us 

return 1;//返回温度值 


void Negative()//温度为零度以下时,将变换温度 

Negative_Temperature=Temperature; 
Negative_Temperature=Negative_Temperature&0xf800; 
if(Negative_Temperature==0xf800) 

Temperature=~Temperature; 
Temperature=Temperature+1; 
Negative_sign=0; 



void write_Data_String1()//显示时间函数 
{  
uchar i; 
unsigned long mm; 
DispBuf[0]=TEMP_1/1000000;//显示百位 
mm=TEMP_1%1000000; 

DispBuf[1]=mm/100000;//显示十位 
mm=mm%100000; 

DispBuf[2]=mm/10000;//显示个位 
mm=mm%10000; 

DispBuf[3]=mm/1000;//显示小数点:0.1 
mm=mm%1000; 

DispBuf[4]=mm/100;//显示小数点:0.01 
mm=mm%100; 

DispBuf[5]=mm/10;//显示小数点:0.001 
DispBuf[6]=mm%10;//显示小数点:0.0001 

i=DispBuf[0];//百位判断,如果为0,则消隐 
if(i==0) 
i=10;  
else if(Negative_sign==0)//负温度判断,如果为0,则温度为负的,显示负号 
i=11; 

DispBuf[0]=DispTab_1[i];//查表,取字符 
i=DispBuf[1]; 
DispBuf[1]=DispTab_1[i]; 
i=DispBuf[2]; 
DispBuf[2]=DispTab_1[i]; 
i=DispBuf[3]; 
DispBuf[3]=DispTab_1[i]; 
i=DispBuf[4]; 
DispBuf[4]=DispTab_1[i]; 
i=DispBuf[5]; 
DispBuf[5]=DispTab_1[i]; 
i=DispBuf[6]; 
DispBuf[6]=DispTab_1[i]; 


write_Directive(0x80+0x40);//第一行,第五个位置地址 

write_Data(’D’); 
write_Data(’S’); 
write_Data(’1’); 
write_Data(’8’); 
write_Data(’B’); 
write_Data(’2’); 
write_Data(’0’); 
write_Data(’:’); 
//write_Data(DispBuf[0]);//第一行,第五个位置 
// 
write_Data(DispBuf[1]);//第一行,第六个位置  
write_Data(DispBuf[2]);//第一行,第八个位置 

write_Data(’.’);//第一行,第七个位置 

write_Data(DispBuf[3]);//第一行,第九个位置 

write_Data(DispBuf[4]);//第一行,第十个位置 

//write_Data(DispBuf[5]);//第一行,第十一个位置 
//write_Data(DispBuf[6]);//第一行,第十二个位置 
write_Data(0x00);//第一行,第十三个位置显示温度符号 



void Timer1() interrupt 3//TR1 

//TR1=0; 

//P1M0=0x08;//P1.3高阻 
/* 
void RT_DJ() 

D_J=0; 
R_100K=0; 
P1M0=0x18;//P1.3,P1.4高阻 
P1M1=0x18;//P1.3,P1.4高阻 

TH1=0x00; 
TL1=0x00; 
P1M0=0x48;//P1.3,P1.6高阻 
P1M1=0x48;//P1.3,P1.6高阻 

R_100K=1; 
TR1=1; 
while(!D_J); 
TR1=0; 
aa=TH1; 
aa=aa<<8; 
aa|=TL1; 
Time_R=aa; 
temp=aa; 

}*/ 

void ADC_Conversion()//ADC开始转 

ADC_CONTR=0x87; 
delay(1); 
ADC_CONTR=0x8f; 
delay(1); 
//while((ADC_CONTR==0x8f)); 
ADC_CONTR=0x87; 
delay(1); 
//temp=ADC_DATA;//高8位 


void main() 


//delay1(5);//程序1次延时时间为 19.53us 
//P1M1=0x80; 
//P1M0=0x80; 
///sbit RT=P1^3;//外接NTC 
//sbit R_100K=P1^4;// 
//sbit D_J=P1^6;//检测 
uchar i; 
cc=0x3d; 
dd=30; 
//goto lk; 
init(); 

Temperature_symbol();//写入温度符号 
while(1) 


DB18B20_init();//DB18B20复位 

write_DB18B20(0xcc);//写DB18B20;0xcc 跳过 ROM 指令 
write_DB18B20(0x44);//写DB18B20;0x44 启动温度转换指令 

delay(1000);//延时1秒 

DB18B20_init();//DB18B20复位 
write_DB18B20(0xcc);//写DB18B20;0xcc 跳过 ROM 指令 
write_DB18B20(0xbe);//写DB18B20;0xbe 读温度指令 
Temperature=read_DB18B20();//读 DB18B20 温度,读出的温度在 Temperature 
Negative();//温度为零度以下时,将变换温度,否则不变 
TEMP_1=Temperature*0.0625*10000;//转换成 十进制(*10000,表示,显示到小数点后4位:0.0000) 
write_Data_String1();//显示温度 


//RT_DJ(); 
for(i=0;i<10;i++) 

ADC_Conversion(); 
bb[i]=ADC_DATA;//高8位; 


Time_RT=bb[0]+bb[1]+bb[2]+bb[3]+bb[4]+bb[5]+bb[6]+bb[7]+bb[8]+bb[9]; 
ee=Time_RT/10; 
//lk: temp=0x46; 
//if(ee==cc) 
//{ 
// temp5=30; 
//} 
if(ee>cc) 

for(i=0;i<94;i++) 

cc=cc+1; 
dd=dd+0.5; 
if(ee==cc) 

temp5=dd*10; 
i=93; 



if(ee
for(i=0;i<30;i++) 

cc=cc-1; 
dd=dd-0.5; 
if(ee==cc) 

temp5=dd*10; 
i=29; 



write_Data_String(); 
delay(100);  


推荐阅读

史海拾趣

HIT(日立)公司的发展小趣事
定期对电路进行检查和维护,及时发现并处理潜在问题,确保电路的安全性和稳定性。
CONEC公司的发展小趣事

1978年,CONEC在利普施塔特创立,标志着公司电子业务的起点。创立初期,公司可能面临着资金、技术和市场等多方面的挑战。然而,凭借着对电子行业的深刻理解和坚定的创业决心,CONEC逐渐在市场中站稳脚跟。1980年,DIN EN 60603系列产品的成功上线生产,为公司赢得了初步的声誉和市场认可,为后续的发展奠定了坚实基础。

Carlisle Interconnect Technologies公司的发展小趣事

随着科技的进步和市场的变化,Carlisle Interconnect Technologies敏锐地捕捉到了新型材料的发展潜力。公司成为第一批采用PTFE(聚四氟乙烯)这种独特材料生产高温电线和电缆的公司之一。PTFE材料具有出色的耐高温、耐腐蚀和电气性能,使得公司的产品在航空航天、电子通信等领域得到了广泛应用。这一创新举措不仅提升了公司的市场竞争力,也为整个行业的技术进步做出了贡献。

Dawning Precision Co Ltd公司的发展小趣事

为了进一步提升产品的品质和可靠性,Dawning加强了品质管理体系的建设。公司引进了先进的生产设备和检测仪器,制定了严格的品质检测流程。同时,Dawning还定期对员工进行品质管理培训,提高员工的品质意识和操作技能。这些措施的实施,使得Dawning的产品在品质上得到了极大的提升,赢得了客户的信赖和好评。

Elcos AG公司的发展小趣事

在电子科技日新月异的21世纪初,Elcos AG由一群志同道合的电子工程师创立。他们看到了电子元器件市场中的机遇,决定专注于研发和生产高性能的电子元器件。初始阶段,公司面临着资金紧张、技术挑战和市场认知度低的困境。然而,凭借对技术的执着和对市场的敏锐洞察,Elcos AG逐步攻克了技术难题,并通过与几家小型电子产品制造商的合作,打开了市场的大门。

AVG [AVG Semiconductors(HITEK)]公司的发展小趣事

AVG深知在竞争激烈的电子行业中,单打独斗难以取得长远的发展。因此,公司积极寻求与行业内外的合作伙伴建立紧密的合作关系。通过与上下游企业建立供应链合作关系,AVG确保了原材料的稳定供应和产品质量的可靠性;通过与高校和研究机构合作开展技术研发,AVG不断引入新的技术和创新思路。这些合作伙伴关系的建立,为AVG的发展提供了有力支持,也促进了整个电子行业的共赢发展。

问答坊 | AI 解惑

关于低频信号发生器的问题,请高手们指教

我的电路设计和程序都编写好了,但是输出波形很不理想,只有方波OK,三角波,锯齿波,正弦波都失真很厉害,求大侠们帮小弟解决下这个问题! ORG 0000H MAIN:          MOV A,#00H      MO ...…

查看全部问答>

运算放大器基本电路30例

运算放大器基本电路30例…

查看全部问答>

2440-camera-display????

在camera驱动的Display_Cam_Image 中 memcpy((void *)(FRAMEBUF_BASE+ (240*pos_y + pos_x) + y*240*2),(void *)buffer_rgb,(QCIF_XSIZE)*2); 这句中 FRAMEBUF_BASE+ (240*pos_y + pos_x) + y*240*2 这个地址为什么要这样计算???…

查看全部问答>

关于ARM+DSP双核开发系统的问题

我们现在做的一个关于嵌入式课题在开发系统选型时遇到了一点问题,因为我们的系统既需要良好的GUI又需要较强大的信号处理能力,因此我们不得不把目光放到了arm+dsp双核开发系统上,但过去的双核开发系统应用相对较少,大多是选取一片独立的arm芯片 ...…

查看全部问答>

讨论:各位在单片机中用什么算法去做菜单?

讨论:各位在单片机中用什么算法去做菜单?   比如我要用89s52和smc1602做个菜单。这个菜单有很多层的,即有子菜单。   不知道各位用的是什么方法和算法?   小弟我一开始就用树和链表方式做的。不好。 & ...…

查看全部问答>

自己做个数子示波器,液晶屏是用那款好!

动手做个示波器,液晶显示屏不知用那款好些.有的说用 NS 12864C,也有的的说用 NS 12864R 有点拿不准.想请教高手.用那款实用好些,二者有何区别.请给欲我答复.感激.谢谢!…

查看全部问答>

【低功耗】LDO的选用技术

LDO 是新一代的集成电路稳压器,它与三端稳压器最大的不同点在于,LDO 是一个自耗很低 的微型片上系统(SoC)。LDO 按 其 静 态 耗 流 来 分 , 分 为 OmniPowerTM / MicroPowerTM / NanoPowerTM 三种产品。OmniPowerTM LDO 的静态电流在 10 ...…

查看全部问答>

深入浅出ARM7

深入浅出ARM7-LPC213x_214x(上).pdf 深入浅出ARM7_LPC213x__214x_下册.pdf…

查看全部问答>

各位大侠看看这个Atmega128单片机接收数据代码有啥问题,谢谢!怀疑是中断接收那里

#include #include #include #define fosc 8000000 #define baud 4800 #define uchar unsigned char #define uint unsigned int char rev_buf[80];        //接收缓存      /*uchar rev ...…

查看全部问答>

cyclone v使用报告——内存内存控制器

使用Altera的UniPHY控制器,采用软核和硬核两种模式,使用的时候一般是PHY跟controller一起使用,例化的时候已经将两者合为一体了。使用软核或硬核的区别只是下图的一个check box是否选上。 本来还好好的,默认没有选上,一点击使用硬核之后,图表 ...…

查看全部问答>