6 -【第十三届】蓝桥杯物联网试题 (省赛题)

设计题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

节点1

1.将时钟树频率设置成32MHz

在这里插入图片描述

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

引脚功能

在这里插入图片描述

使能中断

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

打开串口通信2

在这里插入图片描述

3.生成工程代码

在这里插入图片描述

4.移植OLED、LoRa库文件

在这里插入图片描述

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 "usart.h"

void Task_BrdInit(void);
void Task_Main(void);
void key_fun(void);
void led_fun(void);
void oled_dis(void);

#endif
Task_Main.c
#include "Task_Main.h"

radio_handle_t handle;
#define FREQ			445000000L

bool key_flag = 0;
bool lora_flag = 0;
uint8_t LD2=0, LD3=0, LD5=0;

uint32_t count = 0;
uint8_t data[10] = {0};
uint8_t uart_recv_buf[256] = {0};

uint8_t ID = 97;
char lora_send_buf[23] = "ID:97,LD2:0,LD3:0,LD5:0";

int fputc(int ch, FILE *f)
{
    while(((USART2->ISR)&(1<<7))==0);
    USART2->TDR = (uint8_t)ch;
  
    return ch;
}

void Task_Main(void)
{
	/*按键检测*/
	if(key_flag)
	{
		key_flag = 0;
		key_fun();
	}
	/*指示灯状态检测*/
	led_fun();
	/*OLED显示更新*/
	oled_dis();
}

void Task_BrdInit(void)
{
    //OLED初始化
    OLED_PowerControl(ENABLE);
    HAL_Delay(200);
    OLED_Init();
    OLED_Clear();
	OLED_ShowString(0, 0, (unsigned char *)"      RX:      ", 16);
	OLED_ShowString(0, 2, (unsigned char *)"     NUM: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);
	
	data[0] = '\0';
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_14)
	{
		key_flag = 1;
	}
	if(GPIO_Pin == GPIO_PIN_10)
	{
		lora_flag = 1;
	}
}

void key_fun(void)
{
	sprintf(lora_send_buf, "ID:%2d,LD2:%c,LD3:%c,LD5:%c", ID, LD2, LD3, LD5);
	radio_buf_send(handle, (uint8_t *)lora_send_buf, 23);
	radio_mode_set(handle, RX_MODE);
}

void led_fun(void)
{
	if(LD2)
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);		
	}
	if(LD3)
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);		
	}
	if(LD5)
	{
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);		
	}	
}

void oled_dis(void)
{
	char dis1[16] = {0};
	char dis2[16] = {0};	
	
	sprintf(dis1, "      RX:%c", data[0]);
	sprintf(dis2, "     NUM:%d", count);
	
	OLED_ShowString(0, 0, (uint8_t *)dis1, 16);
	OLED_ShowString(0, 2, (uint8_t *)dis2, 16);	
}

stm32l0xx_it.c
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
extern uint8_t data[10];
extern uint32_t count;
extern uint8_t LD2, LD3, LD5;

/* 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[0] = USART2->RDR;
		switch(data[0])
		{
			case '@':
				if(LD5)
				{
					LD5 = 0;
				}
				else
				{
					LD5 = 1;
				}
				count++;
				break;
			case '#':
				if(LD2)
				{
					LD2 = 0;
				}
				else
				{
					LD2 = 1;
				}	
				count++;
				break;
			case '$':
				if(LD3)
				{
					LD3 = 0;
				}
				else
				{
					LD3 = 1;
				}
				count++;
				break;
			default:
		HAL_UART_Transmit(&huart2, (uint8_t *)"error", 5, 50);				
				break;
		}
	}
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}
main.c
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "Task_Main.h"
/* USER CODE END Includes */
  /* USER CODE BEGIN 2 */
	Task_BrdInit();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* 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库文件

在这里插入图片描述

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 "adc.h"

void Task_BrdInit(void);
void Task_Main(void);
void get_adc(void);
void oled_dis(void);
void oled_flush(void);
void lora_recv(void);
void get_cmd(void);
void led_fun(void);
	
#endif

Task_Main.c
#include "Task_Main.h"

radio_handle_t handle;
#define FREQ			445000000L

bool key_flag = 0;
bool lora_flag = 0;
bool oled_mode = 0;

uint32_t ADC_Value[20] = {0};
uint8_t LD2=0, LD3=0, LD5=0;
uint32_t num = 0;

uint8_t lora_recv_buf[256] = {0};
uint16_t lora_recv_buf_size = 0;

float vol1 = 3.1;
float vol2 = 0.8;

void Task_Main(void)
{
	/*按键检测*/
	if(key_flag)
	{
		key_flag = 0;
		oled_mode = !oled_mode;
		oled_flush();
	}
	/*ADC检测*/
	get_adc();
	/*oled显示刷新*/
	oled_dis();
	/*lora接收检测*/
	if(lora_flag)
	{
		lora_flag = 0;
		lora_recv();
	}
	/*led状态更新*/
	led_fun();
}

void Task_BrdInit(void)
{
    //OLED初始化
    OLED_PowerControl(ENABLE);
    HAL_Delay(200);
    OLED_Init();
    OLED_Clear();
	OLED_ShowString(0, 0, (unsigned char *)"    RP1:3.1V    ", 16);
	OLED_ShowString(0, 2, (unsigned char *)"    RP2:0.8V    ", 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
    } 
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_14)
	{
		key_flag = 1;
	}
	if(GPIO_Pin == GPIO_PIN_10)
	{
		lora_flag = 1;
	}
}

void get_adc(void)
{
	HAL_ADC_Start_DMA(&hadc, ADC_Value, 10);
	vol2 = ((ADC_Value[0]+ADC_Value[2]+ADC_Value[4]+ADC_Value[6]+ADC_Value[8])*3.3)/(4095*5);
	vol1 = ((ADC_Value[1]+ADC_Value[3]+ADC_Value[5]+ADC_Value[7]+ADC_Value[9])*3.3)/(4095*5);	
	vol1 = (int)(vol1*10 + 0.5) * 0.1;
	vol2 = (int)(vol2*10 + 0.5) * 0.1;
}

void oled_dis(void)
{
	char dis_vol1[3] = {0};
	char dis_vol2[3] = {0};
	char dis_num[6] = {0};
	
	if(!oled_mode)
	{
		sprintf(dis_vol1, "%3.1f", vol1);
		sprintf(dis_vol2, "%3.1f", vol2);		

		OLED_ShowString(64, 0, (uint8_t *)dis_vol1, 16);
		OLED_ShowString(64, 2, (uint8_t *)dis_vol2, 16);	
	}
	else
	{
		sprintf(dis_num, "%d", num);
		OLED_ShowString(72, 0, (uint8_t *)dis_num, 16);	
		if(LD2&LD3)
		{
			OLED_ShowString(64, 2, (unsigned char *)"ON ", 16);
		}
		else
		{
			OLED_ShowString(64, 2, (unsigned char *)"OFF", 16);
		}		
	}
}

void oled_flush(void)
{
	char oled_fl1[16] = {0};
	char oled_fl2[16] = {0};	
	
	if(!oled_mode)
	{
		sprintf(oled_fl1, "    RP1:%3.1fV    ", vol1);
		sprintf(oled_fl2, "    RP1:%3.1fV    ", vol2);	
		
		OLED_ShowString(0, 0, (uint8_t *)oled_fl1, 16);
		OLED_ShowString(0, 2, (uint8_t *)oled_fl2, 16);		
	}
	else
	{
		sprintf(oled_fl1, "     NUM:%d", num);
		OLED_ShowString(0, 0, (uint8_t *)"                ", 16);
		OLED_ShowString(0, 0, (uint8_t *)oled_fl1, 16);		
		if(LD2&LD3)
		{
			OLED_ShowString(0, 2, (unsigned char *)"    STA:ON      ", 16);
		}
		else
		{
			OLED_ShowString(0, 2, (unsigned char *)"    STA:OFF     ", 16);
		}
		
	}	
}

void lora_recv(void)
{
	int ret = -1;
	
	ret = radio_buf_recv(handle, lora_recv_buf, &lora_recv_buf_size);
	if((ret== RADIO_RET_OK)&&(lora_recv_buf_size==23))
	{
		get_cmd();
	}
}

void get_cmd(void)
{
	if((lora_recv_buf[3]=='9')&&(lora_recv_buf[4]=='7'))
	{
		LD2 = lora_recv_buf[10];
		LD3 = lora_recv_buf[16];
		LD5 = lora_recv_buf[22];	
		num++;
	}
}

void led_fun(void)
{
	if(LD2==1)
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);		
	}
	if(LD3==1)
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);		
	}
	if(LD5==1)
	{
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);		
	}	
}

main.c
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "Task_Main.h"
/* USER CODE END Includes */
  /* USER CODE BEGIN 2 */
	Task_BrdInit();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	 Task_Main();
  }
  /* USER CODE END 3 */

实验现象

Node_A

Node_B

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T-Y_yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值