#include "main.h" #include "delay.h" #define IO_H HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_SET) #define IO_L HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET) #define IO_R HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_11) void M1820_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } unsigned char M1820_Start() { // IO_H; // delay_us(7); // IO_L; // delay_us(80); // IO_H; // delay_us(7); // while(0 == IO_R); // IO_H; unsigned char i = 0; IO_L; //数据线拉0 delay_us(642); //延时480-960us //实际延时642us IO_H; //拉高后延时等待80us,判断DS是否响应,响应数据线会被再次拉低 i=0; while(IO_R) //判断DS是否响应,拉低数据线 { delay_us(10); i++; if(i>5) { return 0; //判断超时,温度传感器为不存在 } } return 1; //温度传感器存在 } void M1820_Wr_Onebyte(unsigned char dat) //先写低位 { unsigned char i = 0; for(i=0;i < 8;i++) { IO_L; delay_us(7); if(dat & 0x01) { IO_H; } else{ IO_L; } delay_us(10);//error1采样器件器件采集自己的就行,主机什么也不用干。 IO_H; dat >>= 1; } } unsigned char M1820_Rd_Onebytr(void) //先读低位 { unsigned char i,j,dat; for(i=0;i<8;i++) { IO_L; delay_us(7); IO_H; j = IO_R; delay_us(14); dat = (dat>>1)|(j<<7); delay_us(5); IO_H; } return dat; } unsigned char Ds18b20ReadByte() //读取数据 { unsigned char j,bi,rdat; rdat = 0; for(j=8;j>0;j--) { IO_L; //1.数据线拉低 2.延时15us 3.数据线拉高,释放总线,准备读数据 //4.延时10us 5.读数据的状态,进行数据处理 6.延时45us delay_us(15); IO_H; //数据线拉高 delay_us(15); bi = IO_R; //读取1bit数据,储存数据 rdat = ( rdat >> 1 ) | (bi << 7 ); //bi = 1, 1000 0000 | 000000 = 1000 0000 delay_us(45); //延时>45us } return rdat; } void Ds18b20WriteByte(unsigned char dat) { unsigned char j; for(j=0;j<8;j++) { IO_L; //1.数据线拉低 2.延时15us 3.发送数据,低位到高位 4.延时60u 5.数据线拉高 delay_us(20); //延时15us //DsPort = dat & 0x01; //发送数据 if(dat & 0x01) { IO_H; } else{ IO_L; } delay_us(30); //延时68us IO_H; //数据线拉高 dat >>= 1; //右移一位,发送下一位 } } void ChangeTemp() //温度转换 { //M1820_Start(); //器件初始化 //delay_us(1000); //延时 Ds18b20WriteByte(0xCC); //CC为跳过ROM,直接可以温度转换 Ds18b20WriteByte(0x44); //44为启动温度转换,一次需要750ms,连续检测可以不进行延时 } void ReadTempCom() //温度读取指令 { //M1820_Start(); //器件初始化 delay_us(1000); //延时 Ds18b20WriteByte(0xCC); //CC为跳过ROM,直接可以温度转换 Ds18b20WriteByte(0xBE); //BE为读取ROM的数据,两个字节 } int temp = 0; unsigned char tmh,tml; //存储温度高/低字节 int ReadTemp() //封装函数,读取温度 { ChangeTemp(); //温度转换 ReadTempCom(); //温度读取 tml = Ds18b20ReadByte(); //ROM的低字节 tmh = Ds18b20ReadByte(); //ROM的高字节 temp = tmh; //存储高字节 temp <<= 8; temp |= tml; //存储低字节 return temp; } int temp; unsigned char tem_h,tem_l,bai,shi,ge,shifen,baifen; char *p1 = "1:"; char *p2 = "2:"; char *p3 = "3:"; char rom_1[8]={0x28,0xFF,0x2D,0x86,0x67,0x18,0x01,0x97};//第三个18B20 char rom_2[8]={0X28,0X00,0X4E,0X45,0X92,0X17,0X02,0X6D}; char rom_3[8]={0x28,0x30,0x5F,0x45,0x92,0x0A,0x02,0x54}; //执行 void M1820_Act(void) { ReadTemp(); // unsigned char i; // float j=0; // // M1820_Start();//18b20开始信号 // // // M1820_Wr_Onebyte(0xcc);//发送跳过ROM的ROM命令 // // // // M1820_Wr_Onebyte(0x44); // M1820_Start();//18b20开始信号 // // M1820_Wr_Onebyte(0x55);//发送匹配ROM命令 // // for(i=0;i<8;i++) // // { // // M1820_Wr_Onebyte(rom_1[i]); // // } // M1820_Wr_Onebyte(0xBE); // // // // tem_l = M1820_Rd_Onebytr(); // tem_h = M1820_Rd_Onebytr(); // // // temp = tem_h; // temp <<= 8; // temp |= tem_l; // if( temp < 0 ) // { // temp = temp - 1; // temp = ~temp; // } // j = temp; // temp = j * 0.0625 * 100 + 0.5; // bai = (temp / 10000) + '0'; // shi = (temp % 10000/1000) + '0'; // ge = (temp % 1000/100) + '0'; // shifen = (temp % 100/10) + '0'; // baifen = temp % 10 + '0'; // M1820_Start(); //18b20开始信号 // M1820_Wr_Onebyte(0xcc); //发送跳过ROM的ROM命令 // M1820_Wr_Onebyte(0x44); // M1820_Start(); //18b20开始信号 // M1820_Wr_Onebyte(0x55); //发送匹配ROM命令 // for(i=0;i<8;i++) // { // M1820_Wr_Onebyte(rom_2[i]); // } // M1820_Wr_Onebyte(0xBE); // tem_l = M1820_Rd_Onebytr(); // tem_h = M1820_Rd_Onebytr(); // temp = tem_h; // temp <<= 8; // temp |= tem_l; // if( temp < 0 ) // { // temp = temp - 1; // temp = ~temp; // } // // j = temp; // temp = j * 0.0625 * 100 + 0.5; // bai = (temp / 10000) + '0'; // shi = (temp % 10000/1000) + '0'; // ge = (temp % 1000/100) + '0'; // shifen = (temp % 100/10) + '0'; // baifen = temp % 10 + '0'; // M1820_Start();//18b20开始信号 // M1820_Wr_Onebyte(0xcc);//发送跳过ROM的ROM命令 // //// for(i=0;i<8;i++) //// { //// rom_3[i] = M1820_Rd_Onebytr(); //// } //// for(i=0;i<8;i++) //// { //// printf("%c",rom_3[i]); //// } // M1820_Wr_Onebyte(0x44); // M1820_Start();//18b20开始信号 // M1820_Wr_Onebyte(0x55);//发送匹配ROM命令 // for(i=0;i<8;i++) // { // M1820_Wr_Onebyte(rom_3[i]); // } // M1820_Wr_Onebyte(0xBE); // tem_l = M1820_Rd_Onebytr(); // tem_h = M1820_Rd_Onebytr(); // temp = tem_h; // temp <<= 8; // temp |= tem_l; // if( temp < 0 ) // { // temp = temp - 1; // temp = ~temp; // } // j = temp; // temp = j * 0.0625 * 100 + 0.5; // bai = (temp / 10000) + '0'; // shi = (temp % 10000/1000) + '0'; // ge = (temp % 1000/100) + '0'; // shifen = (temp % 100/10) + '0'; // baifen = temp % 10 + '0'; }