设计题
配置过程:
节点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 433000000L
bool 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 433000000L
uint8_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的相关信息