123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- /* include ---------------------------------------------------------*/
- #include "main.h"
- /* private define -------------------------------------------------*/
- #define DS18B20_DQ_SCK_APBxClock_FUN RCC_APB2PeriphClockCmd
- #define DS18B20_DQ_GPIO_CLK RCC_APB2Periph_GPIOA
- #define DS18B20_DQ_GPIO_PORT GPIOA
- #define DS18B20_DQ_GPIO_PIN GPIO_Pin_7
- #define DS18B20_DQ_0 GPIO_ResetBits(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN )
- #define DS18B20_DQ_1 GPIO_SetBits(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN )
- #define DS18B20_DQ_IN() GPIO_ReadInputDataBit( DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN)
- /* private variables ----------------------------------------------*/
- /* private function prototypes ------------------------------------*/
- static void DS18B20_Mode_IPU(void);
- static void DS18B20_Mode_Out_PP(void);
- static void DS18B20_Rst(void);
- static uint8_t DS18B20_Presence(void);
- static uint8_t DS18B20_ReadBit(void);
- static uint8_t DS18B20_ReadByte(void);
- static void DS18B20_WriteByte(uint8_t dat);
- static void DS18B20_SkipRom(void);
- static void DS18B20_MatchRom(void);
- static uint8_t Init(void);
- static void ReadId(uint8_t * ds18b20_id);
- static float GetTemp_SkipRom(void);
- static float GetTemp_MatchRom( uint8_t * ds18b20_id );
- /* public variables -----------------------------------------------*/
- DS18B20_t DS18B20 =
- {
- Init,
- ReadId,
- GetTemp_SkipRom,
- GetTemp_MatchRom
- };
- /**
- * @brief 初始化
- * @param None
- * @retval None
- * @note None
- */
- static uint8_t Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- DS18B20_DQ_SCK_APBxClock_FUN ( DS18B20_DQ_GPIO_CLK, ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init ( DS18B20_DQ_GPIO_PORT , &GPIO_InitStructure );
- DS18B20_DQ_1;
-
- DS18B20_Rst();
-
- return DS18B20_Presence ();
- }
- /**
- * @brief 使DS18B20-DATA引脚变为输入模式
- * @param None
- * @retval None
- * @note None
- */
- static void DS18B20_Mode_IPU(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
- }
- /**
- * @brief 使DS18B20-DATA引脚变为输出模式
- * @param None
- * @retval None
- * @note None
- */
- static void DS18B20_Mode_Out_PP(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
- }
- /**
- * @brief 主机给从机发送复位脉冲
- * @param None
- * @retval None
- * @note None
- */
- static void DS18B20_Rst(void)
- {
- /* 主机设置为推挽输出 */
- DS18B20_Mode_Out_PP();
-
- DS18B20_DQ_0;
- /* 主机至少产生480us的低电平复位信号 */
- DelayClass.DelayUs(750);
-
- /* 主机在产生复位信号后,需将总线拉高 */
- DS18B20_DQ_1;
-
- /*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/
- DelayClass.DelayUs(15);
- }
- /**
- * @brief 检测从机给主机返回的存在脉冲
- * @param None
- * @retval 0 成功 1 失败
- * @note None
- */
- static uint8_t DS18B20_Presence(void)
- {
- uint8_t pulse_time = 0;
-
- /* 主机设置为上拉输入 */
- DS18B20_Mode_IPU();
-
- /* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
- * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
- */
- while( DS18B20_DQ_IN() && pulse_time<100 )
- {
- pulse_time++;
- DelayClass.DelayUs(1);
- }
- /* 经过100us后,存在脉冲都还没有到来*/
- if( pulse_time >=100 )
- return 1;
- else
- pulse_time = 0;
-
- /* 存在脉冲到来,且存在的时间不能超过240us */
- while( !DS18B20_DQ_IN() && pulse_time<240 )
- {
- pulse_time++;
- DelayClass.DelayUs(1);
- }
- if( pulse_time >=240 )
- return 1;
- else
- return 0;
- }
- /**
- * @brief 从DS18B20读取一个bit
- * @param None
- * @retval None
- * @note None
- */
- static uint8_t DS18B20_ReadBit(void)
- {
- uint8_t dat;
-
- /* 读0和读1的时间至少要大于60us */
- DS18B20_Mode_Out_PP();
- /* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
- DS18B20_DQ_0;
- DelayClass.DelayUs(10);
- /* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
- DS18B20_Mode_IPU();
- if( DS18B20_DQ_IN() == SET )
- {
- dat = 1;
- }
- else
- {
- dat = 0;
- }
- /* 这个延时参数请参考时序图 */
- DelayClass.DelayUs(45);
-
- return dat;
- }
- /**
- * @brief 从DS18B20读一个字节,低位先行
- * @param None
- * @retval None
- * @note None
- */
- static uint8_t DS18B20_ReadByte(void)
- {
- uint8_t i, j, dat = 0;
-
- for(i=0; i<8; i++)
- {
- j = DS18B20_ReadBit();
- dat = (dat) | (j<<i);
- }
-
- return dat;
- }
- /**
- * @brief 写一个字节到DS18B20,低位先行
- * @param None
- * @retval None
- * @note None
- */
- static void DS18B20_WriteByte(uint8_t dat)
- {
- uint8_t i, testb;
- DS18B20_Mode_Out_PP();
-
- for( i=0; i<8; i++ )
- {
- testb = dat&0x01;
- dat = dat>>1;
- /* 写0和写1的时间至少要大于60us */
- if (testb)
- {
- DS18B20_DQ_0;
- /* 1us < 这个延时 < 15us */
- DelayClass.DelayUs(8);
-
- DS18B20_DQ_1;
- DelayClass.DelayUs(58);
-
- }
- else
- {
- DS18B20_DQ_0;
- /* 60us < Tx 0 < 120us */
- DelayClass.DelayUs(70);
-
- DS18B20_DQ_1;
- /* 1us < Trec(恢复时间) < 无穷大*/
- DelayClass.DelayUs(2);
- }
- }
- }
- /**
- * @brief 跳过匹配 DS18B20 ROM
- * @param None
- * @retval None
- * @note None
- */
- static void DS18B20_SkipRom(void)
- {
- DS18B20_Rst();
-
- DS18B20_Presence();
-
- DS18B20_WriteByte(0XCC);/* 跳过 ROM */
-
- }
- /**
- * @brief 执行匹配 DS18B20 ROM
- * @param None
- * @retval None
- * @note None
- */
- static void DS18B20_MatchRom(void)
- {
- DS18B20_Rst();
-
- DS18B20_Presence();
-
- DS18B20_WriteByte(0X55); /* 匹配 ROM */
-
- }
- /**
- * @brief 在跳过匹配 ROM 情况下获取 DS18B20 温度值
- * @param None
- * @retval None
- * @note None
- */
- static float GetTemp_SkipRom(void)
- {
- uint8_t tpmsb, tplsb;
- short s_tem;
- float f_tem;
-
- DS18B20_SkipRom ();
- DS18B20_WriteByte(0X44); /* 开始转换 */
-
- DS18B20_SkipRom ();
- DS18B20_WriteByte(0XBE); /* 读温度值 */
-
- tplsb = DS18B20_ReadByte();
- tpmsb = DS18B20_ReadByte();
-
- s_tem = tpmsb<<8;
- s_tem = s_tem | tplsb;
-
- if( s_tem < 0 ) /* 负温度 */
- {
- f_tem = (~s_tem+1) * 0.0625;
- }
- else
- {
- f_tem = s_tem * 0.0625;
- }
- return f_tem;
- }
- /**
- * @brief 在匹配 ROM 情况下获取 DS18B20 ID
- * @param ds18b20_id 用于存放 DS18B20 序列号的数组的首地址
- * @retval None
- * @note None
- */
- static void ReadId(uint8_t * ds18b20_id)
- {
- uint8_t uc;
-
- DS18B20_WriteByte(0x33); //读取序列号
- for ( uc = 0; uc < 8; uc ++ )
- {
- ds18b20_id [ uc ] = DS18B20_ReadByte();
- }
- }
- /**
- * @brief 在匹配 ROM 情况下获取 DS18B20 温度值
- * @param ds18b20_id 存放 DS18B20 序列号的数组的首地址
- * @retval None
- * @note None
- */
- static float GetTemp_MatchRom( uint8_t * ds18b20_id )
- {
- uint8_t tpmsb, tplsb, i;
- short s_tem;
- float f_tem;
-
- DS18B20_MatchRom (); //匹配ROM
-
- for(i=0;i<8;i++)
- {
- DS18B20_WriteByte ( ds18b20_id [i]);
- }
-
- DS18B20_WriteByte(0X44); /* 开始转换 */
- DS18B20_MatchRom (); //匹配ROM
-
- for(i=0;i<8;i++)
- {
- DS18B20_WriteByte (ds18b20_id [i]);
- }
-
- DS18B20_WriteByte(0XBE); /* 读温度值 */
-
- tplsb = DS18B20_ReadByte();
- tpmsb = DS18B20_ReadByte();
-
-
- s_tem = tpmsb<<8;
- s_tem = s_tem | tplsb;
-
- if( s_tem < 0 ) /* 负温度 */
- {
- f_tem = (~s_tem+1) * 0.0625;
- }
- else
- {
- f_tem = s_tem * 0.0625;
- }
- return f_tem;
- }
|