云之手紅外式測(cè)溫計(jì)產(chǎn)品設(shè)計(jì)分享(基于合泰BH67F2752方案)
前面我們介紹了華大半導(dǎo)體開源的額溫槍項(xiàng)目,順帶也分享了入門華大HC32L136平臺(tái)的SDK,這樣再去看項(xiàng)目代碼才能學(xué)習(xí)到更多實(shí)際產(chǎn)品的軟件設(shè)計(jì)思想,鏈接如下:
火爆全網(wǎng)開源額溫槍同平臺(tái)之華大HC32L136 SDK開發(fā)入門
分享一個(gè)近期開源火爆全網(wǎng)的額溫槍方案(硬件+源碼)
今天,就來(lái)介紹下深圳市云之手科技有限公司的測(cè)溫產(chǎn)品,出自陳工之手,這也是他個(gè)人目前開源的第二個(gè)項(xiàng)目,也是個(gè)非常成功的項(xiàng)目,產(chǎn)品已經(jīng)實(shí)現(xiàn)大批量產(chǎn)。第一個(gè)開源DIY項(xiàng)目鏈接如下:
深圳云之手科技開源炫酷RGB燈板DIY項(xiàng)目
這是基于合泰BH67F2752方案,該方案最大的優(yōu)勢(shì)是成本非常低,我們先來(lái)看看產(chǎn)品硬件原理圖:
1、紅外式測(cè)溫計(jì)產(chǎn)品原理圖等
電路原理圖
產(chǎn)品PCB實(shí)物圖
產(chǎn)品實(shí)物圖(公模)
為什么要采用公模?因?yàn)榱慨a(chǎn)的項(xiàng)目產(chǎn)品屬于商業(yè)機(jī)密,包括外觀等等都是和客戶簽訂了相應(yīng)的保密合同,所以我們不能公開已經(jīng)出貨的產(chǎn)品的技術(shù)資料,但是我們還是可以以公模的方式公開,在一定程度上和原來(lái)的產(chǎn)品外觀等等都有一定的區(qū)別,不過(guò)大致框架是一樣的,不影響我們學(xué)習(xí)。
2、紅外式測(cè)溫計(jì)產(chǎn)品演示效果
3、紅外式測(cè)溫計(jì)產(chǎn)品軟件框架
基于合泰官方提供測(cè)溫Demo程序進(jìn)行開發(fā),也有合泰的其它方案,資料在文章末尾,感興趣的朋友可以回復(fù)關(guān)鍵詞獲取。
(1)主程序框架
void main()
{
//判斷是否是上電復(fù)位或者是正常情況下的非正常復(fù)位
//如果成立則執(zhí)行上電初始化動(dòng)作,反之則執(zhí)行WDT溢出初始化
if(_to == 0 || _pdf == 0) // WDT Reset
{
//上電復(fù)位或者是正常情況下的非正常復(fù)位
fun_Ram_CLear(); // CLR RAM
fun_Sys_Init();
fun_Reset_Init();
}
else
{
//WDT 溢出復(fù)位
fun_Reset_Init();
}
fun_Uart_Init();
fun_Test_Function();
//蜂鳴器上電響一聲
BEEP_ON();
Delay_Ms(200);
BEEP_OFF();
/* fun_BAT_INIT();*/
SDK_TM.HaltTime = 110; //進(jìn)入休眠模式
/* fun_CorrMode_Printf();*/
while(1)
{
//清除看門狗
GCC_CLRWDT();
// 工作循環(huán)
/* SDK_TM.HaltTime = 120; //Test 不要進(jìn)入休眠 */
if(SDK_TM.HaltTime < HALT_TIME)
{
if(_tb0f) // 8ms中斷標(biāo)志位判斷
{
_tb0f = 0; //8ms標(biāo)志位清零
fun_SysTimeScan();
fun_WorkModeScan(); //工作模式處理
fun_BeepScan(); //蜂鳴器處理
fun_BacklightScan(); //背光處理
fun_Key_Scan(); //按鍵掃描處理
//清除標(biāo)誌位 ,在工作流程控制可使用gbv_500ms,由此地方統(tǒng)一清除
if (gbv_500ms)
{
gbv_500ms = 0;
/*fun_LCD_Display_Mode();*/
}
}
// ADC 輪詢掃描
fun_ADC_Polling();
}
// 休眠模式
else
{
fun_SysSleep();
}
}
}
(2)功能測(cè)試部分
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)背光處理
void fun_BacklightScan()
{
if(gbv_KeyStatus_L_4)
{
gbv_KeyStatus_L_4 = 0;
fun_Uart_SendByte(0x11);
Backlight = ~Backlight;
}
}
(4)測(cè)溫工作模式處理
void fun_WorkModeScan(void)
{
//獲取系統(tǒng)狀態(tài)模式
switch(SDK_SYS.WorkMode)
{
//系統(tǒng)開關(guān)
case WORKMODE_POWERON:
break;
//系統(tǒng)喚醒模式
case WORKMODE_WAKEUP:
//按鍵1喚醒開機(jī)
if(gbv_KeyStatus_1)
{
SDK_KEY.KeyStatus.U8 &= 0x01;
SDK_KEY.KeyStatus_L.U8 = 0;
fun_LCD_Init();
//上電初始化顯示
fun_LCD_Display_Power();
//跳轉(zhuǎn)到工作模式
GOTO_SCAN_MODE();
}
break;
//掃描模式
case WORKMODE_SCAN:
{
fun_LCD_Display_Update();
//獲取NTC數(shù)值,返回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;
// 進(jìn)入量測(cè)工作模式
//-----------------------------------------------------------------------//
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();
//進(jìn)入休眠模式
GOTO_WAKEUP_MODE();
}
//長(zhǎng)按按鍵2進(jìn)入校驗(yàn)?zāi)J?br> if(gbv_KeyStatus_L_2)
{
gbv_KeyStatus_L_2 = 0;
//跳轉(zhuǎn)到校準(zhǔn)模式
GOTO_CORR_MODE();
fun_LCD_Display_Cor(0);
//校準(zhǔn)模式打印
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)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
LCD_DISPLAY_NUM(0, SDK_CAL.BodyTemp.U16);
fun_Uart_SendASCII(SDK_CAL.BodyTemp.U16);
}
else if(SDK_SYS.DisMode == Mode_Room)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
LCD_DISPLAY_NUM(0, SDK_CAL.AmbTemp.U16);
fun_Uart_SendASCII(SDK_CAL.AmbTemp.U16);
}
else if(SDK_SYS.DisMode == Mode_SurTmp)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
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)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
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)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
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)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
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____();
}
//檢測(cè)短按按鍵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);
//將第一個(gè)校準(zhǔn)點(diǎn)帶入
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);
//設(shè)置蜂鳴器模式
fun_BeepSet(BEEP_1);
if(SDK_SYS.Dis_CF_Flag == 1) //C
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
LCD_DISPLAY_NUM(0, SDK_CAL.BodyTemp.U16);
fun_Uart_SendASCII(SDK_CAL.BodyTemp.U16);
}
else if(SDK_SYS.Dis_CF_Flag == 2)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
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;
//獲取環(huán)境溫度
case WORKMODE_AmbTemp:
{
//將NTC的溫度和VTP的ADC值帶入
SDK_CAL.AmbTemp.U16 = fun_Tsen_Calculate(SDK_CAL.RES_Buff.U16);
//設(shè)置蜂鳴器模式
fun_BeepSet(BEEP_1);
if(SDK_SYS.Dis_CF_Flag == 1) //C
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
LCD_DISPLAY_NUM(0, SDK_CAL.AmbTemp.U16);
fun_Uart_SendASCII(SDK_CAL.AmbTemp.U16);
}
else if(SDK_SYS.Dis_CF_Flag == 2)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
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);
//將第一個(gè)校準(zhǔn)點(diǎn)帶入
SDK_CAL.ObjTemp.U16 = fun_Tobj_Calculate(SDK_CAL.AmbTemp.U16, SDK_CAL.ADC_Vtp.S16);
//設(shè)置蜂鳴器模式
fun_BeepSet(BEEP_1);
if(SDK_SYS.Dis_CF_Flag == 1) //C
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
LCD_DISPLAY_NUM(0, SDK_CAL.ObjTemp.U16);
fun_Uart_SendASCII(SDK_CAL.ObjTemp.U16);
}
else if(SDK_SYS.Dis_CF_Flag == 2)
{
//設(shè)置LCD顯示溫度,帶小數(shù)點(diǎn)
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____();
}
}
//校準(zhǔn)模式
case WORKMODE_CORR:
{
fun_CORR_MODE();
break;
}
default:
GOTO_SCAN_MODE();
break;
}
}
開源項(xiàng)目資料下載
公眾號(hào)后臺(tái)回復(fù):合泰測(cè)溫 即可獲取下載鏈接,如果有需要該方案或者需要根據(jù)現(xiàn)在的功能進(jìn)行產(chǎn)品定制,可以直接聯(lián)系云之手陳工。
公眾號(hào)粉絲福利時(shí)刻
這里我給大家申請(qǐng)到了福利,本公眾號(hào)讀者購(gòu)買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購(gòu)買小熊派的朋友,淘寶搜索即可,跟客服說(shuō)你是公眾號(hào):嵌入式云IOT技術(shù)圈
的粉絲,立享9折優(yōu)惠!
往期精彩
分享一個(gè)近期開源火爆全網(wǎng)的額溫槍方案(硬件+源碼)
火爆全網(wǎng)開源額溫槍同平臺(tái)之華大HC32L136 SDK開發(fā)入門
深圳云之手科技開源炫酷RGB燈板DIY項(xiàng)目
TKM32F499高性能MCU評(píng)估板試用之萬(wàn)事開頭難,先點(diǎn)個(gè)燈來(lái)壓壓驚!
網(wǎng)紅物聯(lián)網(wǎng)開發(fā)板小熊派使用評(píng)測(cè)
若覺得本次分享的文章對(duì)您有幫助,隨手點(diǎn)[在看]
并轉(zhuǎn)發(fā)分享,也是對(duì)我的支持。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!