18B20通讯程序-PIC
2012-07-03
sarszhang
标签: ds18b20

这是我在16F877,18F1320,18F1220上通过的18B20程序,18B20主要是延时问题,这个解决了,什么都可以通过。

[原作者没有提供所使用的编译器,由于是C程序,所以大同小异,建议使用时,确认是否与你的编译器兼容]

#include <pic18f1220.h>
#define uch unsigned char
#define unint unsigned int
#define DQ  RB3//定义18B20数据端口  
#define DQ_DIR  TRISB3//定义18B20D口方向寄存器 
#define W1_INPUT 1
#define W1_OUTPUT 0
#define FALSE  0
#define TRUE  !FALSE
#define DQ_HIGH()  DQ_DIR = W1_INPUT
#define DQ_LOW()  DQ = 0; DQ_DIR = W1_OUTPUT
void delay(unint x)
{
    unint d;
    d = x;
    while (--d)
    {;}
}

bit reset(void)//初始化18B20
{
    static bit presence;//定义一个应答信号
    DQ_LOW();
    delay(70);//置总线为低电平并保持至少480us

    DQ_HIGH();//等电阻拉高总线并保持15-60us

    delay(5);
    presence = DQ; //接受应答信号
    delay(20);//延时60-240us

    return (presence); //返回应答信号
}

//*************** 读一位函数******************//
bit read_bit(void)
{
    static bit i;

    DQ_LOW();
    DQ_LOW();
    DQ_HIGH();
    asm("nop");
    asm("nop");
    asm("nop");
    i = DQ;

    delay(3);
    return (i);
}

//*********************写一位函数****************//
void write_bit(uch bitval)
{
    DQ_LOW();
    delay(1);

    if (bitval == 1) {
        DQ_HIGH();

    }

    delay(3);
    DQ_HIGH();
}

//************** 从18B20中读一个字节**************//
uch read_byte(void)
{
    uch i;
    uch j;
    uch value = 0;

    for (i = 0; i < 8; i++) {
        j = read_bit(); //调读位函数

        if (j) { //如果是 1 置1
            value |= (0x01 << i); //先读低位,再读高位
            asm("nop");
            asm("nop");
            asm("nop");
        }
    }//否则置 0
    return (value);
}

//*********************向18B20中 写一个字节**************//
void write_byte(uch val)
{
    uch i;
    uch temp;

    for (i = 0; i < 8; i++) {
        temp = val >> i;
        temp &= 0x01;
        write_bit(temp);//调写位函数

    }
    asm("nop");
    asm("nop");
    asm("nop");
}

main()
{
    uch teml, temh;

    GIE = 0;
    OSCCON = 0X6E; //这是18F1320的频率选择寄存器
    ADCON1 = 0X7F;

    do {
        ;
    }
    while (reset()) ; //复位等待从机应答
    write_byte(0XCC);//忽略ROM匹配
    write_byte(0X44);//发送温度转化命令


    delay(25000);//延时100-300us
    do {
        ;
    }
    while (reset()); //再次复位,等待从机应答

    write_byte(0XCC);//忽略ROM匹配
    write_byte(0XBE);//发送读温度命令
    teml = read_byte(); //读出温度低8

    temh = read_byte(); //读出温度高8位

    DQ_HIGH();//释放总线
}


可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号