標(biāo)題: 基于STM32自碼 DS18B20驅(qū)動(dòng)程序 [打印本頁(yè)]
作者: cloud1256 時(shí)間: 2017-12-27 12:23
標(biāo)題: 基于STM32自碼 DS18B20驅(qū)動(dòng)程序
為了加深對(duì)于底層驅(qū)動(dòng)開(kāi)發(fā)的認(rèn)識(shí)和理解,樓主決定自擼常見(jiàn)模塊,傳感器的驅(qū)動(dòng)程序。-------立貼為證。
DS18B20是一款單總線(xiàn)可編程分辨率的數(shù)字溫度計(jì),詳細(xì)內(nèi)容可見(jiàn)中英文datasheet,筆者不在贅述。
很早就接觸到的溫度傳感器,也相信每一個(gè)曾學(xué)習(xí)過(guò)嵌入式開(kāi)發(fā)的人都用過(guò),筆者在STM32F4上自碼DS18B20驅(qū)動(dòng),有些小小心得:
1.初始化時(shí)序要注意,筆者親測(cè),在MCU控制單總線(xiàn)為低電平240us即可(數(shù)據(jù)手冊(cè)上要求至少480us)釋放總線(xiàn),等待60us后即可檢測(cè)到到DS18B20返回的拉低單總線(xiàn)信號(hào),此處,需注意至少應(yīng)在此等待120us,否則可能會(huì)導(dǎo)致溫度傳感器無(wú)法正常工作。
2.初學(xué)者需注意時(shí)序,對(duì)于DS18B20的操作都必需經(jīng)過(guò)三步:初始化,ROM命令(多為跳過(guò)指令0xCC),DS18B20功能命令。再次強(qiáng)調(diào)對(duì)其的每一個(gè)操作必須經(jīng)過(guò)這三步,可閱讀code加深理解。
3.在讀取DS18B20時(shí),注意順序,DS18B20先發(fā)送低位,在字節(jié)讀取時(shí)應(yīng)當(dāng)注意。
4.初學(xué)者應(yīng)嘗試實(shí)現(xiàn)對(duì)于DS18B20內(nèi)部ROM的8位系列號(hào)(28H),和48位唯一序列號(hào)進(jìn)行讀取,以及修改溫度傳感器內(nèi)部EEPROM的過(guò)溫、低溫報(bào)警值。(可參考筆者code)
廢話(huà)不多說(shuō),上碼:
- #include <ds18b20.h>
- #include "delay.h"
- #include "usart.h"
-
- //ds18b20初始化
- void init_ds18b20( void )
- {
- init_onewire_out();
- GPIO_ResetBits(GPIOG,GPIO_Pin_9);
- delay_us(480);
- init_onewire_in();
- delay_us(60);
- if( !DQ_In)
- {
- delay_us(120);
-
- }
- }
- //ds18b20 檢測(cè)
- void chack_ds18b20( void )
- {
- init_onewire_out();
- GPIO_ResetBits(GPIOG,GPIO_Pin_9);
- delay_us(240);
- init_onewire_in();
- delay_us(60);
- if( !DQ_In)
- {
- delay_us(80);
- if( !DQ_In )
- printf("檢測(cè)到DS18B20!\r\n");
-
- }
-
- }
- //設(shè)置為主設(shè)備寫(xiě)總線(xiàn),從設(shè)備讀總線(xiàn)
- void init_onewire_out( void )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG時(shí)鐘
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
- GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
- }
- //設(shè)置為主設(shè)備讀取總線(xiàn),從設(shè)備寫(xiě)總線(xiàn)
- void init_onewire_in( void )
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG時(shí)鐘
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
- // GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
- GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
- }
-
- void ds18b20_write_byte( u8 data )
- {
- u8 i;
- u8 j=0;
- init_onewire_out();
- for(i=0;i<8;i++)
- {
- j=data & 0x01;
- if(j)
- {
- DQ_Out=0; //寫(xiě)1
- delay_us(15);
- DQ_Out=1;
- delay_us(60);
-
- }
- else
- {
- DQ_Out=0; //寫(xiě)0
- delay_us(60);
- DQ_Out=1;
- delay_us(1);
- }
- data = data>>1;
- }
- }
- //讀取DS18B20 的一位
- u8 ds18b20_read_bit( void )
- {
- u8 bit;
- init_onewire_out();
- DQ_Out=0;
- delay_us(2);
- DQ_Out=1;
- init_onewire_in();
- delay_us(12);
- if(DQ_In)
- bit=1;
- else
- bit=0;
- delay_us(50);
- return bit;
- }
- //讀ds18b20的字節(jié)
- u8 ds18b20_read_byte ( void )
- {
- u8 data=0;
- u8 i;
- u8 j=0;
- for(i=0;i<8;i++)
- {
- j=ds18b20_read_bit();
- if(j) //注意順序即可,ds18b20先發(fā)送地位到總線(xiàn)上
- j=j<<i;
- data |=j;
-
- }
- return data;
- }
- //獲取ds18b20的系列碼和48位唯一序列號(hào)
- void ds18b20_read_rom_number()
- {
- u32 number=0;
- u8 data,i,serial_num,ds18b20_crc;
- init_ds18b20();
- ds18b20_write_byte(0x33);
- serial_num = ds18b20_read_byte();
- for(i=0;i<6;i++)
- {
- data = ds18b20_read_byte();
- number |= data;
- number = number<<8;
- }
- ds18b20_crc = ds18b20_read_byte();
-
- printf("系列號(hào)是:%d\r\n",serial_num);
- printf("序列號(hào)是:%d\r\n",number);
- printf("CRC校驗(yàn)為:%d\r\n",ds18b20_crc);
-
- }
- //開(kāi)啟ds18b20溫度轉(zhuǎn)換
- void tem_chage( void )
- {
- init_ds18b20();
- ds18b20_write_byte(0xcc); //忽略rom指令
- ds18b20_write_byte(0x44); //開(kāi)啟轉(zhuǎn)換
- }
-
- short get_temp( void )
- {
- int temp=0;
- u8 i,TH,TL;
- short tem;
-
- tem_chage();
- delay_us(10);
- init_ds18b20();
- ds18b20_write_byte(0xcc); //忽略rom指令
- ds18b20_write_byte(0xbe); //讀取溫度轉(zhuǎn)換值
- TL=ds18b20_read_byte();
- TH=ds18b20_read_byte();
-
- if(TH > 7) //通過(guò)判讀存儲(chǔ)器的高五位的0,1來(lái)判斷溫度的正負(fù),
- {
- temp = 0; //為負(fù)
- TH =~TH;
- TL =~TL;
- }
- else
- temp = 1; //為正
- tem = TH;
- tem =tem<<8;
- tem =tem+TL;
- tem = (double)tem * 0.625;
- if(temp)
- return tem;
- else
- return -tem;
-
- }
- void ds18b20_return_TH_TL_CONF( void )
- {
- char data,data_TH,data_TL,CONF;
- init_ds18b20();
- ds18b20_write_byte(0xcc); //忽略rom指令
- ds18b20_write_byte(0xbe); //讀取溫度轉(zhuǎn)換值
- data = ds18b20_read_byte();
- data = ds18b20_read_byte();
- data_TH = ds18b20_read_byte();
- data_TL = ds18b20_read_byte();
- CONF =ds18b20_read_byte();
- printf("過(guò)溫報(bào)警的溫度為:%d℃\r\n",data_TH);
- printf("低溫報(bào)警的溫度為:%d℃\r\n",-(data_TL-128));
- CONF &=0x60 ;
- CONF =CONF>>5;
- switch (CONF) {
- case 0:
- printf("ds18b20的測(cè)量精度為9位,精度為0.5℃\r\n");
- break;
- case 1:
- printf("ds18b20的測(cè)量精度為10位,精度為0.25℃\r\n");
- break;
- case 2:
- printf("ds18b20的測(cè)量精度為11位,精度為0.125℃\r\n");
- break;
- case 3:
- printf("ds18b20的測(cè)量精度為12位,精度為0.0625℃\r\n");
- break;
- default:
- printf("error!!\r\n");
- break;
- }
- }
- //設(shè)置溫度報(bào)警值和配置精度,TH過(guò)溫報(bào)警值(TH>0),TL低溫報(bào)警值(TL為負(fù)數(shù) ),mode配置模式0,1,2,3
- //mode=0 精度為9位 00011111 dat=31
- //mode=1 精度為10位 00111111 dat=63
- //mode=2 精度為11位 01011111 dat=95
- //mode=3 精度為12位 01111111 dat =127
- void ds18b20_write_TH_TL_CONF(u8 TH,u8 TL,u8 mode)
- {
- u8 dat;
- switch (mode){
- case 0:
- dat=31;
- break;
- case 1:
- dat=63;
- break;
- case 2:
- dat=95;
- break;
- case 3:
- dat=127;
- break;
- default:
- printf("mode error!!\r\n");
- dat=127;
- break;
- }
- TL=TL+128;
- init_ds18b20();
- ds18b20_write_byte(0xcc); //忽略rom指令
- ds18b20_write_byte(0x4e); //寫(xiě)入暫存寄存器 ,過(guò)溫和低溫報(bào)警值
- ds18b20_write_byte(TH); //寫(xiě)入20°為過(guò)溫報(bào)警值
- ds18b20_write_byte(TL); //寫(xiě)入-20°為低溫報(bào)警值
- ds18b20_write_byte(dat); //寫(xiě)入精度
- init_ds18b20();
- ds18b20_write_byte(0xcc); //忽略rom指令
- ds18b20_write_byte(0x48); //將寫(xiě)入的暫存寄存器拷入EEPROM
- }
- void ds18b20_chack_self( void )
- {
- chack_ds18b20();
- ds18b20_read_rom_number();
- ds18b20_return_TH_TL_CONF();
- }
復(fù)制代碼
筆者用串口助手得到結(jié)果如下: 
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
亚洲黄色在线免费观看
|
欧美激情精品久久久久久
|
精品日韩在线观看
|
啪啪网页|
色888www视频在线观看
|
国产成人福利
|
国产精品久久
|
久久久久久久久久久蜜桃
|
365夜爽爽欧美性午夜免费视频
|
狠狠色狠狠色综合系列
|
国产一伦一伦一伦
|
久久久久久久久久毛片
|
精品久久香蕉国产线看观看亚洲
|
成人黄色网址大全
|
人人人人干
|
奇米影视77
|
国产999精品久久久久久绿帽
|
天堂成人国产精品一区
|
精品一二区
|
免费观看成人鲁鲁鲁鲁鲁视频
|
久久精品成人
|
国产资源在线观看
|
www亚洲成人
|
久久骚
|
欧美日韩精品在线免费观看
|
欧美二区在线
|
天天躁天天操
|
黄篇网址
|
国产成人99久久亚洲综合精品
|
久草视频在线播放
|
91av免费版|
av午夜激情
|
爱爱视频在线观看
|
精品国产三级
|
九九热热九九
|
青青草网
|
欧美一区二区二区
|
久久久久久久av麻豆果冻
|
久久99精品久久久久子伦
|
成人精品国产一区二区4080
|
国产日韩欧美在线播放
|