数字传感器(M1820B)
M1820B是一款16-bit ADC,具有-70°C到+150°C的超宽工作范围的高精度单总线数字温度测量芯片。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。并且有多种封装可以满足用户需求,DFN8、SOT23-3、TO92S。
器件特性:
- 最高测量精度:±0.5°C
- 测量范围:-70°C到+150°C
- 低功耗:典型待机电流0.1uA@3.3V,测温峰值电流0.45mA@3.3V,测温平均电流5.2uA(@3.3V,1s周期)
- 宽工作电压范围:1.8V-5.5V
- 感温分辨率:16位输出0.004℃
- 温度转换时间可配置:10.5ms/5.5ms/4ms
- 可配置单次/周期测量
- 用户可设置温度报警
- 32bit额外EEPROM空间用于存放用户信息
- 每颗芯片有64bit的ID序列号,便于多点组网寻址
- 标准单总线接口
硬件设计:
M1820B一共有三个引脚,分别是:
- GND:电源地线
- DQ:数字信号输入/输出端。
- VDD:外接供电电源输入端。
软件设计:
温度数字输出16bit 有符号二进制补码,低8位LSB代表小数,分辨率为1/256℃,高8位代表整数,S为符号位。
程序如下:
void M1820B_GPIO_Init(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( M1820B_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = M1820B_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(M1820B_GPIO_PORT, &GPIO_InitStructure);
DS_OUT = 1;
}
/*****初始化DS18B20*****/
void M1820B_Init(void)
{
DS_OUT = 1;
delay_us(8);
DS_OUT = 0; /* 复位脉冲,主机发送 */
delay_us(500); //精确延时,大于480us
DS_OUT = 1;
delay_us(50); // /* 存在脉冲,主机接收 */
DS_IN_MODE
while(0 == DS_IN); // 复位OK */
DS_OUT = 1;
delay_us(480);
DS_OUT_MODE
}
/*****写一个字节*****/
void WriteOneChar(unsigned char Byte)
{
unsigned char i;
DS_OUT_MODE
for(i = 0;i<8;i++)
{
DS_OUT = 0; //下拉总线
delay_us(2); //产生一点时序
DS_OUT = Byte & 0x01; //0x01 00000001 // 0XCC 1100 1100; 0110 0110 ; 0011 0011
delay_us(70); //76.95us
DS_OUT = 1; //上拉总线
delay_us(2);
Byte >>= 1; //dat右移一位
}
}
/*****读一个字节*****/
unsigned char ReadOneChar(void)
{
unsigned char i,j,dat;
DS_OUT_MODE
for(i=0;i<8;i++)
{
DS_OUT = 0;
delay_us(2);
DS_OUT = 1;
delay_us(6);
DS_IN_MODE
j = DS_IN;
delay_us(3);
dat = (dat>>1)|(j<<7);
delay_us(50);
DS_OUT_MODE
DS_OUT = 1;
}
return dat;
}
/*****读取温度*****/
float Get_M1820B_Temp(void)
{
uint8_t Flag=0,Low=0,High=0,Transfer_Temp=0,Transfer_Temp2=0,Transfer_Rsh=0;
uint16_t Real_temp=0x00;
float Tmp=0,Temp_Float=0;
/* 向MB1820B发送指令 */
M1820B_Init();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
M1820B_Init();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
/* 主机发布BE指令后,必须立即产生读时序 */
Low=ReadOneChar(); //读低8位
High=ReadOneChar(); //读高8位
Real_temp = (High<<8)| Low;
//OLED_ShowNum(0,2,Real_temp,5,16); /*显示MB1820B寄存器值*/
/* 开始对采集回来的数据进行处理 */
Temp_Float = (Real_temp & 0xFF) * 0.00390625; /*保留8位小数*/
Transfer_Rsh = (Real_temp&0xFF00) >> 8; /*保留高8位整数,bit15 S为正负号*/
/*补码转原码操作*/
Flag = (Transfer_Rsh&0x80)>>7; /* 判断数据的第15位 即确定正负数 */
if(Flag) /* 假如第15bit为1,即寄存器数据为正数 */
{
Transfer_Temp = Transfer_Rsh;
Transfer_Temp2 = ~(Transfer_Temp)+ 1 ; //对数据取反+1
if((Transfer_Temp2&0x40)>>6) Tmp += 64; else Tmp += 0;
if((Transfer_Temp2&0x20)>>5) Tmp += 32; else Tmp += 0;
if((Transfer_Temp2&0x10)>>4) Tmp += 16; else Tmp += 0;
if((Transfer_Temp2&0x08)>>3) Tmp += 8; else Tmp += 0;
if((Transfer_Temp2&0x04)>>2) Tmp += 4; else Tmp += 0;
if((Transfer_Temp2&0x02)>>1) Tmp += 2; else Tmp += 0;
if((Transfer_Temp2&0x01)>>0) Tmp += 1; else Tmp += 0;
Tmp = -Tmp + 40;
}
else /* 假如第15bit为0,即寄存器数据为正数 */
{
Transfer_Temp2 = Transfer_Rsh; //0x6A
if((Transfer_Temp2&0x40)>>6) Tmp += 64; else Tmp += 0;
if((Transfer_Temp2&0x20)>>5) Tmp += 32; else Tmp += 0;
if((Transfer_Temp2&0x10)>>4) Tmp += 16; else Tmp += 0;
if((Transfer_Temp2&0x08)>>3) Tmp += 8; else Tmp += 0;
if((Transfer_Temp2&0x04)>>2) Tmp += 4; else Tmp += 0;
if((Transfer_Temp2&0x02)>>1) Tmp += 2; else Tmp += 0;
if((Transfer_Temp2&0x01)>>0) Tmp += 1; else Tmp += 0;
Tmp = Tmp + 40;
}
Tmp += Temp_Float;
return(Tmp);
}
百度网盘:链接:https://pan.baidu.com/s/1wtTfWWFdQtCHgQn51gmxKg?pwd=ljpt
提取码:ljpt
--来自百度网盘超级会员V2的分享