标题:
LM75温度传感器的单片机控制程序 带掉电保护功能
[打印本页]
作者:
metatron
时间:
2017-6-11 21:36
标题:
LM75温度传感器的单片机控制程序 带掉电保护功能
基于STC12C5A60S2芯片,有掉电保护程序
单片机源程序如下:
//LM75温度控制器//
//头文件
#include<STC12C5A60S2.h>
#include<intrins.h>
//宏
#define uchar unsigned char
#define uint unsigned int
#define CONF 0X01 //配置寄存器
#define TEMP 0X00 //温度寄存器只读
#define ALARM 0X03 //超温关闭极限寄存器默认5000H
#define DELAY 0X02 //滞后寄存器默认4B00H
#define WADDR 0X90 //写地址
#define RADDR 0X91 //读地址
//////////////
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴 段
//0, 1, 2 3 4 5 6 7 8 9
uchar out[]={0x01,0x02,0x04,0x08}; //位
uchar discount=0;
sbit sda=P3^5;
sbit scl=P3^4;
sbit os=P3^2;
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^4;
sbit redled=P1^2;
uint disshu=0;
float tempchu;
uchar tempcount=0;
uint Tsettemp;
bit dp=0;
uchar dat;
//IAP
#define ENABLE_IAP 0X83
#define IAP_ADDRESS 0X0000//定义EEPROM 的起始地址
sfrIAP_DATA=0XC2;
sfrIAP_ADDRH=0XC3;
sfrIAP_ADDRL=0XC4;
sfrIAP_CMD=0XC5;
sfrIAP_TRIG=0XC6;
sfrIAP_CONTR=0XC7;
//*****************************************************//函数名
void init(void); //初始化
void start(void); //起始
void stop(void); //终止
void ack(void); //应答
void noack(void); //非应答
bit rack(void); //接受应答位
void send(uchar date); //发送数据 1字节
uchar read(void); //接受数据 1字节
uchar w_config(uchar cdata); //写配置寄存器
uchar Twendu(uchar Twd,uchar wen_high,uchar wen_low); //高低温
float read_16(uchar addr); //读2字节
uchar read8(uchar adder); //读1字节
void disseg(uint seg); //显示
void delay(void); //5us
void delay10ms(void); //10us
void delay500ms(void); //500ms
void kaishi(void); //
//AIP //
void iapidle(); //AIP初始化函数
uchar iapreadbyte(uint addr); //读EEPROM的一个字节地址的内容
void iapprogrambyte(uint addr,uchar dat); //写一个字节的IAP/ISP/EEPROM空间
void iaperasesector(uint addr); //扇区擦除
//*****************************************************//
//初始化
void init(void)
{
scl=1;
delay();
sda=1;
delay();
}
//起始
void start(void)
{
scl=1;
sda=1;
delay();
sda=0;
delay();
scl=0;
}
//终止
void stop(void)
{
scl=0;
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
sda=0;
}
//应答
void ack(void)
{
uchar a;
sda=0;
scl=1;
delay();
while(sda==1&&(a<255))
{
a++;
}
scl=0;
delay();
}
//非应答
void noack(void)
{
sda=1;
scl=1;
delay();
scl=0;
sda=0;
}
//接受应答位
bit rack(void)
{
bit flag;
scl=1;
delay();
flag=sda;
scl=0;
delay();
return flag;
}
//发送数据 1字节
void send(uchar date)
{
uchar s,temp;
temp=date;
for(s=0;s<8;s++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
//接受数据 1字节
uchar read(void)
{
uchar s,temp;
scl=0;
delay();
sda=1;
for(s=0;s<8;s++)
{
scl=1;
delay();
temp=(temp<<1)|sda;
scl=0;
delay();
}
delay();
return temp;
}
//写配置寄存器
uchar w_config(uchar cdata)
{
bit i=0;
start();
send(WADDR);
i=rack();
if(i)
{
stop();
return 0;
}
send(CONF);
i=rack();
if(i)
{
stop();
return 0;
}
send(cdata);
i=rack();
if(i)
{
stop();
return 0;
}
delay();
stop();
}
//写2字节温度
uchar Twendu(uchar Twd,uchar wen_high,uchar wen_low)
{
bit i=0;
start();
send(WADDR);
i=rack();
if(i)
{
return 0;
}
send(Twd);
i=rack();
if(i)
{
return 0;
}
send(wen_high);
i=rack();
if(i)
{
return 0;
}
send(wen_low);
i=rack();
if(i)
{
return 0;
}
delay();
stop();
}
//读16位
float read_16(uchar addr)
{
bit i=0;
float cun16;
uchar cun1,cun2;
start();
send(WADDR);
i=rack();
if(i)
{
stop();
return 0;
}
send(addr);
i=rack();
if(i)
{
stop();
return 0;
}
start();
send(RADDR);
i=rack();
if(i)
{
stop();
return 0;
}
cun1=read();// cun16=read();
//cun16=cun16<<8;
ack();
cun2=read()>>7; //cun16|=read();
noack();
delay();
stop();
if(cun1&0x80)
{
dp=1;
cun16=((~(cun1<<1))>>1+1)+cun2*0.5;
}
else
{
dp=0;
cun16=cun1+cun2*0.5;
}
return cun16;
}
uchar read8(uchar adder)
{
uchar i,m;
start();
send(WADDR);
i=rack();
if(i)
{
return 0;
}
send(adder);
i=rack();
if(i)
{
return 0;
}
start();
send(RADDR);
i=rack();
if(i)
{
return 0;
}
m=read();
noack();
delay();
stop();
return m;
}
//************************************************IAP*************************************************************//
void iapidle() //****初始化函数
{
IAP_CONTR=0; //关闭IAP功能
IAP_CMD=0; //CMD寄存器初始化
IAP_TRIG=0; //清空触发寄存器
IAP_ADDRH=0X80; //数据指针指向非EEPROM区
IAP_ADDRL=0; //CLEAR IAP address to preventmisuse
}
uchar iapreadbyte(uint addr) //读EEPROM的一个字节地址的内容
{
IAP_CONTR=ENABLE_IAP; //设置IAP控制寄存器
IAP_CMD=1; //设置IAP的命令寄存器为读状态
IAP_ADDRL=addr; //设置EERPROM的低8位地址
IAP_ADDRH=addr>>8;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
_nop_();
dat=IAP_DATA;
iapidle();
return dat;
}
void iapprogrambyte(uint addr,uchar dat) //写一个字节的IAP/ISP/EEPROM空间
{
IAP_CONTR=ENABLE_IAP; //打开IAP功能并设置等待时间
IAP_CMD=2; //设置写命令
IAP_ADDRL=addr; //设置字节地址低8位
IAP_ADDRH=addr>>8; //设置字节地址的高8位
IAP_DATA=dat; //写内容
IAP_TRIG=0X5A; //发送触发命令1
IAP_TRIG=0XA5; //发送触发命令2
_nop_(); //等待直到写操作完成 60us
iapidle();
}
void iaperasesector(uint addr) //扇区擦除
{
IAP_CONTR=ENABLE_IAP; //开IAP功能并设置等待时间
IAP_CMD=3; //设置擦除命令
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x5a;
IAP_TRIG=0XA5;
_nop_(); // 21ms
iapidle();
}
//************************************************IAP*************************************************************//
void kaishi(void)
{
P2M0 = 0xff;
P2M1 = 0x00;
P0M0 = 0xff;
P0M1 = 0x00;
TMOD = 0x11;
ET0 = 1; //定时器中断允许
TR0 = 1; //定时器0启动
TH0 = 0x3C; //定时器0初值 1Ms
TL0 = 0xb0;
ET1 = 1; //定时器中断允许
TR1 = 1; //定时器1启动
TH1 = 0xFC; //定时器1初值 1Ms
TL1 = 0x18;
EA=1;
}
void main(void)
{
uchar xuhuan=0;
bit js=1;
uchar dat0;
bit fffz=0;
float Tset;
w_config(0x00);
iapreadbyte(0x00); //读数
dat0=dat;
Twendu(ALARM,dat0,0x00);
Twendu(DELAY,0x00,0x00);
kaishi();
while(1)
{
if(!key1&&js)
{
delay10ms();
if(!key1&&js)
{
js=0;
TR0=0;
Tset=read_16(ALARM)*10;
Tsettemp=Tset;
xuhuan=1;
redled=1;
}
}
while(xuhuan==1)
{
disshu=Tsettemp;
if(!key2&&js)
{
delay10ms();
if(!key2&&js)
{
Tsettemp=Tsettemp+10;
if(Tsettemp>=1500)
{
Tsettemp=1500;
}
js=0;
}
}
if(!key3&&js)
{
delay10ms();
if(!key3&&js)
{
Tsettemp=Tsettemp-10;
if(Tsettemp<=100)
{
Tsettemp=100;
}
js=0;
}
}
if(!key1&&js)
{
delay10ms();
if(!key1&&js)
{
xuhuan=0;
TR0=1;
js=0;
dat=Tsettemp/10;
iaperasesector(0x00); //擦除
iapprogrambyte(0x00,dat); //写入
Twendu(ALARM,dat,0x00);
}
}
if(key1&&key2&&key3)
{
js=1;
}
}
if(key1&&key2&&key3)
{
js=1;
}
}
}
void timer0() interrupt 1 //1000us
{
float huan=0;
float qing;
TH0=0x3c;
TL0=0xb0;
tempcount++;
if(tempcount==3)
{
tempcount=0;
huan=read_16(0x00);
tempchu=huan*10;
disshu=tempchu;
}
if((tempchu!=0)&&(Tsettemp!=0))
{
if(tempchu>=Tsettemp)
{
redled=0;
}
}
}
void timer1() interrupt 3 //1000us
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
LM75温度传感器.rar
(2.89 KB, 下载次数: 29)
2017-6-11 21:36 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1