本帖最后由 Kalman 于 2021-10-26 19:15 编辑

这次在MM32 eMiniBoard上实现DS18B20测温功能。
首先安装完成MM32-LINK驱动、MM32F3270系列pack文件

硬件如下:
1.png
微信图片_20211024222521.jpg
在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();
  • }
  • 复制代码
    main.c代码如下:
    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);
  •     }
  • }
  • 复制代码
    效果如下:
    20211024_225803.gif

    测试工程:
    MM32_DS18B20.zip (536.55 KB, 下载次数: 2)
    全部回复 0
    暂无评论,快来抢沙发吧