天天看點

cubemx stm32 lu90614子產品 人體溫度檢測子產品 可以替代溫槍 驅動代碼lu90614cubemx代碼編寫使用方法

lu90614

  • 使用序列槽通信在,指值得注意的是,他的TX接單片機的TX,RX接單片機的RX,和其他的序列槽裝置不一樣。
    cubemx stm32 lu90614子產品 人體溫度檢測子產品 可以替代溫槍 驅動代碼lu90614cubemx代碼編寫使用方法

模式切換包

lu90614有兩種模式,

一個是物溫模式,一個是體溫模式(檢測人體溫度用體溫模式)

不同模式的切換需要發送不同的包

體溫模式發送指令:0XFA 0XC5 0XBF;

物溫模式發送指令:0XFA 0XC6 0XC0;

開始測溫包

切換模式後,需要測溫就得發個開始測溫包

開始測溫并上傳溫度指令 0XFA 0XCA 0XC4;

測溫時會回發包,回發包有8個資料,格式是:

標頭+指令+DataH+DataL+保留位1+保留位2+保留位3+保留位4+校驗位

  • 指令:
               
  • 0XAA,此時為物溫模式,DataH 為物溫整數位,DataL 為小數位,機關攝氏度;
               
  • 0XAC,此時為體溫模式,DataH 為體溫整數位,DataL 為小數位,機關攝氏度。
               

cubemx

開一個序列槽,配置9600波特率,開接收中斷。

代碼編寫

lu90614.c

#include "lu90614.h"

/* 
 *
 * 溫度值回傳指令:
 *		一包資料:標頭+指令+DataH+DataL+保留位 1+保留位 2+保留位 3+保留位 4+校驗位
 *
 *		標頭:	0XFE,為固定標頭;
 *
 *		指令:	0XAA,此時為物溫模式,DataH 為物溫整數位,DataL 為小數位,機關攝氏度;
 *				0XAC,此時為體溫模式,DataH 為體溫整數位,DataL 為小數位,機關攝氏度。
 *
 *		校驗位= 標頭 + 指令 + DataH + DataL + 保留位1 + 保留位2 + 保留位3 + 保留位4,
 *		溢出時隻保留低 8 位。
 *
*/


uint8_t a_rx_buf = 0;
uint8_t rx_buf[32] = {0};

uint16_t rx_cnt = 0;
uint16_t usart_rx_sta = 0;
uint16_t usart_sta = 0;

Temp_Body_SUBS lu90614Temp;


__attribute__((weak)) void lu90614_operation(void)
{
	
}


void iu90614_send_cmd(IL90614_CMD cmd)
{
	uint8_t pCmdPack[3] = {0};
	
	// 錯誤退出
	if((cmd<BODY_TEMPER_PACK) || (cmd>=IL90614_CMD_MAX))
	{
		return;
	}
	
	// 發包判斷
	switch(cmd)
	{
		case BODY_TEMPER_PACK:
			pCmdPack[0] = 0xfa;
			pCmdPack[1] = 0xc5;
			pCmdPack[2] = 0xbf;
		break;
		case SUBS_TEMPER_PACK:
			pCmdPack[0] = 0xfa;
			pCmdPack[1] = 0xc6;
			pCmdPack[2] = 0xc0;
		break;
		case TEMP_MEASURE_PACK:
			pCmdPack[0] = 0xfa;
			pCmdPack[1] = 0xca;
			pCmdPack[2] = 0xc4;
		break;
		default:
		break;
	}	
    HAL_UART_Transmit(&luuart, (uint8_t *)pCmdPack, LU90614_CMD_LEN, 0xfff);
}



void iu90614_init(void)
{
	// 序列槽接收中斷初始化
	HAL_UART_Receive_IT(&luuart, &a_rx_buf, 1);
	
	// 發送檢測人體溫度包
	iu90614_send_cmd(BODY_TEMPER_PACK);
	// 開始測溫
	iu90614_send_cmd(TEMP_MEASURE_PACK);
}


void lu90614_scan(void)
{
	static uint16_t iCnt = 0; // 用于判斷是否長久未接收到資料
	
	if(usart_rx_sta & 0X8000)//接收到一次資料
	{
		iCnt = 0;
		
		// 擷取溫度
		lu90614Temp.temperInteger = rx_buf[2];		
		lu90614Temp.temperDecimal = rx_buf[3]/10;
		lu90614Temp.temperInteger = lu90614Temp.temperInteger & 0X00FF;
		
		// 在一定範圍的資料才是有效的
		if((lu90614Temp.temperInteger>0) && (lu90614Temp.temperInteger<70))
		{
			// 列印到序列槽上
			printf("temp : %d.%d\r\n", 
			lu90614Temp.temperInteger, lu90614Temp.temperDecimal);

			// 在外部重寫該函數,來定義擷取溫度後的行動
			lu90614_operation();

		}
		
		// 等待置位後在發資料
		iu90614_send_cmd(TEMP_MEASURE_PACK);
		
		usart_rx_sta = 0;//啟動下次接收
	}
	else
	{
		iCnt++;
		if(iCnt >= 5000)
		{
			// 大于等于5000時,重新發送開始測溫。
			iu90614_send_cmd(TEMP_MEASURE_PACK);
			iCnt = 0;
		}
	}
}

// 中斷回調函數
void lu90614_rx_it_func(void)
{
	if((usart_rx_sta & 0x8000) == 0)//接收未完成
	{
		if(a_rx_buf == 0XFE)//接收到指令頭
		{
			usart_sta=1;
			rx_cnt=0;
		}
		if(usart_sta)
		{
			rx_buf[rx_cnt] = a_rx_buf;
			rx_cnt++;
			if(rx_cnt >= 8)//接收8位資料接收完畢
			{
				usart_sta=0;
				usart_rx_sta |= 0x8000;//接收已完成
			}
		}
	}
	HAL_UART_Receive_IT(&luuart, &a_rx_buf, 1);
}



           

lu90614.h

#ifndef _LU90614_H_
#define _LU90614_H_


#ifdef __cplusplus
extern "C" {
#endif

/*********************
 *      INCLUDES
 *********************/

#include <stdint.h>
#include "usart.h"


/*********************
 *      DEFINES
 *********************/

/* 序列槽句柄 */
#define luuart huart2

/* 發送指令的長度 */
#define LU90614_CMD_LEN 3



/**********************
 *      TYPEDEFS
 **********************/

typedef enum
{
	BODY_TEMPER_PACK = 1 ,	// 體溫模式發送指令枚舉
	SUBS_TEMPER_PACK	 ,	// 物溫模式發送指令枚舉
	TEMP_MEASURE_PACK	 ,	// 開始測溫并上傳溫度指令枚舉
	IL90614_CMD_MAX
}IL90614_CMD;

// 測得的溫度
typedef struct
{
	uint8_t temperInteger;	// 整數
	uint8_t temperDecimal;	// 小數
}Temp_Body_SUBS;


/**********************
 * GLOBAL PROTOTYPES
 **********************/

// 外部使用的讀取到的溫度
extern Temp_Body_SUBS lu90614Temp;

// 發送包
void iu90614_send_cmd(IL90614_CMD cmd);


void iu90614_init(void);
void lu90614_scan(void);
void lu90614_rx_it_func(void);

// 重寫該虛函數,來定義擷取溫度後的行動
void lu90614_operation(void);

/*	// 使用方法

初始化:
	iu90614_init();

主循環:
	lu90614_scan();

序列槽接收中斷:
	lu90614_rx_it_func();

 重寫虛函數:
void lu90614_operation(void)
{
	// 添加任意代碼
}

*/



#ifdef __cplusplus
} /*extern "C"*/
#endif

#endif /*_LU90614_H_*/


           

使用方法

初始化:

iu90614_init();

主循環:

lu90614_scan();

序列槽接收中斷:

lu90614_rx_it_func();

重寫虛函數:

void lu90614_operation(void)

{

// 添加任意代碼

}

繼續閱讀