📄 tklxy18b20pic.c
字号:
#include<pic.h>
#include<pic12f6x.h>
__CONFIG(INTIO&UNPROTECT&BORDIS&PWRTEN&MCLRDIS);
#define uch unsigned char
#define unint unsigned int
const unsigned char cs @ 0x3ff; //内部振荡器校准
unsigned char temp_data[]={0x00,0x00}; //读出温度暂放
float wendu1=0,wendu0=0; //分别存放十进制的温度的整数部分和小数部分
float wendu=0; //用于存放十进制的温度
unint dingshi=0;
unint chuzhi=0;
uch i=3;
//************11us延时函数*************/
void delay(unint d)
{
while(--d)
{;}
}
//************18b20复位函数************/
reset(void)
{
char presence=1;
while(presence)
{
GPIO5=0;
TRIS5=0; //主机拉至低电平
delay(5); //延时550us
TRIS5=1; //释放总线等电阻拉高总线,并保持15~60us
delay(5); //延时66us
if(GPIO5==1) presence=1;
else presence=0; //接收到应答信号
delay(44); //延时500us
TRIS5=1; //主机拉至高电平
}
}
//************18b20写字节函数************/
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
GPIO5=0;
TRIS5=0; //从高拉至低电平
NOP();
NOP();
NOP(); //3us
temp=val&0x01; //最低位移出
if(temp==1) TRIS5=1; //如果写1,拉高电平
delay(4);
val=val/2;//右移一位
TRIS5=1;
NOP();
NOP();
NOP();
}
}
//************18b20读字节函数************/
uch read_byte(void)
{
uch i;
uch value=0;
uch j=0;
for(i=8;i>0;i--)
{
GPIO5=0;
TRIS5=0;
NOP();
NOP();
NOP(); //3us
TRIS5=1;
NOP();
NOP();
NOP(); //3us
j=GPIO5;
value>>=1;
if(j) value|=0x80;
delay(4); //66us
}
return(value);
}
//*************读温度函数**************/
read_temp()
{
reset(); //总线复位
write_byte(0xCC); //发Skip ROM命令
write_byte(0x44); //发转换命令
reset();
write_byte(0xCC); //Skip ROM
write_byte(0xBE); //发读命令
temp_data[0]=read_byte(); //读出18b20的1字节
temp_data[1]=read_byte(); //读出18b20的2字节
TRIS5=1;
}
//**************处理温度函数*************/
work_temp()
{
float pinlv;
if(temp_data[1]<127) //判断温度的正负,为正则做
{
wendu1=temp_data[0]/16+temp_data[1]*16; //将二进制温度整数部分转化为十进制
wendu0=(temp_data[0]&0x0f)*0.0625; //将二进制温度小数部分转化为十进制
wendu=wendu1+wendu0; //存放采集到的十进制温度
}
pinlv=wendu*8+200; //频率=整数温度*8+200
dingshi=(int)(500000/pinlv); //定时时间=1000000/(2*频率)us半个周期,20为定时器调整值
chuzhi=65535-dingshi+11;
}
//**************12f629初始化**************/
void initial()
{
INTCON=0X00; //初始化
CMIE=0; //禁止比较器中断
CMCON=0x13; //关比较器
CMIF=0;
WPU5=1; //使能上拉
TRISIO=0x2a; //初始化端口
OPTION=0x0b; //端口上拉使能,将分频器分给看门狗,分频比为1:8
}
//************定时器1初始化函数************/
void tm1int()
{
T1CON=0x00; //TMR1工作于定时器方式
PEIE=1; //使能所有未屏蔽的外设中断
TMR1IE=1; //TMR1中断允许
TMR1IF=0; //清除TM1的中断标志
TMR1H=chuzhi>>8; //将chuzhi的高八位写入
TMR1L=chuzhi;
}
//**************定时器中断函数**************/
void interrupt timer()
{
GPIO4=!GPIO4; //GPIO4取反
TMR1IF=0; //清除中断标志
TMR1H=chuzhi>>8;
TMR1L=TMR1L+chuzhi; //GIE=1;
}
//****************主函数*******************/
main()
{
OSCCAL=cs; //内部振荡器校准
initial(); //12f629初始化
GPIO4=1;
VRCON=0xa2; //设置比较电压
reset();
read_temp();
work_temp();
tm1int();
GIE=1; //开全局中断
TMR1ON=1; //打开TMR1定时器
while(1)
{
//CLRWDT();
}
}
//
//*******************结束*******************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -