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

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

硬件如下:
1.png
微信图片_20211024222521.jpg
在MM32函数库GPIO_Toggle例程上增加DS18B20驱动代码

DS18B20.c代码如下:
  1. void DS18B20_SetDigitalOutput(void)
  2. {
  3.     GPIO_InitTypeDef  GPIO_InitStruct;
  4.     GPIO_StructInit(&GPIO_InitStruct);
  5.     GPIO_InitStruct.GPIO_Pin  =  DS18B20_Pin;
  6.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  7.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  8.     GPIO_Init(DS18B20_Port, &GPIO_InitStruct);
  9. }
  10. void DS18B20_SetDigitalInput(void)
  11. {
  12.     GPIO_InitTypeDef  GPIO_InitStruct;
  13.     GPIO_StructInit(&GPIO_InitStruct);
  14.     GPIO_InitStruct.GPIO_Pin  =  DS18B20_Pin;
  15.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  16.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING;
  17.     GPIO_Init(DS18B20_Port, &GPIO_InitStruct);
  18. }
  19. //复位DS18B20
  20. void DS18B20_Rst(void)
  21. {
  22.     DS18B20_SetDigitalOutput(); //输出模式
  23.     DS18B20_SetLow(); //拉低DQ
  24.     DELAY_Us(750); //拉低750us(480~960us)
  25.     DS18B20_SetHigh(); //拉高DQ
  26. }
  27. //等待DS18B20应答,有应答返回0,无应答返回1
  28. uint8_t DS18B20_Check(void)
  29. {
  30.     uint8_t retry = 0;
  31.     //进入接收模式,等待应答信号
  32.     //等待时间
  33.     DS18B20_SetDigitalInput(); //输入模式
  34.     DELAY_Us(15); //等待15~60us
  35.     while(DS18B20_GetValue() && retry < 120) //最多再等待120us
  36.     {
  37.         retry++;
  38.         DELAY_Us(1);
  39.     };
  40.     if(retry >= 120)
  41.         return 1; //120us未响应,则判断未检测到
  42.     else
  43.         retry = 0;
  44.     //DS18B20开始拉低DQ
  45.     while(!DS18B20_GetValue() && retry < 240) //最长拉低240us
  46.     {
  47.         retry++;
  48.         DELAY_Us(1);
  49.     };
  50.     if(retry >= 240)
  51.         return 1;
  52.     return 0;
  53. }
  54. //写字节到DS18B20
  55. void DS18B20_Write_Byte(uint8_t dat)
  56. {
  57.     uint8_t j;
  58.     uint8_t temp;
  59.     DS18B20_SetDigitalOutput(); //输出模式
  60.     for(j = 1; j <= 8; j++)
  61.     {
  62.         temp = dat & 0x01;
  63.         dat = dat >> 1;
  64.         if (temp) //输出高
  65.         {
  66.             DS18B20_SetLow(); //拉低DQ
  67.             DELAY_Us(2); //延时2us
  68.             DS18B20_SetHigh(); //拉高DQ
  69.             DELAY_Us(60); //延时60us
  70.         }
  71.         else //输出低
  72.         {
  73.             DS18B20_SetLow(); //拉低DQ
  74.             DELAY_Us(60); //延时60us
  75.             DS18B20_SetHigh(); //拉高DQ
  76.             DELAY_Us(2); //延时2us
  77.         }
  78.     }
  79.     DS18B20_SetDigitalInput(); //输入模式
  80. }
  81. //从DS18B20读位
  82. uint8_t DS18B20_Read_Bit(void)
  83. {
  84.     uint8_t data;
  85.     DS18B20_SetDigitalOutput(); //输出模式
  86.     DS18B20_SetLow(); //拉低DQ
  87.     DELAY_Us(2); //延时2us
  88.     DS18B20_SetHigh(); //拉高DQ
  89.     DS18B20_SetDigitalInput(); //输入模式
  90.     DELAY_Us(12); //延时12us
  91.     if(DS18B20_GetValue()) //读DQ数据
  92.         data = 1;
  93.     else
  94.         data = 0;
  95.     DELAY_Us(50); //延时50us
  96.     return data;
  97. }
  98. //从DS18B20读字节
  99. uint8_t DS18B20_Read_Byte(void)
  100. {
  101.     uint8_t i, j, dat = 0;
  102.     for(i = 1; i <= 8; i++)
  103.     {
  104.         j = DS18B20_Read_Bit();
  105.         dat = (j << 7) | (dat >> 1);
  106.     }
  107.     return dat;
  108. }
  109. //开始温度转换
  110. void DS18B20_Start(void)
  111. {
  112.     DS18B20_Rst();
  113.     DS18B20_Check();
  114.     DS18B20_Write_Byte(0xcc);
  115.     DS18B20_Write_Byte(0x44);
  116. }
  117. /*//读取温度值
  118. float DS18B20_Get_Temp(void)
  119. {
  120.     uint8_t sign; //温度符号,0为-,1为+
  121.     uint8_t TL, TH;
  122.     uint16_t temp;
  123.     float temp1;
  124.     DS18B20_Start ();
  125.     _delay_ms(800); //等待转换完成
  126.     DS18B20_Rst();
  127.     DS18B20_Check();
  128.     DS18B20_Write_Byte(0xcc);
  129.     DS18B20_Write_Byte(0xbe);
  130.     TL = DS18B20_Read_Byte();
  131.     TH = DS18B20_Read_Byte();
  132.     if(TH > 7)
  133.     {
  134.         TH = ~TH;
  135.         TL = ~TL;
  136.         sign = 0; //温度为负
  137.     }
  138.     else
  139.         sign = 1; //温度为正
  140.     temp = TH; //高八位
  141.     temp <<= 8;
  142.     temp += TL; //低八位
  143.     temp1 = (float)temp * 0.0625; //转换实际温度
  144.     if(sign)
  145.         return temp1; //返回温度值
  146.     else
  147.         return -temp1;
  148. }*/
  149. //读取温度值
  150. int16_t DS18B20_Get_Temp(void)
  151. {
  152.     uint8_t sign; //温度符号,0为-,1为+
  153.     uint8_t TL, TH;
  154.     uint16_t temp;
  155.     float temp1;
  156.     DS18B20_Start();
  157.     DELAY_Ms(800); //等待转换完成
  158.     DS18B20_Rst();
  159.     DS18B20_Check();
  160.     DS18B20_Write_Byte(0xcc);
  161.     DS18B20_Write_Byte(0xbe);
  162.     TL = DS18B20_Read_Byte();
  163.     TH = DS18B20_Read_Byte();
  164.     if(TH > 7)
  165.     {
  166.         TH = ~TH;
  167.         TL = ~TL;
  168.         sign = 0; //温度为负
  169.     }
  170.     else
  171.         sign = 1; //温度为正
  172.     temp = TH; //高八位
  173.     temp <<= 8;
  174.     temp += TL; //低八位
  175.     temp1 = (float)temp * 0.625 + 0.5; //转换实际温度(放大10倍),+0.5四舍五入
  176.     temp = (uint16_t)temp1;
  177.     if(sign)
  178.         return temp; //返回温度值
  179.     else
  180.         return -temp;
  181. }
  182. uint8_t DS18B20_Init(void)
  183. {
  184.     DS18B20_Rst();
  185.     return DS18B20_Check();
  186. }
main.c代码如下:
  1. s32 main(void)
  2. {
  3.     int16_t Temperature = 0;
  4.     GPIO_InitTypeDef  GPIO_InitStruct;
  5.     RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE);
  6.     GPIO_StructInit(&GPIO_InitStruct);
  7.     GPIO_InitStruct.GPIO_Pin  =  DS18B20_Pin;
  8.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  9.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  10.     GPIO_Init(DS18B20_Port, &GPIO_InitStruct);
  11.     LED_Init();
  12.     DELAY_Init();
  13.     CONSOLE_Init(9600);
  14.     if(DS18B20_Init())
  15.     {
  16.         printf("Not detected DS18B20 \r\n ");
  17.     }
  18.     else
  19.     {
  20.         printf("Detected DS18B20 \r\n");
  21.     }
  22.     while(1)
  23.     {
  24.         LED1_TOGGLE();
  25.         LED2_TOGGLE();
  26.         LED3_TOGGLE();
  27.         LED4_TOGGLE();
  28.         DELAY_Ms(1000);
  29.         Temperature = DS18B20_Get_Temp();
  30.         printf("Temperature: %d.%d℃ \r\n", Temperature / 10, Temperature % 10);
  31.     }
  32. }
效果如下:
20211024_225803.gif

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