[XMG助力国产生态]
@XMGroupe.
本文介绍MC3172驱动DS18B20。
此驱动根据datasheet模拟实现。
1.初始化程序
#define DQ_Groupe GPIOD_BASE_ADDR
#define DQ_IO GPIO_PIN11
u8 DS18B20_Init(void)
{
u16 temp = 0;
u8 i = 0;
INTDEV_SET_CLK_RST(GPIOD_BASE_ADDR,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV2));
GPIO_SET_OUTPUT_EN_VALUE(GPIOD_BASE_ADDR,GPIO_PIN11,GPIO_SET_ENABLE);
//总线拉低 延时642us
GPIO_SET_OUTPUT_PIN_TO_0(GPIOD_BASE_ADDR,GPIO_PIN11);
delay_us(642);
//总线拉高,DS18B20会在15us后将总线拉低
GPIO_SET_OUTPUT_PIN_TO_1(GPIOD_BASE_ADDR,GPIO_PIN11);
delay_us(15);
GPIO_SET_INPUT_EN_VALUE(DQ_Groupe,DQ_IO,GPIO_SET_ENABLE);
temp = (GPIO_GET_INPUT_VALUE_SAFE(DQ_Groupe) & 0x0800) >> 11;
while(temp)
{
temp = (GPIO_GET_INPUT_VALUE_SAFE(DQ_Groupe) & 0x0800) >> 11;
delay_us(10);
i++;
if(i > 100)
{
return 0;
}
}
return 1;
}
2.读写字节
//读一个字节
u8 DS18B20_ReadByte(void)
{
u8 i = 0;
u16 dat = 0;
u8 byte = 0;
for(i = 8; i > 0; i --)
{
//先把总线拉低1us
GPIO_SET_OUTPUT_EN_VALUE(DQ_Groupe,DQ_IO,GPIO_SET_ENABLE);
GPIO_SET_OUTPUT_PIN_TO_0(DQ_Groupe,DQ_IO);
delay_us(1);
//释放总线,延迟6us
GPIO_SET_OUTPUT_PIN_TO_1(DQ_Groupe,DQ_IO);
delay_us(6);
//读取数据
GPIO_SET_INPUT_EN_VALUE(DQ_Groupe,DQ_IO,GPIO_SET_ENABLE);
dat = (GPIO_GET_INPUT_VALUE_SAFE(DQ_Groupe) & 0x0800) >> 11;
byte = (byte >> 1) | (dat << 7);
//等待48us后读取下一位
delay_us(48);
}
return byte;
}
//写一个字节
void DS18B20_WriteByte(unsigned char dat)
{
u8 i = 0;
u16 temp = 0;
for(i = 8; i > 0; i --)
{
//写入每一位数据前先把总线拉低1us
GPIO_SET_OUTPUT_EN_VALUE(DQ_Groupe,DQ_IO,GPIO_SET_ENABLE);
GPIO_SET_OUTPUT_PIN_TO_0(DQ_Groupe,DQ_IO);
delay_us(1);
//写入数据,低位开始
if(dat & 0x01)
{
GPIO_SET_OUTPUT_PIN_TO_1(DQ_Groupe,DQ_IO);
}
else
{
GPIO_SET_OUTPUT_PIN_TO_0(DQ_Groupe,DQ_IO);
}
dat = dat >> 1;
//总线数据持续60us
delay_us(60);
//释放总线,延时1us
GPIO_SET_OUTPUT_PIN_TO_1(DQ_Groupe,DQ_IO);
delay_us(1);
}
}
3.读取温度
int DS18B20_ReadTemp(void)
{
int temp = 0;
u8 tmh,tml;
//启动转换
DS18B20_Init();
delay_ms(1);
DS18B20_WriteByte(0xcc);
DS18B20_WriteByte(0x44);
//发送温度读取指令
DS18B20_Init();
delay_ms(1);
DS18B20_WriteByte(0xcc);
DS18B20_WriteByte(0xbe);
//读取温度
tml = DS18B20_ReadByte();
tmh = DS18B20_ReadByte();
temp = (tmh << 8) | tml;
return temp;
}
4.数据转换为浮点
float datatrans(int temp)
{
float temp_re = 0;
float tp;
if(temp < 0) //当温度值为负数
{
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp = temp - 1;
temp = ~temp;
tp = temp;
temp_re = tp*0.0625+0.0005;//四舍五入
temp_re = temp_re * (-1);
}
else
{
tp = temp;
temp_re = tp*0.0625+0.0005;
}
return temp_re;
}
最终效果
离线
这是一个有温度的帖子
离线