3 -【第十一届】蓝桥杯物联网试题(国赛题)
设计题




配置过程:
节点1
1.将时钟树频率设置成32MHz

2.将GPIO引脚做如下配置:
引脚功能

使能中断



打开串口通信2


3.生成工程代码

4.移植OLED、LoRa、STS30库文件

5.编写逻辑代码
Task_Main.h
#ifndef _TASK_MAIN_H_
#define _TASK_MAIN_H_#include "main.h"
#include "stm32l0xx_hal.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "oled.h"
#include "sx127x_lora.h"
#include "sts30.h"
#include "usart.h"void Task_BrdInit(void);
void Task_Main(void);
void uart_recv(void);
void oled_dis_mode0(void);
void oled_dis_mode1(void);
void get_temp(void);
void recv_buf(void);
void get_cmd(void);#endif
Task_Main.c
#include "Task_Main.h"radio_handle_t handle;
#define FREQ 433000000Lbool key_flag = 0;
bool recv_flag = 0;
//0:温度界面 1:温度上下限
bool oled_mode = 0;float temp = 00.0;
int Tmax = 26;
int Tmin = 22;bool k1_stat = 0;
bool k2_stat = 1;uint8_t uart_recv_buf[256] = {0};
uint8_t data[10] = {0};
uint8_t count = 0;uint8_t lora_recv_buf[256] = {0};
uint16_t lora_recv_size = 0;int fputc(int ch, FILE *f)
{while(((USART2->ISR)&(1<<7))==0);USART2->TDR = (uint8_t)ch;return ch;
}void Task_Main(void)
{// 1.按键检测if(key_flag){key_flag = 0;oled_mode = !oled_mode;}// 2.lora接收检测if(recv_flag){recv_flag = 0;recv_buf();}// 3.获取温度get_temp();// 4.串口接收检测uart_recv();// 5.oled显示if(oled_mode==0){oled_dis_mode0();}else{oled_dis_mode1(); }
}void Task_BrdInit(void)
{//sts30初始化sts30_pin_init();//OLED初始化OLED_PowerControl(ENABLE);HAL_Delay(200);OLED_Init();OLED_Clear();OLED_ShowString(0, 0, (unsigned char *)" Temperature ", 16);OLED_ShowString(0, 2, (unsigned char *)" 25.0 ", 16);//LoRa初始化spi_init();zm4xx_pin_init();handle = radio_zm4xx_inst_init(spi_recv_byte,spi_send_byte,zm4xx_rst_pin_set,zm4xx_sel_pin_set,HAL_Delay,delay_us);if(handle != NULL){if(RADIO_RET_OK == radio_freq_set(handle, FREQ)){}radio_mode_set(handle, RX_MODE); //Receive Mode} __HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);HAL_UART_Receive_IT(&huart2, uart_recv_buf, 1);
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_14){key_flag = 1;}if(GPIO_Pin == GPIO_PIN_10){recv_flag = 1;}
}void uart_recv(void)
{uint16_t temp = 0;if(count>=4){count = 0;data[5] = '\0';if((data[0]=='M') && (data[1]=='A') && (data[2]=='X')){temp = (data[3]-0x30)*10 + (data[4]-0x30);if(temp > Tmin){Tmax = temp;printf("OK\r\n");}else{printf("ERROR\r\n");}}else if((data[0]=='M') && (data[1]=='I') && (data[2]=='N')){temp = (data[3]-0x30)*10 + (data[4]-0x30);if(temp < Tmax){Tmin = temp;printf("OK\r\n");}else{printf("ERROR\r\n");} }else{printf("ERROR\r\n"); } }
}void oled_dis_mode0(void)
{char dis_str[16] = {0};sprintf(dis_str, " %4.1f ", temp);OLED_ShowString(0, 0, (unsigned char *)" Temperature ", 16);OLED_ShowString(0, 2, (uint8_t *)dis_str, 16);
}void oled_dis_mode1(void)
{char dis_str1[16] = {0};char dis_str2[16] = {0};sprintf(dis_str1, " Tmax:%02d ", Tmax);sprintf(dis_str2, " Tmin:%02d ", Tmin); OLED_ShowString(0, 0, (uint8_t *)dis_str1, 16);OLED_ShowString(0, 2, (uint8_t *)dis_str2, 16);
}void get_temp(void)
{temp = Get_Temperature();temp = (int)((temp*10)+0.5)/10.0;if(temp > Tmax){k1_stat = 1;k2_stat = 0;HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);}else if(temp < Tmin){k1_stat = 0;k2_stat = 1;HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);}else{k1_stat = 0;k2_stat = 0;HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); }
}void recv_buf(void)
{int ret = 0;ret = radio_buf_recv(handle, lora_recv_buf, &lora_recv_size);if(ret == RADIO_RET_OK){get_cmd();}
}void get_cmd(void)
{char data[6] = {0};if(lora_recv_size == 1){switch(lora_recv_buf[0]){case 0x1:sprintf(data, "1:%04.1f", temp);radio_buf_send(handle, (uint8_t *)data, strlen(data));radio_mode_set(handle, RX_MODE);break;case 0x2:sprintf(data, "2:%02d%02d", Tmax, Tmin);radio_buf_send(handle, (uint8_t *)data, strlen(data));radio_mode_set(handle, RX_MODE); break;case 0x3:sprintf(data, "3:%d", k1_stat);radio_buf_send(handle, (uint8_t *)data, strlen(data));radio_mode_set(handle, RX_MODE); break;case 0x4:sprintf(data, "4:%d", k2_stat);radio_buf_send(handle, (uint8_t *)data, strlen(data));radio_mode_set(handle, RX_MODE); break;}}
}
stm32l0xx_it.c
定义变量
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
extern uint8_t data[10];
extern uint8_t count;
/* USER CODE END TD */
串口接收代码
/*** @brief This function handles USART2 global interrupt / USART2 wake-up interrupt through EXTI line 26.*/
void USART2_IRQHandler(void)
{/* USER CODE BEGIN USART2_IRQn 0 */if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE)==SET){data[count] = USART2->RDR;if(data[count] == 'M'){count = 0;data[count++] = 'M';}else{count++;}}/* USER CODE END USART2_IRQn 0 */HAL_UART_IRQHandler(&huart2);/* USER CODE BEGIN USART2_IRQn 1 *//* USER CODE END USART2_IRQn 1 */
}
main.c
引入头文件
/* USER CODE BEGIN Includes */
#include "Task_Main.h"
/* USER CODE END Includes */
板级初始化
/* USER CODE BEGIN 2 */Task_BrdInit();/* USER CODE END 2 */
主控代码
/* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Task_Main();}/* USER CODE END 3 */
节点2
1.将时钟树频率设置成32MHz

2.将GPIO引脚做如下配置:
引脚功能

使能中断


3.生成工程代码

4.移植LoRa、OLED、Key库文件

5.编写逻辑代码
Task_Main.h
#ifndef _TASK_MAIN_H_
#define _TASK_MAIN_H_#include "main.h"
#include "stm32l0xx_hal.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "oled.h"
#include "sx127x_lora.h"
#include "key.h"void Task_BrdInit(void);
void Task_Main(void);
void get_temp(void);
void get_temp_set(void);
void get_k1_stat(void);
void get_k2_stat(void);
void recv_buf(void);
void get_cmd(void);#endif
Task_Main.c
#include "Task_Main.h"radio_handle_t handle;
#define FREQ 433000000Luint8_t key_num = 0;
bool recv_flag = 0;uint8_t cmd_temp[1] = {0x01};
uint8_t cmd_temp_set[5] = {0x02};
uint8_t cmd_k1_stat[5] = {0x03};
uint8_t cmd_k2_stat[5] = {0x04};uint8_t lora_recv_buf[256] = {0};
uint16_t lora_recv_size = 0;float temp = 00.0;
int Tmax, Tmin;
bool k1_stat, k2_stat;void Task_Main(void)
{key_num = Keyboard_Scan();switch(key_num){case 1:get_temp();break;case 2:get_temp_set();break; case 4:get_k1_stat();break; case 5:get_k2_stat();break; }if(recv_flag){recv_flag = 0;recv_buf();}
}void Task_BrdInit(void)
{//OLED初始化OLED_PowerControl(ENABLE);HAL_Delay(200);OLED_Init();OLED_Clear();OLED_ShowString(0, 0, (unsigned char *)" Tmax:26 ", 16);OLED_ShowString(0, 2, (unsigned char *)" Tmin:22 ", 16);//LoRa初始化spi_init();zm4xx_pin_init();handle = radio_zm4xx_inst_init(spi_recv_byte,spi_send_byte,zm4xx_rst_pin_set,zm4xx_sel_pin_set,HAL_Delay,delay_us);if(handle != NULL){if(RADIO_RET_OK == radio_freq_set(handle, FREQ)){}radio_mode_set(handle, RX_MODE); //Receive Mode}//按键初始化key_pin_init();
}void get_temp(void)
{radio_buf_send(handle, cmd_temp, 1);radio_mode_set(handle, RX_MODE);
}void get_temp_set(void)
{radio_buf_send(handle, cmd_temp_set, 1);radio_mode_set(handle, RX_MODE);
}void get_k1_stat(void)
{radio_buf_send(handle, cmd_k1_stat, 1);radio_mode_set(handle, RX_MODE);
}void get_k2_stat(void)
{radio_buf_send(handle, cmd_k2_stat, 1);radio_mode_set(handle, RX_MODE);
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_10){recv_flag = 1;}
}void recv_buf(void)
{int ret = 0;ret = radio_buf_recv(handle, lora_recv_buf, &lora_recv_size);if(ret == RADIO_RET_OK){get_cmd();}
}void get_cmd(void)
{char dis_str1[16] = {0};char dis_str2[16] = {0};if(lora_recv_buf[0] == '1'){temp = (lora_recv_buf[2]-0x30)*10 + (lora_recv_buf[3]-0x30) + (lora_recv_buf[5]-0x30)*0.1;sprintf(dis_str2, " %4.1f ", temp);OLED_ShowString(0, 0, (unsigned char *)" Temperature ", 16);OLED_ShowString(0, 2, (uint8_t *)dis_str2, 16); }else if(lora_recv_buf[0] == '2'){Tmax = (lora_recv_buf[2]-0x30)*10 + (lora_recv_buf[3]-0x30); Tmin = (lora_recv_buf[4]-0x30)*10 + (lora_recv_buf[5]-0x30); sprintf(dis_str1, " Tmax:%02d ", Tmax);sprintf(dis_str2, " Tmin:%02d ", Tmin); OLED_ShowString(0, 0, (uint8_t *)dis_str1, 16);OLED_ShowString(0, 2, (uint8_t *)dis_str2, 16); }else if(lora_recv_buf[0] == '3'){k1_stat = (bool)(lora_recv_buf[2]-0x30);OLED_ShowString(0, 0, (unsigned char *)" K1 Status ", 16);if(k1_stat){OLED_ShowString(0, 2, (unsigned char *)" 1 ", 16); }else{OLED_ShowString(0, 2, (unsigned char *)" 0 ", 16); }}else if(lora_recv_buf[0] == '4'){k2_stat = (bool)(lora_recv_buf[2]-0x30); OLED_ShowString(0, 0, (unsigned char *)" K2 Status ", 16); if(k2_stat){OLED_ShowString(0, 2, (unsigned char *)" 1 ", 16); }else{OLED_ShowString(0, 2, (unsigned char *)" 0 ", 16); } }
}
main.c
引入头文件
/* USER CODE BEGIN Includes */
#include "Task_Main.h"
/* USER CODE END Includes */
板级初始化
/* USER CODE BEGIN 2 */Task_BrdInit();/* USER CODE END 2 */
主控代码
/* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Task_Main();}/* USER CODE END 3 */
实验现象
Node_A
节点A可以通过串口调节温度上下限

节点A可以通过按键切换界面


Node_B
节点B可以通过矩阵按键查询节点A的相关信息




本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
