要求:
以STM32F10x系列主控,利用ESP8266模块、GXH3L以及数码管,实现一个实时性较低的家用温度监测装置。用户可以通过手机订阅MQTT上的温度主题查看此时间段内室内的大致温度,也可以通过数码管清楚的看到室内温度。
实现代码:
main.c:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "tempget.h"
#include "NUMLED.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define AT "AT\r\n"
#define AT_WIFI_MODE "AT+CWMODE=3\r\n"
#define AT_SET_PSW "AT+CWJAP=\"DayDream\",\"cyberchino\"\r\n"
#define AT_SET_MQTT_CFG "AT+MQTTUSERCFG=0,1,\"NULL\",\"xxx\",\"xxx\",0,0,\"\"\r\n"
#define AT_SET_MQTT_CLENTID "AT+MQTTCLIENTID=0,\"xxx1|securemode=2\\,signmethod=hmacsha256\\,timestamp=1746264316150|\"\r\n"
#define AT_SET_MQTT_CONN "AT+MQTTCONN=0,\"iot-06z00dcx1hvlwd3.mqtt.iothub.aliyuncs.com\",1883,1\r\n"
#define AT_MQTT_SUB "AT+MQTTSUB=0,\"/sys/xxxx/xxx/thing/service/property/set\",1\r\n"
#define AT_MQTT_PUB "AT+MQTTPUB=0,\"/sys/xxx/xxx/thing/event/property/post\",\"{\\\"params\\\":{\\\"CurrentTemperature\\\":%d}}\",1,0\r\n"
//以上内容替换为你自己的信息
#define ACK_OK "OK"
#define BUFFER_SIZE 256
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t rx_buf[BUFFER_SIZE];
uint8_t tx_buf[BUFFER_SIZE];
bool rx_status = false;
extern DMA_HandleTypeDef hdma_uart4_rx;
uint8_t dma_rxbuf[BUFFER_SIZE];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
static void init(void);
static bool send_cmd(uint8_t *cmd, uint8_t *ack);
static void read_cmd();
float temperature = 0.0;
uint8_t recv_dat[6] = {0};
uint8_t recv_status[3] = {0};
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_UART4_Init();
MX_USART1_UART_Init();
MX_I2C2_Init();
MX_TIM6_Init();
/* USER CODE BEGIN 2 */
printf("A Temperature Detect System by YU from AminiPro Developers\n");
printf("EMBD APP INITING......\n");
printf("Loading GXHT3L Detector......\n");
GXHT3L_Reset();
GXHT3L_Init();
printf("*GXH3L Finished Loading*\n");
__HAL_UART_ENABLE_IT(&huart4,UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart4,dma_rxbuf,sizeof(dma_rxbuf));
init();
printf("INIT Finished\n");
printf("...............................................");
HAL_TIM_Base_Start_IT(&htim6);
if (GXHT3L_Read_Dat(recv_dat) == HAL_OK){
GXHT3L_Dat_To_Float(recv_dat, &temperature);
printf("temp == %f\n",temperature);
}
// uint8_t send_count = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
display(temperature);
// send_count ++;
// if(send_count >= 10){
// //10s????
// send_count = 0;
// sprintf((char *)tx_buf,"AT+MQTTPUB=0,\"/sys/a1Yd6Ze47ON/device1/thing/event/property/post\",\"{\\\"params\\\":{\\\"CurrentTemperature\\\":%d}}\",1,0\r\n", temperature);
// send_cmd(tx_buf,(uint8_t *)ACK_OK);
// temperature ++;
// if(temperature > 100)
// temperature = 20;
// }
// read_cmd();
// HAL_Delay(1000);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
void DMA_to_APP(uint8_t* dma_rxbuf, uint8_t len){
if(rx_status){
return;
}
if(len > BUFFER_SIZE){
return;
}
memcpy(rx_buf,dma_rxbuf,len);
rx_status = true;
}
bool send_cmd(uint8_t *cmd, uint8_t *ack){
int time_out=500;
memset(rx_buf,0,sizeof(rx_buf));
printf("send -----> %s\n",cmd);
HAL_UART_Transmit_DMA(&huart4,(uint8_t *)cmd,strlen((const char*)cmd));
while(time_out--){
if(rx_status){
printf("read-----> %s\n",rx_buf);
if(strstr((const char*)rx_buf, (const char*)ack)!=NULL){
printf("ack ok\n");
rx_status = false;
return true;
}
memset(rx_buf,0,sizeof(rx_buf));
rx_status = false;
}
HAL_Delay(10);
}
printf("ack fail\n");
return false;
}
void read_cmd(){
if(rx_status){
printf("read ----> %s\n",rx_buf);
rx_status = false;
}
}
void init(){
// send_cmd((uint8_t *)AT,(uint8_t *)ACK_OK);
// HAL_Delay(500);
send_cmd((uint8_t *)AT_WIFI_MODE,(uint8_t *)ACK_OK);
HAL_Delay(500);
send_cmd((uint8_t *)AT_SET_PSW,(uint8_t *)ACK_OK);
HAL_Delay(500);
send_cmd((uint8_t *)AT_SET_MQTT_CFG,(uint8_t *)ACK_OK);
HAL_Delay(500);
send_cmd((uint8_t *)AT_SET_MQTT_CLENTID,(uint8_t *)ACK_OK);
HAL_Delay(500);
send_cmd((uint8_t *)AT_SET_MQTT_CONN,(uint8_t *)ACK_OK);
HAL_Delay(500);
send_cmd((uint8_t *)AT_MQTT_SUB,(uint8_t *)ACK_OK);
HAL_Delay(500);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if (htim==&htim6){
if (GXHT3L_Read_Dat(recv_dat) == HAL_OK){
GXHT3L_Dat_To_Float(recv_dat, &temperature);
sprintf((char *)tx_buf,"AT+MQTTPUB=0,\"/sys/a1Yd6Ze47ON/device1/thing/event/property/post\",\"{\\\"params\\\":{\\\"CurrentTemperature\\\":%f}}\",1,0\r\n", temperature);
send_cmd(tx_buf,(uint8_t *)ACK_OK);
}
}
}
void UART_IDLEHandler(){
if(__HAL_UART_GET_FLAG(&huart4, UART_FLAG_IDLE) == SET){
__HAL_UART_CLEAR_FLAG(&huart4, UART_FLAG_IDLE);
HAL_UART_DMAStop(&huart4);
uint8_t rlen = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_uart4_rx);
DMA_to_APP(dma_rxbuf, rlen);
HAL_UART_Receive_DMA(&huart4,dma_rxbuf,sizeof(dma_rxbuf));
}
}
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1,(uint8_t*) &ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
tempget.h:
#include "main.h"
#define GXHT3L_ADDR_WRITE 0x44<<1 //10001000
#define GXHT3L_ADDR_READ (0x44<<1)+1 //10001001
typedef enum
{
/* ?????? */
SOFT_RESET_CMD = 0x30A2,
/* ????/???? */
PREHEAT_ENABLE_CMD = 0x306D,
PREHEAT_DISENABLE_CMD = 0x3066,
/* ?????? */
DEVICE_STATUS_CMD = 0xF32D,
/*
??????
????:Repeatability_CS_CMD
CS:Clock stretching
*/
HIGH_ENABLED_CMD = 0x2C06,
MEDIUM_ENABLED_CMD = 0x2C0D,
LOW_ENABLED_CMD = 0x2C10,
HIGH_DISABLED_CMD = 0x2400,
MEDIUM_DISABLED_CMD = 0x240B,
LOW_DISABLED_CMD = 0x2416,
/*
??????
????:Repeatability_MPS_CMD
MPS:measurement per second
*/
HIGH_0_5_CMD = 0x2032,
MEDIUM_0_5_CMD = 0x2024,
LOW_0_5_CMD = 0x202F,
HIGH_1_CMD = 0x2130,
MEDIUM_1_CMD = 0x2126,
LOW_1_CMD = 0x212D,
HIGH_2_CMD = 0x2236,
MEDIUM_2_CMD = 0x2220,
LOW_2_CMD = 0x222B,
HIGH_4_CMD = 0x2334,
MEDIUM_4_CMD = 0x2322,
LOW_4_CMD = 0x2329,
HIGH_10_CMD = 0x2737,
MEDIUM_10_CMD = 0x2721,
LOW_10_CMD = 0x272A,
/* ???????????? */
READOUT_FOR_PERIODIC_MODE = 0xE000,
} GXHT3L_CMD;
extern float temperature;
extern uint8_t recv_dat[6];
extern uint8_t recv_status[3];
uint8_t GXHT3L_Send_Cmd(GXHT3L_CMD cmd);
void GXHT3L_Reset(void);
void GXHT3L_Preheat_Disable(void);
uint8_t GXHT3L_Read_Status(uint8_t* dat);
uint8_t GXHT3L_Init(void);
uint8_t GXHT3L_Read_Dat(uint8_t* dat);
uint8_t GXHT3L_Dat_To_Float(uint8_t* const dat, float* temperature);
tempget.c
#include "tempget.h"
#include "i2c.h"
uint8_t GXHT3L_Send_Cmd(GXHT3L_CMD cmd)
{
uint8_t cmd_buffer[2];
cmd_buffer[0] = cmd >> 8;
cmd_buffer[1] = cmd;
return HAL_I2C_Master_Transmit(&hi2c2, GXHT3L_ADDR_WRITE, (uint8_t*) cmd_buffer, 2, 0xFFFF);
}
void GXHT3L_Reset(void)
{
GXHT3L_Send_Cmd(SOFT_RESET_CMD);
HAL_Delay(20);
}
void GXHT3L_Preheat_Disable(void)
{
GXHT3L_Send_Cmd(PREHEAT_DISENABLE_CMD);
HAL_Delay(20);
}
uint8_t GXHT3L_Read_Status(uint8_t* dat)
{
GXHT3L_Send_Cmd(DEVICE_STATUS_CMD);
return HAL_I2C_Master_Receive(&hi2c2, GXHT3L_ADDR_READ, dat, 3, 0xFFFF);
}
uint8_t GXHT3L_Init(void)
{
return GXHT3L_Send_Cmd(MEDIUM_2_CMD);
}
uint8_t GXHT3L_Read_Dat(uint8_t* dat)
{
GXHT3L_Send_Cmd(READOUT_FOR_PERIODIC_MODE);
return HAL_I2C_Master_Receive(&hi2c2, GXHT3L_ADDR_READ, dat, 6, 0xFFFF);
}
uint8_t GXHT3L_Dat_To_Float(uint8_t* const dat, float* temperature)
{
uint16_t recv_temperature = 0;
/* ?????? */
recv_temperature = ((uint16_t)dat[0]<<8)|dat[1];
*temperature = -45 + 175*((float)recv_temperature/65535);
return 0;
}
NUMLED.h
#include "main.h"
void hc595_shift_input(uint8_t byte);
void hc595_storage_input(uint8_t data, uint8_t addr);
void display(uint8_t dat);
NUMLED.c
#include "NUMLED.h"
#include "tempget.h"
void hc595_shift_input(uint8_t byte){
uint32_t i;
for (i=0;i<8;i++){
if (byte&0x80){
HAL_GPIO_WritePin(DS_GPIO_Port,DS_Pin,GPIO_PIN_SET);
}
else {
HAL_GPIO_WritePin(DS_GPIO_Port,DS_Pin,GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(SHCP_GPIO_Port,SHCP_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(SHCP_GPIO_Port,SHCP_Pin,GPIO_PIN_RESET);
byte<<=1;
}
}
void hc595_storage_input(uint8_t data, uint8_t addr){
hc595_shift_input(data);
HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_SET);
hc595_shift_input(1<<addr);
HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_SET);
}
uint8_t num[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void display(uint8_t dat){
uint8_t first = dat/10;
uint8_t second = dat%10;
hc595_storage_input(num[first],1);
hc595_storage_input(num[second],0);
}