4116|2

221

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

《基于GD32的仓库温度报警系统》 [复制链接]

一、方案名称:基于GD32F350的智能仓库温度报警器

二、方案概体介绍:
     该项目主要运用GD32F350作为主控MCU,通过一线式通讯接口,外接一个DS18B20进行温度采集。由于个人只是做项目的demo,没有购买多个DS18B20,一般仓库面积比较大,在实际监控中,建议外挂多个DS18B20模块在总线上,由于是单线式传输,因此对时序要求比较严苛,但它可以挂接许多个DS18B20模块,软硬件实现起来比较方便。本项目实现的功能比较简单,大概的执行流程就是通过DS18B20实时采集室内温度,并通过内部寄存器将模拟信号转换成数字信号,编写一线式通讯协议,使用GPIOB_12将完成数据的收发。当采集的温度值在10~33℃时为正常范围,显示内部LED灯为0.3秒亮灭间隔,外部7盏灯会依次以0.05秒的时间间隔亮灭。如果大于33℃或者小于10℃时,则内部LED灯以0.05秒的时间间隔依次两灭,同时外部LED的第8盏灯也会以0.3秒亮灭频率闪烁,并且外部蜂鸣器器会持续响起,用到的是GPIOC_6管脚。当然这温度的范围根据用户要求可以适时设定。

三、开发环境:
     本项目是在Keil uVision5上编译、链接、下载。在收到开发板后,首先当然是搭建好开发环境,在Keil uVision5上下载好针对GD32F350的动态库,这样方便后续的程序编译下载。由于此次项目没有采用OLED显示模组,而八段数码管的点亮驱动要求GPIO的资源较多,因此没有去点亮数码管显示实时温度值了,用到的是串口实时打印。

四、总体结构框图及主模块图:

五、项目心得体会:
    由于该项目是采用DS18B20的外部温度采集模块,其通讯方式是单线式,因此要求的时序比较精准。下面是在demo包下改成的配置。库函数system_gd32f3x0.c原始系统配置的是__SYSTEM_CLOCK_108M_PLL_HXTAL外部晶振,但是拿到的板子外部晶振没有给我们用户焊接,因此系统会切换为__SYSTEM_CLOCK_8M_IRC8M内部RC 8Mhz的系统时钟频率。GD32F350是支持内部RC 8Mhz晶振倍频到108Mhz的,需要修改如下宏定义。如果这个没有设置好,那拿到DS18B20datasheet后,看时序图就知道这是至关重要的。之前没有发现这点漏洞,老是发现DS18B20初始化失败,采集数据都是为0℃。
#if defined (GD32F350)
//#define __SYSTEM_CLOCK_8M_HXTAL              (__HXTAL)
//#define __SYSTEM_CLOCK_8M_IRC8M              (__IRC8M)
//#define __SYSTEM_CLOCK_72M_PLL_HXTAL         (uint32_t)(72000000)
//#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2    (uint32_t)(72000000)
//#define __SYSTEM_CLOCK_84M_PLL_HXTAL         (uint32_t)(84000000)
//#define __SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2    (uint32_t)(84000000)
//#define __SYSTEM_CLOCK_96M_PLL_HXTAL         (uint32_t)(96000000)
//#define __SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2    (uint32_t)(96000000)
//#define __SYSTEM_CLOCK_96M_PLL_IRC48M_DIV2   (uint32_t)(96000000)
//#define __SYSTEM_CLOCK_108M_PLL_HXTAL        (uint32_t)(108000000)
#define __SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2     (uint32_t)(108000000)
#endif /* GD32F350 */

    项目功能很简单,内容也比较少,但是走了很多弯路,导致浪费了很多时间。由于项目是用之前做51单片机的系统开发板,该板是由本人手动画PCB,然后用FeCl3蚀刻,钻孔,手动焊接,此次派上用场了。但这次项目也是只用到LED发光二极管和蜂鸣器部分电路,由于LED8与蜂鸣器是串联在一起的,调试的时候一上电,如果在初始化配置GPIOC_6口为输出时,外部电路老是有1.5V左右的电平输出,因此蜂鸣器总是响起。后面量测才知道是硬件电路所致,因为串联了LED8,将电压拉低,三极管被驱动。因此这能在初始化GPIOC_6口时将配置改成输入,当要让蜂鸣器启动时再将改口改成输出。
本来计划采用外部按键来中断蜂鸣器报警,然后可以通过外部按键调节设定温度范围告警值,但由于没有显示部分,操作起来也没有那么方便,因此该部分待后续慢慢完善吧。总的来说此项目的功能是达到了,DS18B20采集的温度值也比较精准。此次项目让我收获许多,同时在微信群里认识了众多有识之士,通过网友的发帖,也认识到自己的差距。时不待我,只有不断的进行实际项目的开发,才能让自己独当一面。

六、视频演示:
七、项目前期帖子回顾:
       GD32F350RB终于收到了,开箱测试一下!
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=918279&fromuid=736480
    基于GD32的仓库温度报警系统---串口调试
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=977265&fromuid=736480
    基于GD32的仓库温度报警系统---DS18B20资料细读
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1006098&fromuid=736480
    基于GD32的仓库温度报警系统---GPIO口点灯
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1006113&fromuid=736480
    基于GD32的仓库温度报警系统---GPIO口驱动蜂鸣器
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1006114&fromuid=736480
    基于GD32的仓库温度报警系统---GPIO初始化与延时设定
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1029153&fromuid=736480

八、项目代码:








结构概况框图.png (20.84 KB, 下载次数: 1)

结构概况框图.png

DS18B20硬件连接图示.png (14.57 KB, 下载次数: 0)

DS18B20硬件连接图示.png

DS18B20原理图.png (16.94 KB, 下载次数: 0)

DS18B20原理图.png

智能仓库温度报警器.zip

4.62 MB, 阅读权限: 1, 下载次数: 88

工程代码

此帖出自GD32 MCU论坛

最新回复

nmg
附给评委补充材料:yin_wu_qing基于GD32的仓库温度报警系统---串口调试点击查看yin_wu_qing请教怎样使用GPIO口点亮八段数码管点击查看yin_wu_qing基于GD32的仓库温度报警系统---DS18B20资料细读点击查看yin_wu_qing基于GD32的仓库温度报警系统---GPIO口点灯点击查看yin_wu_qing基于GD32的仓库温度报警系统---GPIO口驱动蜂鸣器点击查看yin_wu_qing基于GD32的仓库温度报警系统---GPIO初始化与延时设定点击查看   详情 回复 发表于 2018-10-25 09:09
点赞 关注
 

回复
举报

221

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
主要代码附上:
static void ds18b20_write8(unsigned char data)   //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
{                                                                 //在15~60us之间对数据线进行采样,如果是高电平就写1,低电平写0。
        int i;
          //unsigned long flags;
         gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_12);
       for (i = 0; i < 8; i++) {
                if ((data & 0x1) == 1) {
                        gpio_bit_reset(GPIOB, GPIO_PIN_12);
                        delayus(3);
                        gpio_bit_set(GPIOB, GPIO_PIN_12);
                        delayus(80);
                } else {
                        gpio_bit_reset(GPIOB, GPIO_PIN_12);
                        delayus(80);
                        gpio_bit_set(GPIOB, GPIO_PIN_12);
                        delayus(3);
                }
                data >>= 1;
       }
}

static unsigned char ds18b20_read8(void)     //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{                                                           //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
        int i;
        unsigned char bit;
        unsigned char data = 0;
        
        for (i = 0; i < 8; i++) {                   //一个字节有8位
                    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_12);
                gpio_bit_reset(GPIOB, GPIO_PIN_12);
                delayus(2);
                    gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_12);
                bit = gpio_input_bit_get(GPIOB, GPIO_PIN_12);
                data |= (bit << i);
                delayus(60);
        }
        return data;
}

static void ds18b20_reset(void)
{
        unsigned char ret;
          gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_12);  //DQ先置高
          delayus(3);                                                 //稍延时
        gpio_bit_reset(GPIOB, GPIO_PIN_12);             //发送复位脉冲
        delayus(500);                                    //延时(>480us)
        gpio_bit_set(GPIOB, GPIO_PIN_12);               //拉高数据线  
        delayus(30);                                                //等待(15~60us)
          gpio_bit_write(GPIOB, GPIO_PIN_12,RESET);                                            
          gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_12);  
          
        ret = (gpio_input_bit_get(GPIOB, GPIO_PIN_12));
        delayus(500);                                                  
        if (ret == 0) {
                EvbUart1Printf("reset ok.\n");
        } else {
                EvbUart1Printf("reset failed.\n");
        }
}

static float ds18b20_read()
{
        int temp = 0;
          int minus;
        char temp1,temp2;
        ds18b20_reset();                          //初始化
        ds18b20_write8(DS18B20_SKIP_ROM);   //跳过读序列号的操作
        ds18b20_write8(DS18B20_COVERTT);    //启动温度转换
          delayus(125);                                  //转换需要一点时间,延时
        ds18b20_reset();                          //初始化
        ds18b20_write8(DS18B20_SKIP_ROM);   //跳过读序列号的操作
        ds18b20_write8(DS18B20_READ_MEM);   //读温度寄存器(头两个值分别为温度的低位和高位)
        
        temp1 = ds18b20_read8();
        temp2 = ds18b20_read8();

        if(temp2&0xfc)
        {
                minus=1;
                temp=((temp2<<8)|temp1);
                temp=((~temp)+1);
        }
        else
        {
                minus=0;
                temp=((temp2<<8)|temp1);
        }
        temp=(float)temp*0.0625;
        if(minus==1)
        {
                temp=-temp;
        }
        return temp;
}


如有不妥之处,请网友提出,谢谢!
此帖出自GD32 MCU论坛
 
 
 

回复

5220

帖子

236

TA的资源

管理员

板凳
 


附给评委补充材料:
yin_wu_qing
基于GD32的仓库温度报警系统---串口调试
yin_wu_qing
请教怎样使用GPIO口点亮八段数码管
yin_wu_qing
基于GD32的仓库温度报警系统---DS18B20资料细读
yin_wu_qing
基于GD32的仓库温度报警系统---GPIO口点灯
yin_wu_qing
基于GD32的仓库温度报警系统---GPIO口驱动蜂鸣器
yin_wu_qing
基于GD32的仓库温度报警系统---GPIO初始化与延时设定


此帖出自GD32 MCU论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表