18B20时序要点 stm32 72M环境

时间:2024-05-19 16:00:27

网上18B20的资料很多,但似乎都找不到要点。官方文档很详尽,但也是通篇不分段18B20时序要点 stm32 72M环境,官方文档就不能1、2、3的给出主要注意点嘛。

这里结合自己调试过程,总结要点如下,使用stm32 72Mhz主频。

18B20时序要点 stm32 72M环境

本幅图包括复位时序与写时序要点。

复位时序

1、拉低至少480us

2、拉高15-60us,读取状态,为0则通过

3、再次延迟时间,实验时过短会影响后续结果的读出,这里实验最短120us左右。

写时序

1、一次写1bit操作最少持续60us

2、低到高的操作需在15us内完成

18B20时序要点 stm32 72M环境

读时序

1、一次读1bit操作需至少持续60us

2、拉低操作持续1us~15us后释放,且在60us内完成读操作


总结:

这种串行操作的器件属于慢外设,一次温度读取包括两次复位,写4字节,读2字节,这里把所有时序压缩到几乎最短,一次读取也需要4.5ms左右,时间很长,因此如果实时性要求高的话,估计得用中断方式操作。

另外,期间感觉写1时序和读时序好像一样的,器件是怎么知道是写1还是读呢?判断应该是通过写“CC”“BE”成功才启动的读过程,而在此之前都是写过程,写完成启动读时序。因此,先调试写、再调试读,是合理的调试过程。


附代码:

#include "18B20.h"


#define DQ_1_H() GPIO_SetBits(GPIOB, GPIO_Pin_4)
#define DQ_1_L() GPIO_ResetBits(GPIOB, GPIO_Pin_4)
#define RD_DQ_1() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4)
#define DQ_2_H() GPIO_SetBits(GPIOB, GPIO_Pin_3)
#define DQ_2_L() GPIO_ResetBits(GPIOB, GPIO_Pin_3)
#define RD_DQ_2() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3)


void delay_nus(u16 time)
{
u16 i=0;
while(time--)
{
i=35;
while(i--);
}
}


u8 Waitready_1(void)
{
u8 presence = 0;

DQ_1_H();
delay_nus(1) ;


DQ_1_L();
delay_nus(105) ;


DQ_1_H();
delay_nus(2) ;


presence = RD_DQ_1();
delay_nus(30) ;
DQ_1_H();


return(presence) ;
}


void Init_18B20(void) {
GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  ///PB4:channal 1
///PB3:channal 2
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

while(Waitready_1() != 0);
}


u8 ReadOneChar_1(void)
{
u8 i = 0 ;
u8 dat = 0 ;


for (i = 8 ; i > 0 ; i--)
  {
    DQ_1_L();
delay_nus(1) ;
    DQ_1_H();
    dat >>= 1 ;
//    DQ_1_H();
delay_nus(1) ;


    if(RD_DQ_1())
     dat |= 0x80 ;
delay_nus(11) ;
  }


return (dat) ;
}


void WriteOneChar_1(unsigned char dat)
{
  u8 i = 0 ;
  for (i = 8 ; i > 0 ; i--)
  {
    if (dat&0x01) {
DQ_1_L();
delay_nus(1) ;
DQ_1_H();
delay_nus(13) ;
}
else {
DQ_1_L();
delay_nus(13) ;
DQ_1_H();
delay_nus(1) ;
}


    dat>>=1 ;
  }
}


s8 Read_Temperature_1(void)
{
u8 temp_data[2];
s8 rtn = 0;

Waitready_1() ;


WriteOneChar_1(0xCC) ;
WriteOneChar_1(0x44) ;


Waitready_1() ;
WriteOneChar_1(0xCC) ;
WriteOneChar_1(0xBE) ;


temp_data[0] = ReadOneChar_1() ;
temp_data[1] = ReadOneChar_1() ;

rtn = (temp_data[1] << 4) | (temp_data[0] >> 4);

if ( rtn > 0 ) {

}
return (rtn);
}