【GD32F427开发板试用】UART1读取ds18b20温度传感器
本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:Smile°
硬件部分
1.GD32F427R开发板
2.ds18b20温度传感器
详细原理及时序可参考CSDN论坛大佬博客
3.USB转TTL模块
软件部分
参考官方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-60usDS18B20_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>=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 #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; }
结果
用手握住DS18B20探头
温度数值上升