新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于WinAVR的DS18B20源程序

        基于WinAVR的DS18B20源程序

        作者: 時(shí)間:2016-11-23 來源:網(wǎng)絡(luò) 收藏
        #ifndef _DS18B20_C_

        #define _DS18B20_C_

        本文引用地址:http://www.104case.com/article/201611/320578.htm


        #define DQ_18B20 (1<<3) // PD3
        #define DQ_TO_0() (DDRD |= DQ_18B20) // PD3=’0′
        #define DQ_TO_1() (DDRD &= ~DQ_18B20) // PD3=’float’
        #define DQ_status() (PIND & DQ_18B20) // read PD3 pin


        #ifndef CPU_CRYSTAL
        #define CPU_CRYSTAL (11.0592)
        #endif


        #define wait_us(us)
        _delay_loop_2((INT16U)((us)*CPU_CRYSTAL/4))


        // 1個(gè)初始化模塊
        void ds18b20_config(void); // 配置端口

        // 3個(gè)基本模塊
        BOOL ds18b20_reset(void); // 復(fù)位DS18B20
        void ds18b20_write(INT8U dat); // 寫字節(jié)到DS18B20
        INT8U ds18b20_read(void); // 讀字節(jié)從DS18B20

        // 2個(gè)應(yīng)用模塊
        void convert_T(void); // 啟動(dòng)溫度轉(zhuǎn)換
        INT16U read_T(void); // 讀取轉(zhuǎn)換值


        void ds18b20_config(void)
        {
        DDRD &= ~DQ_18B20; // 輸入模式(上電時(shí)為高電平)
        PORTD &= ~DQ_18B20; // 輸出鎖存器寫0,以后不再更改
        }


        BOOL ds18b20_reset(void)
        {
        BOOL bus_flag;

        DQ_TO_0(); // 設(shè)置1-wire總線為低電平(占領(lǐng)總線)…


        wait_us(490); // 490us

        cli(); // 下面這段時(shí)間要求比較嚴(yán)格,為保險(xiǎn)起見,關(guān)中斷
        DQ_TO_1(); // 設(shè)置1-wire總線為高電平(釋放總線)


        wait_us(67.5); // 最佳時(shí)間: 60us+7.5us!(忙延時(shí),只是一種策略)

        // 探測(cè)總線上是否有器件
        if(DQ_status()) bus_flag=FAIL; // 復(fù)位單總線但沒有發(fā)現(xiàn)有器件在線
        else bus_flag=SUCC; // 復(fù)位單總線并發(fā)現(xiàn)有器件在線

        sei(); // 退出臨界代碼區(qū)(開中斷)


        wait_us(490-67.5); // 490-67.5us

        return(bus_flag);
        }


        void ds18b20_write(INT8U dat)
        {
        INT8U count;

        // 每個(gè)字節(jié)共8位,一次發(fā)一位
        for(count=0; count<8; count++) {
        cli(); // 保證絕對(duì)不會(huì)發(fā)生中斷!
        DQ_TO_0(); // 設(shè)置1-wire總線為低電平
        wait_us(2); // about 2us

        if(dat&0×01) DQ_TO_1(); // 并串轉(zhuǎn)換,先低位后高位
        else DQ_TO_0();
        dat >>= 1; // 下一位做好準(zhǔn)備

        // 60us~120us(實(shí)際不能到120us, 因?yàn)槠渌Z句也用時(shí)間了!)
        wait_us(62); // 62us

        DQ_TO_1();
        sei(); // 恢復(fù)系統(tǒng)中斷
        wait_us(2); // 2us
        }
        }


        INT8U ds18b20_read(void)
        {
        INT8U count,dat;

        dat = 0×00; // 數(shù)據(jù)接收準(zhǔn)備

        // 每個(gè)字節(jié)共8位,一次收一位
        for(count=0; count<8; count++) {
        cli(); // 保證絕對(duì)不會(huì)發(fā)生中斷!

        // 從總線拉低到讀總線狀態(tài),不能大于15us!
        DQ_TO_0(); // 設(shè)置1-wire總線為低電平(拉低總線以同步)
        wait_us(2); // 2us
        DQ_TO_1(); // 設(shè)置1-wire總線為高電平(釋放總線)
        wait_us(4); // 4us
        dat >>= 1;
        if(DQ_status()) dat|=0×80; // 讀取總線電平,先收低位再收高位

        sei(); // 恢復(fù)系統(tǒng)中斷
        wait_us(62); // 必須大于60us
        }
        return(dat);
        }


        void convert_T(void)
        {
        if(ds18b20_reset()==SUCC) { // 如果復(fù)位成功
        ds18b20_write(0xcc); // 跳過多器件識(shí)別
        ds18b20_write(0×44); // 啟動(dòng)溫度轉(zhuǎn)換
        }
        }


        INT16U read_T(void)
        {
        INT16U value=0;

        if(ds18b20_reset()==SUCC) { // 如果復(fù)位成功
        ds18b20_write(0xcc); // 跳過多器件識(shí)別
        ds18b20_write(0xbe); // 讀暫存器
        value = (INT16U)ds18b20_read(); // 低字節(jié)
        value += (INT16U)(ds18b20_read())<<8; // 高字節(jié)
        }
        return(value);
        }

        #endif



        關(guān)鍵詞: WinAVRDS18B20源程

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 新和县| 安岳县| 斗六市| 团风县| 安徽省| 和田市| 通州区| 南京市| 汉沽区| 山西省| 东城区| 高清| 西藏| 海盐县| 扎囊县| 积石山| 子洲县| 高州市| 佛山市| 扶余县| 青河县| 横山县| 尤溪县| 延寿县| 洛南县| 桐庐县| 紫云| 鄱阳县| 交口县| 三亚市| 巴彦淖尔市| 准格尔旗| 潜山县| 台前县| 灵武市| 乐东| 北票市| 峡江县| 六安市| 十堰市| 黔西县|