前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >云之手红外式测温计产品设计分享(基于合泰BH67F2752方案)

云之手红外式测温计产品设计分享(基于合泰BH67F2752方案)

作者头像
杨源鑫
发布2020-05-21 16:13:56
1.3K0
发布2020-05-21 16:13:56
举报
文章被收录于专栏:嵌入式开发圈
前面我们介绍了华大半导体开源的额温枪项目,顺带也分享了入门华大HC32L136平台的SDK,这样再去看项目代码才能学习到更多实际产品的软件设计思想,链接如下:

火爆全网开源额温枪同平台之华大HC32L136 SDK开发入门

分享一个近期开源火爆全网的额温枪方案(硬件+源码)

今天,就来介绍下深圳市云之手科技有限公司的测温产品,出自陈工之手,这也是他个人目前开源的第二个项目,也是个非常成功的项目,产品已经实现大批量产。第一个开源DIY项目链接如下:

深圳云之手科技开源炫酷RGB灯板DIY项目

这是基于合泰BH67F2752方案,该方案最大的优势是成本非常低,我们先来看看产品硬件原理图:

1、红外式测温计产品原理图等

电路原理图

产品PCB 3D图纸

产品PCB实物图

产品实物图(公模)

为什么要采用公模?因为量产的项目产品属于商业机密,包括外观等等都是和客户签订了相应的保密合同,所以我们不能公开已经出货的产品的技术资料,但是我们还是可以以公模的方式公开,在一定程度上和原来的产品外观等等都有一定的区别,不过大致框架是一样的,不影响我们学习。

2、红外式测温计产品演示效果

3、红外式测温计产品软件框架

基于合泰官方提供测温Demo程序进行开发,也有合泰的其它方案,资料在文章末尾,感兴趣的朋友可以回复关键词获取。

(1)主程序框架

代码语言:javascript
复制
void main()
{
    //判斷是否是上電復位或者是正常情況下的非正常復位
    //如果成立則執行上電初始化動作,反之則執行WDT溢出初始化
    if(_to == 0 || _pdf == 0)									// WDT	Reset
    {
        //上電復位或者是正常情況下的非正常復位
        fun_Ram_CLear();									// CLR  RAM

        fun_Sys_Init();
        fun_Reset_Init();
    }
    else
    {
        //WDT 溢出復位
        fun_Reset_Init();
    }

    fun_Uart_Init();
    fun_Test_Function();


    //蜂鸣器上电响一声
    BEEP_ON();
    Delay_Ms(200);
    BEEP_OFF();
    /*	fun_BAT_INIT();*/
    SDK_TM.HaltTime = 110;  //进入休眠模式

    /*	fun_CorrMode_Printf();*/
    while(1)
    {
        //清除看門狗
        GCC_CLRWDT();
        //	工作循环
        /*		SDK_TM.HaltTime = 120;	//Test 不要进入休眠	*/

        if(SDK_TM.HaltTime < HALT_TIME)
        {
            if(_tb0f)	//	8ms中断标志位判断
            {
                _tb0f = 0;	//8ms标志位清零

                fun_SysTimeScan();

                fun_WorkModeScan();		//工作模式处理
                fun_BeepScan();			//蜂鸣器处理
                fun_BacklightScan();		//背光处理

                fun_Key_Scan();			//按键扫描处理

                //清除標誌位 ,在工作流程控制可使用gbv_500ms,由此地方統一清除
                if (gbv_500ms)
                {
                    gbv_500ms = 0;
                    /*fun_LCD_Display_Mode();*/
                }
            }

            //	ADC 輪詢掃描
            fun_ADC_Polling();
        }
        //	休眠模式
        else
        {
            fun_SysSleep();
        }
    }
}

(2)功能测试部分

代码语言:javascript
复制
void	fun_Test_Function()
{
    #if(TEST_MODE == TEST_LCD)
    fun_LCD_Test();
    #endif
    #if(TEST_MODE == TEST_BEEP)
    fun_Beep_Test();
    #endif
    #if(TEST_MODE == TEST_PERI)
    fun_Peripherals_Test();
    #endif
    #if(TEST_MODE == TEST_UART)
    fun_Uart_Test();
    #endif
    #if(TEST_MODE == TEST_NTC)
    fun_ADC_NTC_Test();
    #endif
    #if(TEST_MODE == TEST_OPAZERO)
    fun_ADC_OPA_ZeroTest();
    #endif
    #if(TEST_MODE == TEST_OPAVTP)
    fun_ADC_OPA_VTPTest();
    #endif
}

(3)背光处理

代码语言:javascript
复制
void	fun_BacklightScan()
{
    if(gbv_KeyStatus_L_4)
    {
        gbv_KeyStatus_L_4 = 0;
        fun_Uart_SendByte(0x11);
        Backlight = ~Backlight;
    }
}

(4)测温工作模式处理

代码语言:javascript
复制
void fun_WorkModeScan(void)
{
    //获取系统状态模式
    switch(SDK_SYS.WorkMode)		
    {
        //系统开关
        case	WORKMODE_POWERON:	
            break;
        //系统唤醒模式
        case	WORKMODE_WAKEUP:	
            //按键1唤醒开机
            if(gbv_KeyStatus_1)		
            {
                SDK_KEY.KeyStatus.U8 &= 0x01;
                SDK_KEY.KeyStatus_L.U8 = 0;

                fun_LCD_Init();
                //上电初始化显示
                fun_LCD_Display_Power();	
                //跳转到工作模式
                GOTO_SCAN_MODE();	
            }

            break;
        //扫描模式
        case	WORKMODE_SCAN:		
        {

            fun_LCD_Display_Update();
            //获取NTC数值,返回1就是获取成功,返回0获取失败
            if(fun_get_NTC())		
            {
                SDK_CAL.RES_Buff.U16 = fun_Rntc_Calculate(SDK_CAL.ADC_Res1.S16, SDK_CAL.ADC_Res2.S16);
                gbv_Flag_GetNTC = 1;
            }

            if(gbv_Flag_GetNTC)
            {
                gbv_Flag_GetNTC = 0;

                // 進入量測工作模式
                //-----------------------------------------------------------------------//
                if(gbv_KeyStatus_1)
                {
                    gbv_KeyStatus_1 = 0;

                    if(SDK_SYS.DisMode == Mode_Body)
                    {
                        GOTO_MEAS_MODE();
                    }
                    else if(SDK_SYS.DisMode == Mode_Room)
                    {
                        GOTO_AmbTemp_MODE();
                    }
                    else if(SDK_SYS.DisMode == Mode_SurTmp)
                    {
                        GOTO_ObjTemp_MODE();
                    }

                    gbv_Flag_GetNTC = 	0;
                }

                if(gbv_KeyStatus_L_1)
                {
                    gbv_KeyStatus_L_1 = 0;

                    SET_HALT_Sleep();
                    //进入休眠模式
                    GOTO_WAKEUP_MODE();	
                }


                //长按按键2进入校验模式
                if(gbv_KeyStatus_L_2)			
                {
                    gbv_KeyStatus_L_2 = 0;
                    //跳转到校准模式
                    GOTO_CORR_MODE();		
                    fun_LCD_Display_Cor(0);
                    //校准模式打印
                    fun_CorrMode_Printf();	
                }
                //短按按键3切换摄氏度和华氏度显示
                if(gbv_KeyStatus_3)			
                {
                    gbv_KeyStatus_3 = 0;

                    SDK_SYS.Dis_CF_Flag++;

                    if(SDK_SYS.Dis_CF_Flag == 3)
                        SDK_SYS.Dis_CF_Flag = 1;

                    if(SDK_SYS.Dis_CF_Flag == 1)				//C
                    {
                        if(SDK_SYS.DisMode == Mode_Body)
                        {
                            //设置LCD显示温度,带小数点
                            LCD_DISPLAY_NUM(0, SDK_CAL.BodyTemp.U16);	
                            fun_Uart_SendASCII(SDK_CAL.BodyTemp.U16);
                        }
                        else if(SDK_SYS.DisMode == Mode_Room)
                        {
                            //设置LCD显示温度,带小数点
                            LCD_DISPLAY_NUM(0, SDK_CAL.AmbTemp.U16);		
                            fun_Uart_SendASCII(SDK_CAL.AmbTemp.U16);
                        }
                        else if(SDK_SYS.DisMode == Mode_SurTmp)
                        {
                            //设置LCD显示温度,带小数点
                            LCD_DISPLAY_NUM(0, SDK_CAL.ObjTemp.U16);		
                            fun_Uart_SendASCII(SDK_CAL.ObjTemp.U16);
                        }

                    }
                    else if(SDK_SYS.Dis_CF_Flag == 2)			//F
                    {
                        if(SDK_SYS.DisMode == Mode_Body)
                        {
                            //设置LCD显示温度,带小数点
                            LCD_DISPLAY_NUM(1, (SDK_CAL.BodyTemp.U16 * 1.8) + 32);		
                            fun_Uart_SendASCII((SDK_CAL.BodyTemp.U16 * 1.8) + 32);
                        }
                        else if(SDK_SYS.DisMode == Mode_Room)
                        {
                            //设置LCD显示温度,带小数点
                            LCD_DISPLAY_NUM(1, (SDK_CAL.AmbTemp.U16 * 1.8) + 32);		
                            fun_Uart_SendASCII((SDK_CAL.AmbTemp.U16 * 1.8) + 32);
                        }
                        else if(SDK_SYS.DisMode == Mode_SurTmp)
                        {
                            //设置LCD显示温度,带小数点
                            LCD_DISPLAY_NUM(1, (SDK_CAL.ObjTemp.U16 * 1.8) + 32);		
                            fun_Uart_SendASCII((SDK_CAL.ObjTemp.U16 * 1.8) + 32);
                        }
                    }
                }
            }
            //短按按键2切换模式显示
            if(gbv_KeyStatus_2)			
            {
                gbv_KeyStatus_2 = 0;

                SDK_SYS.DisMode ++;

                if(SDK_SYS.DisMode == 4)
                    SDK_SYS.DisMode = 1;

                fun_LCD_Display____();
            }
            //检测短按按键4
            if(gbv_KeyStatus_4)			
            {
                gbv_KeyStatus_4 = 0;
                SDK_SYS.Dis_Beep_Flag = ~SDK_SYS.Dis_Beep_Flag;			
            }
            break;
        }
        //获取人体温度
        case	WORKMODE_MEAS:			
        {
            if(fun_get_VTP())
            {
                //将NTC的温度和VTP的ADC值带入
                SDK_CAL.AmbTemp.U16		=	fun_Tsen_Calculate(SDK_CAL.RES_Buff.U16);		
                //将第一个校准点带入
                SDK_CAL.ObjTemp.U16 	= 	fun_Tobj_Calculate(SDK_CAL.AmbTemp.U16, SDK_CAL.ADC_Vtp.S16);	
                //获取物表温度
                SDK_CAL.ObjTemp.U16 	= 	fun_ObjTemp_DataHandle(SDK_CAL.ObjTemp.U16);					              //获取人体温度
                SDK_CAL.BodyTemp.U16	=	fun_Temp_SurfaceToBody(SDK_CAL.ObjTemp.U16);					
                //设置蜂鸣器模式
                fun_BeepSet(BEEP_1);						

                if(SDK_SYS.Dis_CF_Flag == 1)				//C
                {
                    //设置LCD显示温度,带小数点
                    LCD_DISPLAY_NUM(0, SDK_CAL.BodyTemp.U16);		
                    fun_Uart_SendASCII(SDK_CAL.BodyTemp.U16);
                }
                else if(SDK_SYS.Dis_CF_Flag == 2)
                {
                    //设置LCD显示温度,带小数点
                    LCD_DISPLAY_NUM(1, (SDK_CAL.BodyTemp.U16 * 1.8) + 32);		
                    fun_Uart_SendASCII((SDK_CAL.BodyTemp.U16 * 1.8) + 32);
                }
                //返回等待按键按下模式
                GOTO_SCAN_MODE();							

            }
            else
            {
                //显示等待获取
                fun_LCD_Display____();			
            }
        }
        break;
        //获取环境温度
        case	WORKMODE_AmbTemp:			
        {
            //将NTC的温度和VTP的ADC值带入
            SDK_CAL.AmbTemp.U16		=	fun_Tsen_Calculate(SDK_CAL.RES_Buff.U16);						
            //设置蜂鸣器模式
            fun_BeepSet(BEEP_1);						

            if(SDK_SYS.Dis_CF_Flag == 1)				//C
            {
                //设置LCD显示温度,带小数点
                LCD_DISPLAY_NUM(0, SDK_CAL.AmbTemp.U16);		
                fun_Uart_SendASCII(SDK_CAL.AmbTemp.U16);
            }
            else if(SDK_SYS.Dis_CF_Flag == 2)
            {
                //设置LCD显示温度,带小数点
                LCD_DISPLAY_NUM(1, (SDK_CAL.AmbTemp.U16 * 1.8) + 32);		
                fun_Uart_SendASCII((SDK_CAL.AmbTemp.U16 * 1.8) + 32);
            }
            //返回等待按键按下模式
            GOTO_SCAN_MODE();							

        }
        //获取表面温度
        case	WORKMODE_ObjTemp:			
        {
            if(fun_get_VTP())
            {
                //将NTC的温度和VTP的ADC值带入
                SDK_CAL.AmbTemp.U16		=	fun_Tsen_Calculate(SDK_CAL.RES_Buff.U16);			
                //将第一个校准点带入
                SDK_CAL.ObjTemp.U16 	= 	fun_Tobj_Calculate(SDK_CAL.AmbTemp.U16, SDK_CAL.ADC_Vtp.S16);	
                //设置蜂鸣器模式
                fun_BeepSet(BEEP_1);						


                if(SDK_SYS.Dis_CF_Flag == 1)				//C
                {
                    //设置LCD显示温度,带小数点
                    LCD_DISPLAY_NUM(0, SDK_CAL.ObjTemp.U16);		
                    fun_Uart_SendASCII(SDK_CAL.ObjTemp.U16);
                }
                else if(SDK_SYS.Dis_CF_Flag == 2)
                {
                    //设置LCD显示温度,带小数点
                    LCD_DISPLAY_NUM(1, (SDK_CAL.ObjTemp.U16 * 1.8) + 32);		
                    fun_Uart_SendASCII((SDK_CAL.ObjTemp.U16 * 1.8) + 32);
                }
                //返回等待按键按下模式
                GOTO_SCAN_MODE();							

            }
            else
            {
                //显示等待获取
                fun_LCD_Display____();			
            }
        }
        //校准模式
        case	WORKMODE_CORR:			
        {
            fun_CORR_MODE();
            break;
        }

        default:
            GOTO_SCAN_MODE();
            break;
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式云IOT技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、红外式测温计产品原理图等
  • 2、红外式测温计产品演示效果
  • 3、红外式测温计产品软件框架
    • (1)主程序框架
      • (2)功能测试部分
        • (3)背光处理
          • (4)测温工作模式处理
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档