| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /**
- * @file DS18B20_ATY.c
- *
- * @param Project DEVICE_GENERAL_ATY_LIB
- *
- * @author ATY
- *
- * @copyright
- * - Copyright 2017 - 2026 MZ-ATY
- * - This code follows:
- * - MZ-ATY Various Contents Joint Statement -
- * <a href="https://mengze.top/MZ-ATY_VCJS">
- * https://mengze.top/MZ-ATY_VCJS</a>
- * - CC 4.0 BY-NC-SA -
- * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
- * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
- * - Your use will be deemed to have accepted the terms of this statement.
- *
- * @brief functions of DS18B20 for C platform
- *
- * @version
- * - 1_01_220927 > ATY
- * -# Preliminary version, first Release
- * - Undone
- ********************************************************************************
- */
- #ifndef __DS18B20_ATY_C
- #define __DS18B20_ATY_C
- #include "DS18B20_ATY.h"
- #if 0 /* Legacy implementation disabled after Dev-style refactor */
- /******************************* For user *************************************/
- /******************************************************************************/
- #include "DS18B20.h"
- #include "delay.h"
- #include "usart.h"
- u8 ROM_ID[8];
- u8 Refresh_OLED_Data = 0;
- /*******************************************
- DS18B20 单总线对延时精度要求非常高!!!
- 本程序使用了系统嘀嗒定时器来当做精准延时。
- DQ :GPIOB_7
- *******************************************/
- /*功能:DS18B20初始化*/
- void DS18B20_Init(void)
- {
- /*1.GPIOC口初始化*/
- RCC->APB2ENR |= 1 << 3;
- GPIOB->CRL &= 0x0FFFFFFF;
- GPIOB->CRL |= 0x30000000;
- GPIOB->ODR |= 1 << 7;
- /*2.检测DS18B20设备是否正常*/
- switch(DS18B20_CheckDevice())
- {
- case 0: printf("DS18B20_Init OK!\n"); break;
- case 1: printf("DS18B20设备响应复位信号失败!\n"); break;
- case 2: printf("DS18B20设备释放总线失败!\n"); break;
- }
- }
- /*功能:向DS18B20发送一个复位信号*/
- void DS18B20_SendRestSingle(void)
- {
- /*主机发送复位信号*/
- DS18B20_OutPut_Mode();
- DS18B20_OUT = 0; //拉低总线480~960 us ,对 DS18B20 芯片进行复位
- DelayUs(750);
- DS18B20_OUT = 1;
- DelayUs(15); //释放总线15~60 us
- }
- /*
- 功能:检测DS18B20存在脉冲
- 返回值:
- 0 DS18B20设备正常
- 1 DS18B20设备响应复位信号失败
- 2 DS18B20设备释放总线失败
- */
- u8 DS18B20_CheckReadySingle(void)
- {
- u8 cnt = 0;
- /*1.检测存在脉冲*/
- DS18B20_InPut_Mode();
- while(DS18B20_IN && cnt < 240) //等待DS18B20 拉低总线 (60~240 us 响应复位信号)
- {
- DelayUs(1);
- cnt++;
- }
- if(cnt > 240) return 1;
- /*2.检测DS18B20是否释放总线*/
- cnt = 0;
- DS18B20_InPut_Mode();
- while((!DS18B20_IN) && cnt < 240) //判断DS18B20是否释放总线(60~240 us 响应复位信号之后会释放总线)
- {
- DelayUs(1);
- cnt++;
- }
- if(cnt > 240) return 2;
- else return 0;
- }
- /*
- 功能:检测DS18B20设备是否正常
- 返回值:
- 0 DS18B20设备正常
- 1 DS18B20设备响应复位信号失败
- 2 DS18B20设备释放总线失败
- */
- u8 DS18B20_CheckDevice(void)
- {
- DS18B20_SendRestSingle();/*1.主机发送复位信号*/
- return DS18B20_CheckReadySingle();/*2.检测存在脉冲*/
- }
- /*功能:向DS18B20写一个字节数据(命令)*/
- u8 BS18B20_WriteByte(u8 cmd)
- {
- u8 i = 0;
- DS18B20_OutPut_Mode();
- for(i = 0; i < 8; i++)
- {
- DS18B20_OUT = 0;
- DelayUs(2); //主机拉低总线写数据时间隙2us
- DS18B20_OUT = cmd & 0x01; //如果该写入位为1,必须在15us之内把总线拉高,为0 保持60us即可。
- DelayUs(60); //确保DS18B20已经成功读取到该位数据
- DS18B20_OUT = 1; //一位发送完成
- cmd >>= 1;
- DelayUs(2); //位间隙2us
- }
- return 0;
- }
- /*功能:从DS18B20读取一个字节数据*/
- u8 DS18B20_ReadByte(void)
- {
- u8 i, data = 0;
- for(i = 0; i < 8; i++)
- {
- DS18B20_OutPut_Mode();//初始化为输出模式
- DS18B20_OUT = 0;
- DelayUs(2); //主机拉低总线读数据时间隙2us
- DS18B20_OUT = 1; //释放总线,准备读取位数据
- DS18B20_InPut_Mode(); //初始化为输入模式
- DelayUs(10); //等待DS18B20的数据输出
- data >>= 1; //高位补0,默认以0为准
- if(DS18B20_IN) data |= 0x80;
- DelayUs(60); //延时确保DS18B20采样周期已经过去(非常重要)
- DS18B20_OUT = 1; //释放总线准备读取下一位位数据
- }
- return data;
- }
- /*
- 函数功能: 读取一次DS18B20的温度数据
- 返 回 值: 读取的温度数据
- 考虑的情况: 总线上只是接了一个DS18B20的情况
- */
- u16 DS18B20_GetTemperature(void)
- {
- u16 temp = 0;
- u8 temp_H, temp_L;
- int intT, decT;
- DS18B20_CheckDevice(); //发送复位脉冲、检测存在脉冲
- BS18B20_WriteByte(0xCC); //跳过ROM序列检测
- BS18B20_WriteByte(0x44); //启动一次温度转换
- //等待温度转换完成
- while(DS18B20_ReadByte() != 0xFF){}
- DS18B20_CheckDevice(); //发送复位脉冲、检测存在脉冲
- BS18B20_WriteByte(0xCC); //跳过ROM序列检测
- BS18B20_WriteByte(0xBE); //读取温度
- temp_L = DS18B20_ReadByte(); //读取的温度低位数据
- temp_H = DS18B20_ReadByte(); //读取的温度高位数据
- temp = temp_L | (temp_H << 8); //合成温度
- intT = temp >> 4; /*合成实际温度整数部分****精度相对上面的更高*/
- decT = temp & 0xF; /*合成实际温度小数部分*/
- printf("温度:%d.%d ℃ \n", intT, decT);
- return temp;
- }
- ///*功能:从DS18B20读取温度值,多点测温*/
- //u16 DS18B20_GetTemperature(void)
- //{
- // u16 temp;
- // u8 TL,TH;
- // DS18B20_SendRestSingle(); /*1.主机发送复位信号*/
- // if(DS18B20_CheckReadySingle()) return 0xFF; /*2.检测存在脉冲*/
- // DS18B20_MatchROM(); /*3.匹配 ROM 指令 (仅适用于总线上有多个设备)*/
- BS18B20_WriteByte(0xCC); /*3.跳跃 ROM 指令 (仅适用于总线上只有一个设备)*/
- // BS18B20_WriteByte(0x44); /*4.启动温度转换*/
- // while(DS18B20_ReadByte()!=0xFF); //等待温度转换成功
- // DS18B20_SendRestSingle(); /*5.主机发送复位信号*/
- // if(DS18B20_CheckReadySingle()) return 0xFF; /*6.检测存在脉冲*/
- // DS18B20_MatchROM(); /*6.匹配 ROM 指令 (仅适用于总线上有多个设备)*/
- BS18B20_WriteByte(0xCC); /*7.跳跃 ROM 指令 (仅适用于总线上只有一个设备)*/
- // BS18B20_WriteByte(0xBE); /*8.发送读取温度命令*/
- //
- // TL = DS18B20_ReadByte(); /*9.读取温度高低位、校验位*/
- // TH = DS18B20_ReadByte();
- // DS18B20_SendRestSingle(); /*10.主机发送复位信号,示意停止读取剩下的数据*/
- // temp = TH<<8 | TL; /*11.合成温度值*/
- // return temp;
- //
- temp = temp * 0.0625; /*直接合成实际温度*/
- value = temp * 100 + (value > 0 ? 0.5 : -0.5); //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
- //
- intT = temp >> 4; /*合成实际温度整数部分****精度相对上面的更高*/
- decT = temp & 0xF; /*合成实际温度小数部分*/
- ///* crc = x^8 + x^5 + x^4 + 1*/
- //}
- /*功能:从DS18B20读取ROM信息 (ROM_ID= 28-92-AF-AC-17-13-1-F1)*/
- u8 DS18B20_ReadRomInfo(void)
- {
- u8 i = 0;
- BS18B20_WriteByte(0x33); /*4.启动读取ROM*/
- for(i = 0; i < 8; i++)
- {
- ROM_ID[i] = DS18B20_ReadByte();
- }
- printf("ROM_ID= ");
- for(i = 0; i < 8; i++)
- {
- printf("%X", ROM_ID[i]);
- if(i == 7) printf("\n");
- else printf("-");
- }
- return 0;
- }
- /*
- ROM_ID[0]=0x28
- ROM_ID[1]=0x92
- ROM_ID[2]=0xAF
- ROM_ID[3]=0xAC
- ROM_ID[4]=0x17
- ROM_ID[5]=0x13
- ROM_ID[6]=0x1
- ROM_ID[7]=0xF1
- */
- /*功能:匹配 DS18B20 ROM信息*/
- u8 DS18B20_MatchROM(void)
- {
- u8 i = 0;
- BS18B20_WriteByte(0x55); /*4.匹配64位 ROM 信息*/
- for(i = 0; i < 8; i++)
- {
- BS18B20_WriteByte(ROM_ID[i]);
- }
- return 0;
- }
- // todo: not tested
- #endif /* Legacy implementation end */
- uint8_t DS18B20_InitDev(struct DS18B20_ATY_Dev* dev)
- {
- if (!dev || !dev->drive_low || !dev->release_bus || !dev->read_bus || !dev->delay_us) return 1;
- if (dev->debugEnable == 1 && dev->LOG) dev->LOG("\r\nDS18B20 init done.");
- return 0;
- }
- void DS18B20_ResetDev(struct DS18B20_ATY_Dev* dev)
- {
- __ATY_LOCK(dev);
- dev->drive_low();
- dev->delay_us(750);
- dev->release_bus();
- dev->delay_us(15);
- __ATY_UNLOCK(dev);
- }
- uint8_t DS18B20_CheckReadyDev(struct DS18B20_ATY_Dev* dev)
- {
- __ATY_LOCK(dev);
- uint16_t cnt = 0;
- while (dev->read_bus() && cnt < 240) { dev->delay_us(1); cnt++; }
- if (cnt >= 240) { __ATY_UNLOCK(dev); return 1; }
- cnt = 0;
- while (!dev->read_bus() && cnt < 240) { dev->delay_us(1); cnt++; }
- if (cnt >= 240) { __ATY_UNLOCK(dev); return 2; }
- __ATY_UNLOCK(dev);
- return 0;
- }
- void DS18B20_WriteByteDev(struct DS18B20_ATY_Dev* dev, uint8_t cmd)
- {
- __ATY_LOCK(dev);
- for (uint8_t i = 0; i < 8; ++i) {
- dev->drive_low();
- dev->delay_us(2);
- if (cmd & 0x01) {
- dev->release_bus();
- dev->delay_us(60);
- } else {
- dev->delay_us(60);
- dev->release_bus();
- }
- cmd >>= 1;
- dev->delay_us(2);
- }
- __ATY_UNLOCK(dev);
- }
- uint8_t DS18B20_ReadByteDev(struct DS18B20_ATY_Dev* dev)
- {
- __ATY_LOCK(dev);
- uint8_t data = 0;
- for (uint8_t i = 0; i < 8; ++i) {
- dev->drive_low();
- dev->delay_us(2);
- dev->release_bus();
- dev->delay_us(10);
- data >>= 1;
- if (dev->read_bus()) data |= 0x80;
- dev->delay_us(60);
- }
- __ATY_UNLOCK(dev);
- return data;
- }
- uint16_t DS18B20_GetTemperatureDev(struct DS18B20_ATY_Dev* dev)
- {
- __ATY_LOCK(dev);
- uint16_t temp = 0;
- uint8_t temp_L = 0, temp_H = 0;
- DS18B20_ResetDev(dev);
- (void)DS18B20_CheckReadyDev(dev);
- DS18B20_WriteByteDev(dev, 0xCC);
- DS18B20_WriteByteDev(dev, 0x44);
- while (DS18B20_ReadByteDev(dev) != 0xFF) {}
- DS18B20_ResetDev(dev);
- (void)DS18B20_CheckReadyDev(dev);
- DS18B20_WriteByteDev(dev, 0xCC);
- DS18B20_WriteByteDev(dev, 0xBE);
- temp_L = DS18B20_ReadByteDev(dev);
- temp_H = DS18B20_ReadByteDev(dev);
- temp = temp_L | (temp_H << 8);
- if (dev->debugEnable == 1 && dev->LOG) dev->LOG("\r\nDS18B20 read temperature.");
- __ATY_UNLOCK(dev);
- return temp;
- }
- uint8_t DS18B20_ReadRomInfoDev(struct DS18B20_ATY_Dev* dev, uint8_t rom8[8])
- {
- __ATY_LOCK(dev);
- if (!rom8) { __ATY_UNLOCK(dev); return 1; }
- DS18B20_WriteByteDev(dev, 0x33);
- for (uint8_t i = 0; i < 8; ++i) rom8[i] = DS18B20_ReadByteDev(dev);
- if (dev->debugEnable == 1 && dev->LOG) dev->LOG("\r\nDS18B20 read ROM.");
- __ATY_UNLOCK(dev);
- return 0;
- }
- #endif /* __DS18B20_ATY_C */
- /******************************** End Of File *********************************/
|