这次在MM32 eMiniBoard上实现DS18B20测温功能。
首先安装完成MM32-LINK驱动、MM32F3270系列pack文件
硬件如下:
在MM32函数库GPIO_Toggle例程上增加DS18B20驱动代码
DS18B20.c代码如下:
void DS18B20_SetDigitalOutput(void){ GPIO_InitTypeDef GPIO_InitStruct; GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = DS18B20_Pin; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(DS18B20_Port, &GPIO_InitStruct); } void DS18B20_SetDigitalInput(void) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = DS18B20_Pin; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING; GPIO_Init(DS18B20_Port, &GPIO_InitStruct); } //复位DS18B20 void DS18B20_Rst(void) { DS18B20_SetDigitalOutput(); //输出模式 DS18B20_SetLow(); //拉低DQ DELAY_Us(750); //拉低750us(480~960us) DS18B20_SetHigh(); //拉高DQ } //等待DS18B20应答,有应答返回0,无应答返回1 uint8_t DS18B20_Check(void) { uint8_t retry = 0; //进入接收模式,等待应答信号 //等待时间 DS18B20_SetDigitalInput(); //输入模式 DELAY_Us(15); //等待15~60us while(DS18B20_GetValue() && retry < 120) //最多再等待120us { retry++; DELAY_Us(1); }; if(retry >= 120) return 1; //120us未响应,则判断未检测到 else retry = 0; //DS18B20开始拉低DQ while(!DS18B20_GetValue() && retry < 240) //最长拉低240us { retry++; DELAY_Us(1); }; if(retry >= 240) return 1; return 0; } //写字节到DS18B20 void DS18B20_Write_Byte(uint8_t dat) { uint8_t j; uint8_t temp; DS18B20_SetDigitalOutput(); //输出模式 for(j = 1; j <= 8; j++) { temp = dat & 0x01; dat = dat >> 1; if (temp) //输出高 { DS18B20_SetLow(); //拉低DQ DELAY_Us(2); //延时2us DS18B20_SetHigh(); //拉高DQ DELAY_Us(60); //延时60us } else //输出低 { DS18B20_SetLow(); //拉低DQ DELAY_Us(60); //延时60us DS18B20_SetHigh(); //拉高DQ DELAY_Us(2); //延时2us } } DS18B20_SetDigitalInput(); //输入模式 } //从DS18B20读位 uint8_t DS18B20_Read_Bit(void) { uint8_t data; DS18B20_SetDigitalOutput(); //输出模式 DS18B20_SetLow(); //拉低DQ DELAY_Us(2); //延时2us DS18B20_SetHigh(); //拉高DQ DS18B20_SetDigitalInput(); //输入模式 DELAY_Us(12); //延时12us if(DS18B20_GetValue()) //读DQ数据 data = 1; else data = 0; DELAY_Us(50); //延时50us return data; } //从DS18B20读字节 uint8_t DS18B20_Read_Byte(void) { uint8_t i, j, dat = 0; for(i = 1; i <= 8; i++) { j = DS18B20_Read_Bit(); dat = (j << 7) | (dat >> 1); } return dat; } //开始温度转换 void DS18B20_Start(void) { DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0x44); } /*//读取温度值 float DS18B20_Get_Temp(void) { uint8_t sign; //温度符号,0为-,1为+ uint8_t TL, TH; uint16_t temp; float temp1; DS18B20_Start (); _delay_ms(800); //等待转换完成 DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0xbe); TL = DS18B20_Read_Byte(); TH = DS18B20_Read_Byte(); if(TH > 7) { TH = ~TH; TL = ~TL; sign = 0; //温度为负 } else sign = 1; //温度为正 temp = TH; //高八位 temp <<= 8; temp += TL; //低八位 temp1 = (float)temp * 0.0625; //转换实际温度 if(sign) return temp1; //返回温度值 else return -temp1; }*/ //读取温度值 int16_t DS18B20_Get_Temp(void) { uint8_t sign; //温度符号,0为-,1为+ uint8_t TL, TH; uint16_t temp; float temp1; DS18B20_Start(); DELAY_Ms(800); //等待转换完成 DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0xbe); TL = DS18B20_Read_Byte(); TH = DS18B20_Read_Byte(); if(TH > 7) { TH = ~TH; TL = ~TL; sign = 0; //温度为负 } else sign = 1; //温度为正 temp = TH; //高八位 temp <<= 8; temp += TL; //低八位 temp1 = (float)temp * 0.625 + 0.5; //转换实际温度(放大10倍),+0.5四舍五入 temp = (uint16_t)temp1; if(sign) return temp; //返回温度值 else return -temp; } uint8_t DS18B20_Init(void) { DS18B20_Rst(); return DS18B20_Check(); }
复制代码s32 main(void){ int16_t Temperature = 0; GPIO_InitTypeDef GPIO_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = DS18B20_Pin; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(DS18B20_Port, &GPIO_InitStruct); LED_Init(); DELAY_Init(); CONSOLE_Init(9600); if(DS18B20_Init()) { printf("Not detected DS18B20 \r\n "); } else { printf("Detected DS18B20 \r\n"); } while(1) { LED1_TOGGLE(); LED2_TOGGLE(); LED3_TOGGLE(); LED4_TOGGLE(); DELAY_Ms(1000); Temperature = DS18B20_Get_Temp(); printf("Temperature: %d.%d℃ \r\n", Temperature / 10, Temperature % 10); } }
复制代码测试工程:
热门资料
全部回复 0
暂无评论,快来抢沙发吧