要关中断, 在每个字节读写时序发起时的低电平时关中断,时间只有几个US, 不是在整个读写数据期间关中断
以下是一个PIC16F877的用18B20测温的部分程序 #include <pic.h> #include "temperature.h" #include "main.h"
bank1 bit RE2Bit; bank1 bit bStartConversion; bank1 unsigned int TemperatureMs1000; bank1 bit bWaitConversion; bank1 bit bCanRead; bank1 bit tempBit;
void InitTemperatureTest() { TRISE2 = 1; bStartConversion = 1; TemperatureMs1000 = 1000; bWaitConversion = 0; bCanRead = 0; // Not set 18B20,12 bit precision }
bit Reset18B20() { RE2 = 0; TRISE2 = 0; SetDelayTenUs(55);//3+500 US TRISE2 = 1;//Set Input,RES pull High SetDelayTenUs(7);//73 us tempBit = RE2; SetDelayTenUs(24);//240us return tempBit; }
unsigned char ReadOneChar() { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { GIE = 0;//Close Globle Intterupt RE2 = 0;//delay 2us TRISE2 = 0; dat>>=1; asm("NOP"); TRISE2 = 1; //delay 4Us asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); RE2Bit = RE2; GIE = 1;//Open Globle Intterupt
if(RE2Bit) { dat |= 0x80; } SetDelayTenUs(5);//53 us,all > 60Us } return(dat); }
void WriteOneChar(unsigned char dat) { unsigned char j;
for(j=8; j>0; j--) { GIE = 0;//Close Globle Intterupt RE2 = 0;//delay 2us TRISE2 = 0; asm("NOP"); asm("NOP"); RE2 = dat&0x01; GIE = 1;//Open Globle Intterupt SetDelayTenUs(6);//63us TRISE2 = 1; dat>>=1; } SetDelayTenUs(10);//103us }
bit StartTemperatureTest() { if(!Reset18B20()) { WriteOneChar(0xCC); // ignore ROM Oprator WriteOneChar(0x44); // start temperature conversion bStartConversion = 0; TemperatureMs1000 = 1000; bWaitConversion = 1; return 1; } return 0; }
unsigned char ReadTemperature() { unsigned char a=0; unsigned char b=0; unsigned char t=0; if(!Reset18B20()) { WriteOneChar(0xCC); // ignore ROM Oprator WriteOneChar(0xBE); //read cmd a=ReadOneChar(); //low char b=ReadOneChar(); //high char a=a>>4; //低位右移4位,舍弃小数部分 t=b<<4; //高位左移4位,舍弃符号位 t |= a; t |= (b & 0x80); bCanRead = 0; bStartConversion = 1; } return(t); }
|