代码讲解(c8t6)
温度传感器ds18b20
DS18B20_Init
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PORTA.8 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_8); //输出1
DS18B20_Rst();
return DS18B20_Check();
}
这段代码只有DS18B20_Rst和DS18B20_Check我们没有见到过,我们先对DS18B20_Rst go to definition
DS18B20_Rst
//复位DS18B20
void DS18B20_Rst(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PORTA.8 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_8); //输出0
delay_us(750); //拉低750us
GPIO_SetBits(GPIOA,GPIO_Pin_8); //输出1
delay_us(15); //15us
}
由程序可知,PA8先拉低750us,再拉高15us,为什么这样做?
答:看ds18b20的数据手册知道:
控制器发送400960us低+1560us高形式的脉冲后,ds18b20会再返回一个60-240us的脉冲。
函数DS18B20_Rst()作用是使控制器发送750us低+15us高形式的脉冲,来初始化DS18B20时序。
那用怎么判断ds18b20返回的脉冲是不是60-240us呢?
对DS18B20_Check go to definition
DS18B20_Check
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void)
{
u8 retry=0;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PORTA.8 上拉输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
while (DS18B20_DQ_IN && retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)//等待200us,还不拉低
{
return 1;//直接返回错误
}
else retry=0;//能进到else,表示ds18b20已经有反应,电平变低
while (!DS18B20_DQ_IN && retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}
DS18B20_DQ_IN && retry<200表示在ds18b20还没相应,即DS18B20_DQ_IN为1,且未相应时间<200us时,就一直等待ds18b20相应,如果到200us时ds18b20还没有相应,就直接返回错误。
!DS18B20_DQ_IN && retry<240,表示ds18b20有反应时,DS18B20_DQ_IN为0,则!DS18B20_DQ_IN为1,且响应时间不超过240us,返回相应成功,但如果相应时间超过了240us,也直接返回错误。
DS18B20_Get_Temp
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
short DS18B20_Get_Temp(void)
{
u8 temp;
u8 TL,TH;
short tem;
DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc); // skip rom
DS18B20_Write_Byte(0xbe); // convert
TL=DS18B20_Read_Byte();