GD32F330+DS18B20

功能

        硬件连接:GD32F330   PA5 连接DS18B20的OUT

        功能:死循环while(1),每秒读一次数据,并通过串口打印出来

 

DS18B20初始化

   首先,由于GD32库并没有位操作,改变IO口的输入输出方向,为了简化操作,写了以下函数

/*!
    \brief      set GPIO_pinx mode in
    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,F)
                only one parameter can be selected which is shown as below:
      \arg        GPIOx(x = A,B,C,D,F) 

    \param[in]  pin: GPIO pin
                pin=1,2,3,4...
    \param[out] none
    \retval     none
*/
void gpio_mode_set_in(uint32_t gpio_periph,u8 pin)
{
    uint32_t ctl, pupd;

    ctl = GPIO_CTL(gpio_periph);
    pupd = GPIO_PUD(gpio_periph);
	/* clear the specified pin pupd bits */
	ctl &= ~GPIO_MODE_MASK(pin);
	/* set the specified pin mode in bits */
	ctl |= GPIO_MODE_SET(pin, GPIO_MODE_INPUT);
	
	/* clear the specified pin pupd bits */
    pupd &= ~GPIO_PUPD_MASK(pin);
    /* set the specified pin pupd bits */
	pupd |= GPIO_PUPD_SET(pin, GPIO_PUPD_PULLUP);	
    

    GPIO_CTL(gpio_periph) = ctl;
    GPIO_PUD(gpio_periph) = pupd;
}




/*!
    \brief      set GPIO_pinx mode out
    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,F)
                only one parameter can be selected which is shown as below:
      \arg        GPIOx(x = A,B,C,D,F) 

    \param[in]  pin: GPIO pin
                pin=1,2,3,4...
      \arg        
    \param[out] none
    \retval     none
*/
void gpio_mode_set_out(uint32_t gpio_periph,u8 pin)
{
    uint32_t ctl, pupd;

    ctl = GPIO_CTL(gpio_periph);
    pupd = GPIO_PUD(gpio_periph);
	
	ctl &= ~GPIO_MODE_MASK(pin);
	ctl |= GPIO_MODE_SET(pin, GPIO_MODE_OUTPUT);
	
	/* clear the specified pin pupd bits */
    pupd &= ~GPIO_PUPD_MASK(pin);
    /* set the specified pin pupd bits */
	pupd |= GPIO_PUPD_SET(pin, GPIO_PUPD_PULLUP);	
    
//	GPIO_OMODE(gpio_periph) &= (uint32_t)(~(1<<pin)); //上电之后,初始化过输出模式,可省略
    GPIO_CTL(gpio_periph) = ctl;
    GPIO_PUD(gpio_periph) = pupd;
}

然后添加delay_1ms(),delay_1us()

#include "gd32f3x0.h"
#include "systick.h"
#include "delay.h"

volatile static float count_1us = 0;
volatile static float count_1ms = 0;





/*!
    \brief      configure systick
    \param[in]  none
    \param[out] none
    \retval     none
*/
void systick_config(void)
{
    /* systick clock source is from HCLK/8 */
    systick_clksource_set(SYSTICK_CLKSOURCE_HCLK_DIV8);
    count_1us = (float)SystemCoreClock/8000000;
    count_1ms = (float)count_1us * 1000;
}



/*!
    \brief      delay a time in microseconds in polling mode
    \param[in]  count: count in microseconds
    \param[out] none
    \retval     none
*/
void delay_1us(uint32_t count)
{
    uint32_t ctl;
    
    /* reload the count value */
    SysTick->LOAD = (uint32_t)(count * count_1us);
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
    /* enable the systick timer */
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
    /* wait for the COUNTFLAG flag set */
    do{
        ctl = SysTick->CTRL;
    }while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));
    /* disable the systick timer */
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
}

/*!
    \brief      delay a time in milliseconds in polling mode
    \param[in]  count: count in milliseconds
    \param[out] none
    \retval     none
*/
void delay_1ms(uint32_t count)
{
    uint32_t ctl;
    
    /* reload the count value */
    SysTick->LOAD = (uint32_t)(count * count_1ms);
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
    /* enable the systick timer */
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
    /* wait for the COUNTFLAG flag set */
    do{
        ctl = SysTick->CTRL;
    }while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));
    /* disable the systick timer */
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
}

 

 初始化

u8 ds18b20_init(void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
	gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_5);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 );
    gpio_bit_set(GPIOA, GPIO_PIN_5);	
	ds18b20_rst();
	return ds18b20_check();	
}

复位DS18B20

//复位DS18B20
void ds18b20_rst(void)	   
{    
	gpio_mode_set_out(GPIOA,5);
	gpio_bit_reset(GPIOA,GPIO_PIN_5);
	delay_1us(750);
	gpio_bit_set(GPIOA,GPIO_PIN_5);
	delay_1us(15);
}

自检DS18B20

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 ds18b20_check(void)
{
	u8 retry = 0;
	gpio_mode_set_in(GPIOA,5);
	
	
	while(gpio_input_bit_get(GPIOA,GPIO_PIN_5)&&retry<200)
	{
		retry++;
		delay_1us(1);
	};
	
	
	if(retry>=200)return 1;
	else retry=0;
	
	while(!gpio_input_bit_get(GPIOA,GPIO_PIN_5)&&retry<240)
	{
		retry++;
		delay_1us(1);
	};
	
	if(retry>=240)return 1;
	
	return 0;

}

 读一个位

//从DS18B20读取一个位
//返回值:1/0
u8 ds18b20_read_bit(void) 	 
{
    u8 data;
	
	gpio_mode_set_out(GPIOA,5);
	gpio_bit_reset(GPIOA,GPIO_PIN_5);
	delay_1us(2);
	gpio_bit_set(GPIOA,GPIO_PIN_5);
	
	
	
	gpio_mode_set_in(GPIOA,5);
	delay_1us(12);
	
	if(gpio_input_bit_get(GPIOA,GPIO_PIN_5))data=1;
	else data=0;
	
	delay_1us(50);
	return data;
}

 读一个字节

//从DS18B20读取一个字节
//返回值:读到的数据
u8 ds18b20_read_byte(void)     
{        
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=ds18b20_read_bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}

 写一个字节

//写一个字节到DS18B20
//dat:要写入的字节
void ds18b20_write_byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
	gpio_mode_set_out(GPIOA,5);	//SET PG11 OUTPUT;
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            gpio_bit_reset(GPIOA,GPIO_PIN_5);	// Write 1
            delay_1us(2);                            
           gpio_bit_set(GPIOA,GPIO_PIN_5);
            delay_1us(60);             
        }
        else 
        {
            gpio_bit_reset(GPIOA,GPIO_PIN_5);	// Write 0
            delay_1us(60);             
           gpio_bit_set(GPIOA,GPIO_PIN_5);
            delay_1us(2);                          
        }
    }
}

 读取温度

//从ds18b20得到温度值
//精度:0.01C*100
//返回值:温度值 (-5500~12500) 
short ds18b20_get_temp(void)
{
    u8 temp;
    u8 TL,TH;
	short tem;
    ds18b20_start ();  			// ds1820 start convert
    ds18b20_rst();
    ds18b20_check();	 
    ds18b20_write_byte(0xcc);	// skip rom
    ds18b20_write_byte(0xbe);	// convert	    
    TL=ds18b20_read_byte(); 	// LSB   
    TH=ds18b20_read_byte(); 	// MSB  
	    	  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;					//温度为负  
    }else temp=1;				//温度为正	  	  
    tem=TH; 					//获得高八位
    tem<<=8;    
    tem+=TL;					//获得底八位
    tem=(float)(tem*6.25);		//转换     
	if(temp)return tem; 		//返回温度值
	else return -tem;    
}

main函数

int main(void)
{  
    systick_config();
    uart_init(115200);
	while(ds18b20_init())
	{
		printf("ds18b20 error\r\n");
		delay_1ms(500);		
	}
	printf("初始化成功。\r\n");
	
    while(1)
	{
		printf("temp=%d\r\n",ds18b20_get_temp());	
		delay_1ms(1000);
    }
}

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值