为了加深对于底层驱动开发的认识和理解,楼主决定自撸常见模块,传感器的驱动程序。-------立贴为证。

DS18B20是一款单总线可编程分辨率的数字温度计,详细内容可见中英文datasheet,笔者不在赘述。

很早就接触到的温度传感器,也相信每一个曾学习过嵌入式开发的人都用过,笔者在STM32F4上自码DS18B20驱动,有些小小心得:

1.初始化时序要注意,笔者亲测,在MCU控制单总线为低电平240us即可(数据手册上要求至少480us)释放总线,等待60us后即可检测到到DS18B20返回的拉低单总线信号,此处,需注意至少应在此等待120us,否则可能会导致温度传感器无法正常工作。

2.初学者需注意时序,对于DS18B20的操作都必需经过三步:初始化,ROM命令(多为跳过指令0xCC),DS18B20功能命令。再次强调对其的每一个操作必须经过这三步,可阅读code加深理解。

3.在读取DS18B20时,注意顺序,DS18B20先发送低位,在字节读取时应当注意。

4.初学者应尝试实现对于DS18B20内部ROM的8位系列号(28H),和48位唯一序列号进行读取,以及修改温度传感器内部EEPROM的过温、低温报警值。(可参考笔者code)

废话不多说,上码:

#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 检测
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("检测到DS18B20!\r\n");}}
//设置为主设备写总线,从设备读总线
void init_onewire_out( void )
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟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;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
}
//设置为主设备读取总线,从设备写总线
void init_onewire_in( void )
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟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;//100MHzGPIO_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;     //写1delay_us(15);DQ_Out=1;delay_us(60);}else{DQ_Out=0;        //写0delay_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;elsebit=0;delay_us(50);return bit;
}
//读ds18b20的字节
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先发送地位到总线上j=j<<i;data |=j;}return data;
}
//获取ds18b20的系列码和48位唯一序列号
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("系列号是:%d\r\n",serial_num);printf("序列号是:%d\r\n",number);printf("CRC校验为:%d\r\n",ds18b20_crc);}
//开启ds18b20温度转换
void tem_chage( void )
{init_ds18b20();ds18b20_write_byte(0xcc);       //忽略rom指令ds18b20_write_byte(0x44);  //开启转换
}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);  //读取温度转换值TL=ds18b20_read_byte();TH=ds18b20_read_byte();if(TH > 7)      //通过判读存储器的高五位的0,1来判断温度的正负,{temp = 0; //为负TH =~TH;TL =~TL; }else temp = 1; //为正tem = TH;tem =tem<<8;tem =tem+TL;tem = (double)tem * 0.625;if(temp)return tem;elsereturn -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);  //读取温度转换值data = ds18b20_read_byte();data = ds18b20_read_byte();data_TH = ds18b20_read_byte();data_TL = ds18b20_read_byte();CONF =ds18b20_read_byte();printf("过温报警的温度为:%d℃\r\n",data_TH);printf("低温报警的温度为:%d℃\r\n",-(data_TL-128));CONF &=0x60 ;CONF =CONF>>5;switch (CONF) {case 0:printf("ds18b20的测量精度为9位,精度为0.5℃\r\n");break;case 1:printf("ds18b20的测量精度为10位,精度为0.25℃\r\n");break;case 2:printf("ds18b20的测量精度为11位,精度为0.125℃\r\n");break;case 3:printf("ds18b20的测量精度为12位,精度为0.0625℃\r\n");break;default:printf("error!!\r\n");break;}
}
//设置温度报警值和配置精度,TH过温报警值(TH>0),TL低温报警值(TL为负数 ),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);  //写入暂存寄存器 ,过温和低温报警值ds18b20_write_byte(TH);   //写入20°为过温报警值ds18b20_write_byte(TL);    //写入-20°为低温报警值ds18b20_write_byte(dat);  //写入精度init_ds18b20();ds18b20_write_byte(0xcc);      //忽略rom指令ds18b20_write_byte(0x48);  //将写入的暂存寄存器拷入EEPROM
}
void ds18b20_chack_self( void )
{chack_ds18b20();ds18b20_read_rom_number();ds18b20_return_TH_TL_CONF();
}

笔者用串口助手得到结果如下:

驱动程序一:基于STM32自码 DS18B20驱动程序相关推荐

  1. ds18b20驱动程序Linux,基于linux下的ds18b20驱动程序的编写

    基于Linux操作系统下面的驱动程序的编写 一.所用的平台: 硬件平台:Mini2440 Size of NAND:256M linux kernel:linux-2.6.32.2 二.编写ds18b ...

  2. 基于STM32的数模转换芯片AD5328驱动程序

    一个项目中需要输出4路0~5V模拟量,主控芯片为STM32F103单片机,选用了AD5328作为DAC输出: AD5328是ADI的一款DAC芯片,可输出8路模拟量,SPI通讯,自己根据AD5328数 ...

  3. 基于STM32的TLC2543驱动程序

    这个驱动程序是基于3.0固件库来写的,所以具体的配置都很明确,需要注意两点: 1.读写速度不能太高,否则会读取不到数据. 2.注意数据的读取方式,TLC2543有8位.12位.16位三种数据方式,这里 ...

  4. 实验六 实现一个基于内存映射的设备驱动程序

    实验六 实现一个基于内存映射的设备驱动程序 目录 实验六 实现一个基于内存映射的设备驱动程序 实验环境 一.实验目的 二.实验内容 三.实验步骤 四.实验总结 实验环境 操作系统版本:ubuntu-1 ...

  5. Linux系统驱动之分析内核自带的LCD驱动程序_基于IMX6ULL

    百问网技术交流群,百万嵌入式工程师聚集地: https://www.100ask.net/page/2248041 资料下载 coding无法使用浏览器打开,必须用git工具下载: git clone ...

  6. 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)

    简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...

  7. 基于stm32、0.96寸OLED实现的俄罗斯方块小游戏(详细源码注释)

    概述:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的俄罗斯方块小游戏.项目源码地址:点击下载. 硬件要求: 普通摇杆,两个电位器和一个开关组成,左右摇动控制一个电 ...

  8. K_A11_002 基于STM32等单片机驱动DS18B20串口与OLED0.96双显示

    K_A11_002 基于STM32等单片机驱动DS18B20 串口与OLED0.96双显示 一.资源说明 二.基本参数 1.参数 2.引脚说明 三.驱动说明 时序 对应程序: 四.部分代码说明 1.接 ...

  9. 测试基于STM32的ADIS16405评估板,并在匿名四轴上实时显示3轴陀螺仪+3轴加速度计+3轴磁力计 波形。本文最后还公开一个基于C# 的串口波形显示客户端源码。

    标题:测试基于STM32的ADIS16405评估板,并在匿名四轴上实时显示3轴陀螺仪+3轴加速度计+3轴磁力计 波形.本文最好还公开一个基于C# 的串口波形显示客户端源码. 这里附上该评估板的原理图和 ...

最新文章

  1. strong、copy和mutableCopy详解
  2. python性能优化之函数执行时间分析_python性能优化之函数执行时间分析
  3. ELK+Kafka 企业日志收集平台(二)
  4. [Qt教程] 第16篇 2D绘图(六)坐标系统
  5. Vue001_模板语法
  6. 程序员的国庆节如何安排,你想好了吗?
  7. 【转】带你玩转Visual Studio——02.带你新建一个工程
  8. 日志服务数据加工最佳实践: 从其他logstore拉取数据做富化
  9. 基于Kubernetes的Spark部署完全指南
  10. win7 安装 Visual Studio 2015 出现 “Failed to install MSI package 等错误”
  11. C++11 并发指南------std::thread 详解
  12. maven导入模块后重新导入有两个一样的_Testng在Maven中配置Reportng中文乱码解决及笔记记录...
  13. 购买成熟软件产品后的二次开发的问题
  14. 火星坐标转WGS84
  15. rust服务器显示长度,rust服务器设置倍率
  16. chloe.mysql 源码_AceFx-基于Nfine的Chloe官网及后台源码
  17. 【常用方法】小地图的制作
  18. java pdf 签名_java – PDFBox 1.8.10:填充和签名PDF生成无效签名
  19. Partitioning a graph into balanced connected classes: Formulations,separation and experiments
  20. 高级电子技能及生产工艺流水线实训台QY-GY01A

热门文章

  1. 《网络经济与企业管理》第一遍思维导图
  2. 手机屏幕用户点击划线区域热力图
  3. 关闭CentOS系统自动更新服务 及 关闭yum自动下载更新
  4. python模拟拖拽文件_python 基于selenium实现鼠标拖拽功能
  5. [极客大挑战 2019]Secret File 1解题思路
  6. 计算机学科渗透法制教育,学科渗透法制教育教案
  7. 大数据Spark Structured Streaming
  8. 阿布在漏洞复现---心脏滴血(CVE-2014-0160)
  9. Nginx心脏出血漏洞整改脚本【原创】
  10. 小解:offsetWidth与offsetLeft