?? 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 + -