Smile° · 2023年01月12日 · 山东

【GD32F427开发板试用】UART1读取ds18b20温度传感器

硬件部分

1.GD32F427R开发板
 title=
2.ds18b20温度传感器
 title=
详细原理及时序可参考CSDN论坛大佬博客
3.USB转TTL模块
 title=

软件部分

参考官方systick库实现delay毫秒函数

#include "gd32f4xx.h"
    #include "systick.h"
    
    volatile static uint32_t delay;
    
    /*!
        \brief      configure systick
        \param[in]  none
        \param[out] none
        \retval     none
    */
    void systick_config(void)
    {
        /* setup systick timer for 1000Hz interrupts */
        if(SysTick_Config(SystemCoreClock / 1000000U)) {
            /* capture error */
            while(1) {
            }
        }
        /* configure the systick handler priority */
        NVIC_SetPriority(SysTick_IRQn, 0x00U);
    }
    
    /*!
        \brief      delay a time in milliseconds
        \param[in]  count: count in milliseconds
        \param[out] none
        \retval     none
    */
    void delay_1ms(uint32_t count)
    {
        delay = 1000*count;
    
        while(0U != delay) {
        }
    }
    /*!
        \brief      delay a time in microseconds
        \param[in]  count: count in microseconds
        \param[out] none
        \retval     none
    */
    void delay_1us(uint32_t count)
    {
        delay = count;
    
        while(0U != delay) {
        }
    }

ds18b20.c代码

#include "ds18b20.h"
    
    int DS18B20_Init(void)
    {
      int i=0;
      DS_DIO(1);  //GPIOA->ODR |= 1;  //GPIOA-0输出高电平
      DS18B20_Mode_OutPut();//令DQ口为输出模式
      DS_DIO(0);   //PAout(0)=0;
      delay_1us(720);//延时480-960us
      DS_DIO(0);   //PAout(0)=1;
      delay_1us(30);//等待15-60us 
      DS18B20_Mode_InPut();//改为输入模式
      while(READ_DIO == 1)  //   //while(PAin(0)==1)    //若DS18B20存在则会将总线拉低60-240us
      {   
         delay_1us(1);
         i++;
         if(i>240)  return 0;     //时间大于240us总线仍为高电平则DS18B20不存在
      }
      return 1;
    }
    
    void DS18B20_WriteByte(uint8_t dat)
    {
     int i;
     DS18B20_Mode_OutPut();
     for(i=0;i<8;i++)
     {
      DS_DIO(0); //   PAout(0)=0;        //先拉低引脚
      delay_1us(15);      //等待15us,在第15-60us内DS18B20会获取总线电平
      if(dat&0x01)  DS_DIO(1);  //PAout(0)=dat&0x01;
        else DS_DIO(0); 
      delay_1us(60);      //延时,使时序图完整
      DS_DIO(1);  //    PAout(0)=1;
      dat>>=1;
     }
    }
    
    uint8_t DS18b20_ReadByte(void)
    {
     int j;
     uint8_t dat,byte;
     for(j=8;j>0;j--)
     {
      DS18B20_Mode_OutPut();   
      DS_DIO(0);   //PAout(0)=0;          //先拉低引脚
      delay_1us(1);         //延时至少大于1us
      DS_DIO(1); //PAout(0)=1;          //释放总线
      delay_1us(10);        //DS18B20会在15us发送数据
      DS18B20_Mode_InPut();
      dat=READ_DIO;   //PAin(0);
      byte=(byte>>1)|(dat<<7);
      delay_1us(45);        //使时序完整
      DS18B20_Mode_OutPut();
      DS_DIO(1);   //PAout(0)=1;
     }
     return byte;
    }
    
    /*改变DS18B20的高温报警和低温报警以及分辨率*/
    void DS18B20_Resolving_Temp(void)
    {
     DS18B20_Init();//单片机每次向DS18B20发送功能指令前都需要重新初始化DS18B20和写ROM指令
     delay_1ms(1);
     DS18B20_WriteByte(0xcc);
     DS18B20_WriteByte(0xbe);//高温报警的上限
     DS18B20_WriteByte(0x00);//低温报警的下限
     DS18B20_WriteByte(0x7f);//改变温度分辨率
    }
    
    /*进行温度转化*/
    void Ds18b20ChangeTemp(void)
    {
     DS18B20_Init();
     delay_1ms(1);
     DS18B20_WriteByte(0xcc);//跳过ROM
     DS18B20_WriteByte(0x44);//发送指令RAM温度变换
    }
    
    /*读取温度*/
    void Ds18b20ReadTempCom(void)
    {
     DS18B20_Init();
     delay_1ms(1);
     DS18B20_WriteByte(0xcc);//跳过ROM
     DS18B20_WriteByte(0xbe);//发送指令RAM读暂时寄存器
    }
    
    int Ds18b20ReadTemp(void)
    {
     int temp;
     float fp;
     uint8_t tml,tmh; 
     DS18B20_Resolving_Temp();//改变高温报警和低温报警以及温度的分辨率
     Ds18b20ChangeTemp();//进行温度转换
     Ds18b20ReadTempCom();//读取温度
     tml=DS18b20_ReadByte();//读低8位数据
     tmh=DS18b20_ReadByte();//读高8位数据
     temp=tmh;
     temp<<=8;
     temp|=tml;//拼接为16位数据
     fp = temp;
     if(temp < 0)//DS18B20存储数据为补码形式,当temp<0时需要转为原码
     {
      temp = ~temp;
      temp += 1;
     }
     temp = fp*0.0625*10+0.5;//根据获得的温度所需的小数而改变,如果保留2位小数则乘100,+0.5是为了四舍五入
     return temp;//返回数据
    }

主函数

#include "gd32f4xx.h"
    #include "gd32f427r_start.h"
    #include "systick.h"
    #include <stdio.h>
    #include "ds18b20.h"
    
    /*!
        \brief      main function
        \param[in]  none
        \param[out] none
        \retval     none
    */
    int main(void)
    {
        /* configure systick */
        systick_config();
            /* enable GPIO clock */
        rcu_periph_clock_enable(RCU_GPIOA);
    
        /* enable USART clock */
        rcu_periph_clock_enable(RCU_USART1);
    
        /* configure the USART0 TX pin and USART0 RX pin */
        gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_2);
        gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_3);
    
        /* configure USART0 TX as alternate function push-pull */
        gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2);
        gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
    
        /* configure USART0 RX as alternate function push-pull */
        gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3);
        gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
    
        /* USART configure */
        usart_deinit(USART1);
        usart_baudrate_set(USART1, 115200U);
        usart_receive_config(USART1, USART_RECEIVE_ENABLE);
        usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
        usart_enable(USART1);
    
    
        /* enable the LEDs GPIO clock */
        rcu_periph_clock_enable(RCU_GPIOC);
    
        /* configure LED1 GPIO port */
        gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
        gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
        /* reset LED1 GPIO pin */
        gpio_bit_set(GPIOC, GPIO_PIN_6);
            DS18B20_Init();
        
        while(1) {
            
            
                float  value = (float)Ds18b20ReadTemp()/10;
                 printf("\n\r%.1f\n\r", value);
                
        }
    }
    int fputc(int ch, FILE *f)
    {
        usart_data_transmit(USART1, (uint8_t)ch);
        while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));
        return ch;
    }

结果

 title=
用手握住DS18B20探头
 title=
温度数值上升

推荐阅读
关注数
10697
内容数
187
中国高性能通用微控制器领域的领跑者兆易创新GD系列芯片技术专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息