Altium Designer画的额温枪原理图和PCB图如下:
image.png


image.png
单片机源程序如下:
/******************************************************************************/
  • /** \file main.c
  • **
  • ** A detailed description is available at
  • ** @link Sample Group Some description @endlink
  • **
  • **   - 2017-05-28 LiuHL    First Version
  • **
  • ******************************************************************************/
  • /******************************************************************************
  • * Include files
  • ******************************************************************************/
  • #include "adc.h"
  • #include "gpio.h"
  • #include "bgr.h"
  • #include "lcd.h"
  • #include "lvd.h"
  • #include "app_lcd.h"
  • #include "app_gpio.h"
  • #include "app_adc.h"
  • #include "app.h"
  • /******************************************************************************
  • * Local pre-processor symbols/macros ('#define')                           
  • ******************************************************************************/
  • #define USERKEYTRUE     (0xFFFFFFFFu)
  • #define USERKEYFALSE    (0x00000000u)
  • #define LCDCHAR__       (0xFFFFu)
  • #define CHARGEEMPTY     (0x00000000u)
  • #define CHARGEFULL      (0xFFFFFFFFu)
  • /******************************************************************************
  • * Global variable definitions (declared in header file with 'extern')
  • ******************************************************************************/
  • volatile uint32_t gu32AdcRestult = 0;
  • volatile uint32_t gu32UserKeyFlag[4] = {USERKEYFALSE, USERKEYFALSE, USERKEYFALSE, USERKEYFALSE};
  • volatile stc_lcd_display_cfg_t gstcLcdDisplayCfg = {0};
  • volatile uint32_t gVolFlag = CHARGEFULL;
  • /******************************************************************************
  • * Local type definitions ('typedef')                                         
  • ******************************************************************************/
  • typedef enum enMState
  • {
  •     InitialMode     = 0u,
  •     TempMeasureMode = 1u,
  •     TempShowMode    = 2u,
  •     PowerOffMode    = 3u,
  •     MemoryMode      = 4u,
  •    
  • }enMState_t;
  • /******************************************************************************
  • * Local function prototypes ('static')
  • ******************************************************************************/
  • /******************************************************************************
  • * Local variable definitions ('static')                                      *
  • ******************************************************************************/
  • /*****************************************************************************
  • * Function implementation - global ('extern') and local ('static')
  • ******************************************************************************/
  • /**
  • ******************************************************************************
  • ** \brief  Main function of project
  • **
  • ** \return uint32_t return value, if needed
  • **
  • ** This sample
  • **
  • ******************************************************************************/
  • int32_t main(void)
  • {   
  •     volatile enMState_t enMState = InitialMode;
  •     uint32_t u32AdcResultTmp, u32NtcIndex;
  •    
  •     ///< GPIO 初始化
  •     AppMGpioInit();
  •    
  •     ///< ADC 模块初始化
  •     AppMAdcInit();
  •    
  •     ///< LCD 模块初始化
  •     AppLcdInit();
  •    
  •     ///< 电量监测模块初始化
  •     AppVolMonitorInit();
  •    
  •    
  •     // 初次上电开机LCD全屏显示闪烁两次
  •     {
  •         AppLcdShowAll();
  •         delay1ms(400);
  •         AppLcdClearAll();
  •         delay1ms(400);
  •         AppLcdShowAll();
  •         delay1ms(400);
  •         AppLcdClearAll();
  •         delay1ms(400);
  •         AppLcdShowAll();
  •     }
  •    
  •     while(1)
  •     {   
  •         switch(enMState)
  •         {
  •             case InitialMode:
  •             {
  •                 // LCD 初始状态显示
  •                 gstcLcdDisplayCfg.bM6En     = FALSE;
  •                 gstcLcdDisplayCfg.bM5En     = TRUE;
  •                 gstcLcdDisplayCfg.bM2En     = FALSE;
  •                 gstcLcdDisplayCfg.bM7En     = TRUE;
  •                 gstcLcdDisplayCfg.bM8En     = TRUE;
  •                 gstcLcdDisplayCfg.bM9En     = FALSE;
  •                 gstcLcdDisplayCfg.bM10En    = FALSE;
  •                 gstcLcdDisplayCfg.bM11En    = TRUE;
  •                 gstcLcdDisplayCfg.bM3En     = FALSE;
  •                 gstcLcdDisplayCfg.enTmpMode = Char__;
  •                 gstcLcdDisplayCfg.u16Num    = LCDCHAR__;
  •             }
  •             
  •             {
  •                 if(USERKEYTRUE == gu32UserKeyFlag[2])
  •                 {
  •                     //……
  •                     //(进入温度测量)
  •                     gu32UserKeyFlag[0] = USERKEYFALSE;
  •                     gu32UserKeyFlag[1] = USERKEYFALSE;
  •                     gu32UserKeyFlag[2] = USERKEYFALSE;
  •                     gu32UserKeyFlag[3] = USERKEYFALSE;
  •                     
  •                 }
  •                 else if (USERKEYTRUE == gu32UserKeyFlag[2])
  •                 {
  •                     //……
  •                     gu32UserKeyFlag[0] = USERKEYFALSE;
  •                     gu32UserKeyFlag[1] = USERKEYFALSE;
  •                     gu32UserKeyFlag[2] = USERKEYFALSE;
  •                     gu32UserKeyFlag[3] = USERKEYFALSE;
  •                     
  •                     enMState = TempMeasureMode;
  •                 }
  •             }   
  •                
  •                 // ……
  •             break;
  •             
  •             case TempMeasureMode:
  •                 // ……
  •             break;
  •                
  •             case TempShowMode:
  •                 // ……
  •             break;
  •             
  •             case PowerOffMode:
  •                 // ……
  •             break;
  •             
  •             case MemoryMode:
  •                 // ……
  •             break;
  •             
  •             default:
  •                 // ……
  •             break;
  •                
  •         }
  •         
  •         ///< 温度采集及数据处理
  •         if(USERKEYTRUE == gu32UserKeyFlag[3])
  •         {
  •             gu32UserKeyFlag[3] = USERKEYFALSE;
  •             
  •             AppAdcNtcAvgCodeGet(&u32AdcResultTmp);
  •             u32NtcIndex = App_TempNtcFind(u32AdcResultTmp);
  •             AppLcdStkLcdShow((u32NtcIndex + 10)*10);
  •             delay1ms(1000);
  •             
  •             
  •             AppAdcVirAvgCodeGet(&u32AdcResultTmp);
  •             AppLcdStkLcdShow(App_TempVirFind(u32NtcIndex, u32AdcResultTmp));
  •             delay1ms(3000);
  •             
  •         }
  •         
  •         ///< LCD显示更新
  •         {
  •             //AppLcdDisplayUpdate((stc_lcd_display_cfg_t*)(&gstcLcdDisplayCfg));
  •         }
  •     }
  • }   
  • ///< LVD 中断服务函数
  • void Lvd_IRQHandler(void)
  • {
  •     Lvd_ClearIrq();
  •     // 电量显示更新标识
  •     gVolFlag = CHARGEEMPTY;
  •    
  • }
  • ///< GPIO 中断服务程序 ———— 测温及选择功能键
  • void PortC_IRQHandler(void)
  • {
  •     delay1ms(20);
  •     if (TRUE == Gpio_GetIrqStatus(M_KEY_USER0_PORT, M_KEY_USER0_PIN))
  •     {
  •         Gpio_ClearIrq(M_KEY_USER0_PORT, M_KEY_USER0_PIN);
  •         if(FALSE == Gpio_GetInputIO(M_KEY_USER0_PORT, M_KEY_USER0_PIN))
  •         {
  •             //标定按键按下
  •             //……
  •         }
  •         return;
  •     }
  •    
  •     if (TRUE == Gpio_GetIrqStatus(M_KEY_USER1_PORT, M_KEY_USER1_PIN))
  •     {
  •         Gpio_ClearIrq(M_KEY_USER1_PORT, M_KEY_USER1_PIN);
  •         if(FALSE == Gpio_GetInputIO(M_KEY_USER1_PORT, M_KEY_USER1_PIN))
  •         {
  •             //标定按键按下
  •             //……
  •         }
  •         return;
  •     }
  •    
  •     if (TRUE == Gpio_GetIrqStatus(M_KEY_USER2_PORT, M_KEY_USER2_PIN))
  •     {
  •         Gpio_ClearIrq(M_KEY_USER2_PORT, M_KEY_USER2_PIN);
  •         if(FALSE == Gpio_GetInputIO(M_KEY_USER2_PORT, M_KEY_USER2_PIN))
  •         {
  •             //标定按键按下
  •             //……
  •         }
  •         return;
  •     }
  • }
  • ///< GPIO 中断服务程序 ———— 模式功能键
  • void PortD_IRQHandler(void)
  • {
  •     delay1ms(100);
  •     if (TRUE == Gpio_GetIrqStatus(M_KEY_USER3_PORT, M_KEY_USER3_PIN))
  •     {
  •         Gpio_ClearIrq(M_KEY_USER3_PORT, M_KEY_USER3_PIN);
  •         if(FALSE == Gpio_GetInputIO(M_KEY_USER3_PORT, M_KEY_USER3_PIN))
  •         {
  •             //标定按键按下
  •             gu32UserKeyFlag[3] = USERKEYTRUE;
  •             //……
  •         }
  •         return;
  •     }
  • }
  • /******************************************************************************
  • * EOF (not truncated)
  • ******************************************************************************/
  • 复制代码