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

设计题

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

配置过程:

节点1

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

在这里插入图片描述

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

引脚功能

在这里插入图片描述

使能ADC功能

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

使能RTC功能

在这里插入图片描述

3.生成工程代码

4.移植OLED、LoRa库文件

在这里插入图片描述

5.编写逻辑代码

自定义Task_Main.h Task_Main.c工程文件

Task_Main.h
#ifndef _TASK_MAIN_H_
#define _TASK_MAIN_H_

#include "main.h"
#include "stm32l0xx_hal.h"
#include "rtc.h"
#include "sx127x_lora.h"
#include "oled.h"
#include "stdio.h"
#include "string.h"
#include "stm32l0xx_it.h"
#include "adc.h"

void Task_BrdInit(void);
void Task_Main(void);
uint8_t user_scan(void);
void lora_recv(void);
void get_oled(void);
void get_adc(void);
void get_rtc_dis(void);
void get_adc_dis(void);
void get_rtc(void);

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

#define FREQ			433000000L
radio_handle_t handle;

RTC_DateTypeDef NOWDATE;
RTC_TimeTypeDef NOWTIME;

bool oled_mode = 0;  //0:RTC模式 1:ADC检测模式

float v_vrp1 = 0.00;
float v_vrp2 = 0.00;

uint8_t recv_buf[256] = {0};
uint16_t recv_buf_size;
uint32_t adc_value[2] = {0};
bool recv_flag = 0;
char oled_dis_rtc_1[16] = "      RTC       ";
char oled_dis_rtc_2[16] = "    23-59-55    ";
char oled_dis_adc_1[16] = "VRP1:0.00v      ";
char oled_dis_adc_2[16] = "VRP2:0.00v      ";

char send_data1[21] = "   VRP1:0.00:00-00-00";
char send_data2[21] = "   VRP2:0.00:00-00-00";

extern bool get_led5_flag;
extern bool get_lora_flag;
extern bool get_rtc_flag;
extern bool get_adc_flag;

void Task_Main(void)
{
  if(user_scan())
  {
    oled_mode = !oled_mode;
  }
  get_adc();
  if(oled_mode)
  {
    get_adc_dis();  
  }
  else
  {
    if(get_rtc_flag)
    {
      get_rtc_flag = 0;
      get_rtc_dis();
    }
  }

  if(get_lora_flag)
  {
    get_lora_flag = 0;
    lora_recv();
  }
}

void Task_BrdInit(void)
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
    OLED_PowerControl(ENABLE);
    HAL_Delay(200);
    OLED_Init();
    OLED_Clear();
    OLED_ShowString(0, 0, (uint8_t *)oled_dis_rtc_1, 16);
    OLED_ShowString(0, 2, (uint8_t *)oled_dis_rtc_2, 16);
    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_ADC_Start_DMA(&hadc, adc_value, 2);
}

void get_rtc_dis(void)
{
  HAL_RTC_GetTime(&hrtc, &NOWTIME, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &NOWDATE, RTC_FORMAT_BIN);
  
  sprintf(oled_dis_rtc_2, "    %02d-%02d-%02d    ", NOWTIME.Hours, NOWTIME.Minutes, NOWTIME.Seconds);
  OLED_ShowString(0, 0, (uint8_t *)oled_dis_rtc_1, 16);
  OLED_ShowString(0, 2, (uint8_t *)oled_dis_rtc_2, 16);
}

void get_rtc(void)
{
  HAL_RTC_GetTime(&hrtc, &NOWTIME, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &NOWDATE, RTC_FORMAT_BIN);
}

uint8_t user_scan(void)
{
  uint8_t key_stat = 0;
  key_stat = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14);
  HAL_Delay(50);
  key_stat = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14);
  if(key_stat == 0)
  {
    while(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14));
    return 1;
  }
  return 0;
}

void get_adc_dis(void)
{ 
  OLED_ShowString(0, 0, (uint8_t *)oled_dis_adc_1, 16);
  OLED_ShowString(0, 2, (uint8_t *)oled_dis_adc_2, 16);
}

void get_adc(void)
{
  v_vrp1 = (adc_value[1]*3.3)/(4095);
  v_vrp2 = (adc_value[0]*3.3)/(4095);

  sprintf(oled_dis_adc_1, "VRP1:%.2fv      ", v_vrp1);
  sprintf(oled_dis_adc_2, "VRP2:%.2fv      ", v_vrp2);
  HAL_ADC_Start_DMA(&hadc, adc_value, 2);
}

void lora_recv(void)
{
  uint8_t recv_data[256] = {0};

  if(radio_buf_recv(handle, recv_buf, &recv_buf_size) == RADIO_RET_OK)
  {
      uint8_t i=0;
      for(i=0; i<recv_buf_size-3; i++)
      {
        recv_data[i] = recv_buf[i+3];      
      }
      if(strcmp((const char *)recv_data, (const char *)"VRP1?") == 0)
      {
        recv_flag = 1;
        get_rtc();
        sprintf(send_data1, "   VRP1:%.2f:%02d-%02d-%02d", v_vrp1, NOWTIME.Hours, NOWTIME.Minutes, NOWTIME.Seconds);
        radio_buf_send(handle, (uint8_t *)send_data1, 21);
        radio_mode_set(handle, RX_MODE);
      }
      else if(strcmp((const char *)recv_data, (const char *)"VRP2?") == 0)
      {
        recv_flag = 1;
        get_rtc();
        sprintf(send_data2, "   VRP2:%.2f:%02d-%02d-%02d", v_vrp2, NOWTIME.Hours, NOWTIME.Minutes, NOWTIME.Seconds);        
        radio_buf_send(handle, (uint8_t *)send_data2, 21);
        radio_mode_set(handle, RX_MODE);
      }
      radio_mode_set(handle, RX_MODE);	//Receive Mode
  }
}
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引脚做如下配置:

引脚功能

在这里插入图片描述

使能USART2串口功能

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

3.生成工程代码

4.移植LoRa库文件

在这里插入图片描述

5.编写逻辑代码

自定义Task_Main.h Task_Main.c工程文件

Task_Main.h
#ifndef _TASK_MAIN_H_
#define _TASK_MAIN_H_

#include "main.h"
#include "stdio.h"
#include "string.h"
#include "stm32l0xx_hal.h"
#include "sx127x_lora.h"
#include "usart.h"

void Task_BrdInit(void);
void Task_Main(void);


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

#define FREQ			433000000L
radio_handle_t handle;

uint8_t uart_buf[5] = {0};
uint8_t cmd_num = 0;
uint8_t recv_buf[256] = {0};
uint16_t recv_buf_size;

uint8_t cmd1[27] = "   VRP1?";
uint8_t cmd2[27] = "   VRP2?";

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

void Task_Main(void)
{
  if(cmd_num == 1)
  {
      cmd_num = 0;  
      radio_buf_send(handle, cmd1, 5+3);
      radio_mode_set(handle, RX_MODE);    
  }
  if(cmd_num == 2)
  {
      cmd_num = 0;
      radio_buf_send(handle, cmd2, 5+3);
      radio_mode_set(handle, RX_MODE);    
  }
  if(radio_buf_recv(handle, recv_buf, &recv_buf_size) == RADIO_RET_OK)
  {
      uint8_t recv_data[18] = {0};
      uint8_t i=0;
      
      for(i=0; i<18; i++)
      {
        recv_data[i] = recv_buf[i+3];
      }
    
      printf("%s\n", recv_data);
      radio_mode_set(handle, RX_MODE);	//Receive Mode
  }
}

void Task_BrdInit(void)
{
    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_Receive_IT(&huart2, uart_buf, 5);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    uint8_t i;
    uint8_t uart_data[5] = {0};
  
    for(i=0; i<5; i++)
    {
      uart_data[i] = uart_buf[i];
    }
    if(strcmp((const char *)uart_data, "VRP1?")==0)
    {
      cmd_num = 1;

    }
    else if(strcmp((const char *)uart_data, "VRP2?")==0)
    {
      cmd_num = 2;
    }
    else
    {
      cmd_num = 0;
      printf("Error\n");        
    }
    HAL_UART_Receive_IT(&huart2, uart_buf, 5);  
}
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 */
stm32l0xx_it.c

引入头文件

/* USER CODE BEGIN Includes */
#include "Task_Main.h"
/* USER CODE END Includes */

轮询标志

/* USER CODE BEGIN TD */
bool get_led5_flag = 0;
bool get_lora_flag = 0;
bool get_rtc_flag = 0;
extern bool recv_flag;
/* USER CODE END TD */

轮询函数

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
  static uint16_t lora_num= 0;   
  static uint16_t rtc_num= 0;
  static uint16_t led_num= 0; 
  
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  lora_num++;   
  rtc_num++;
  
  if(lora_num>=200)
  {
    lora_num = 0;
    get_lora_flag = 1;
  }
  if(rtc_num>=800)
  {
    rtc_num = 0;
    get_rtc_flag = 1;
  }
  if(recv_flag==1)
  {
    if(led_num%400==0)
    {
      HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);
    }
    led_num++;
    if(led_num>=3600)
    {
      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
      recv_flag = 0;
      led_num = 0;
    }
  }
  
  /* USER CODE END SysTick_IRQn 1 */
}

实验现象

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

代码优化

节点1

Task_Main.c

#include "Task_main.h"

#define FREQ			433000000L
radio_handle_t handle;
#define PERIOD 100000

RTC_DateTypeDef NOWDATE;
RTC_TimeTypeDef NOWTIME;

bool oled_mode = 0;  //0:RTC模式 1:ADC检测模式

float v_vrp1 = 0.00;
float v_vrp2 = 0.00;

uint8_t recv_buf[256] = {0};
uint16_t recv_buf_size;
uint32_t adc_value[10] = {0};
bool recv_flag = 0;
char oled_dis_rtc_1[16] = "      RTC       ";
char oled_dis_rtc_2[16] = "    23-59-55    ";
char oled_dis_adc_1[16] = "VRP1:0.00V      ";
char oled_dis_adc_2[16] = "VRP2:0.00V      ";

char send_data1[21] = "   VRP1:0.00:00-00-00";
char send_data2[21] = "   VRP2:0.00:00-00-00";

bool get_lora_flag = 0;
extern bool get_led5_flag;
extern bool get_rtc_flag;
extern bool get_adc_flag;

void Task_Main(void)
{
  get_adc(); 
  
  if(oled_mode)
  {
    get_adc_dis();  
  }
  else
  {
    if(get_rtc_flag)
    {
      get_rtc_flag = 0;
      get_rtc_dis();
    }
  }
  if(get_lora_flag)
  {
    get_lora_flag = 0;
    lora_recv();
  }
}

void Task_BrdInit(void)
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
    OLED_PowerControl(ENABLE);
    HAL_Delay(200);
    OLED_Init();
    OLED_Clear();
    OLED_ShowString(0, 0, (uint8_t *)oled_dis_rtc_1, 16);
    OLED_ShowString(0, 2, (uint8_t *)oled_dis_rtc_2, 16);
    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_ADC_Start_DMA(&hadc, adc_value, 10);
}

void get_rtc_dis(void)
{
  HAL_RTC_GetTime(&hrtc, &NOWTIME, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &NOWDATE, RTC_FORMAT_BIN);
  
  sprintf(oled_dis_rtc_2, "    %02d-%02d-%02d    ", NOWTIME.Hours, NOWTIME.Minutes, NOWTIME.Seconds);
  OLED_ShowString(0, 0, (uint8_t *)oled_dis_rtc_1, 16);
  OLED_ShowString(0, 2, (uint8_t *)oled_dis_rtc_2, 16);
}

void get_rtc(void)
{
  HAL_RTC_GetTime(&hrtc, &NOWTIME, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &NOWDATE, RTC_FORMAT_BIN);
}

void get_adc_dis(void)
{ 
  OLED_ShowString(0, 0, (uint8_t *)oled_dis_adc_1, 16);
  OLED_ShowString(0, 2, (uint8_t *)oled_dis_adc_2, 16);
}

void get_adc(void)
{
  v_vrp2 = ((adc_value[0]+adc_value[2]+adc_value[4]+adc_value[6]+adc_value[8])*3.3)/(4095*5);
  v_vrp1 = ((adc_value[1]+adc_value[3]+adc_value[5]+adc_value[7]+adc_value[9])*3.3)/(4095*5);

  sprintf(oled_dis_adc_1, "VRP1:%.2fV      ", v_vrp1);
  sprintf(oled_dis_adc_2, "VRP2:%.2fV      ", v_vrp2);
  HAL_ADC_Start_DMA(&hadc, adc_value, 10);
}

void lora_recv(void)
{
  uint8_t recv_data[256] = {0};

  if(radio_buf_recv(handle, recv_buf, &recv_buf_size) == RADIO_RET_OK)
  {
      uint8_t i=0;
      for(i=0; i<recv_buf_size-3; i++)
      {
        recv_data[i] = recv_buf[i+3];      
      }
      if(strcmp((const char *)recv_data, (const char *)"VRP1?") == 0)
      {
        HAL_LPTIM_Counter_Start_IT(&hlptim1, PERIOD);
        get_rtc();
        sprintf(send_data1, "   VRP1:%.2f:%02d-%02d-%02d", v_vrp1, NOWTIME.Hours, NOWTIME.Minutes, NOWTIME.Seconds);
        radio_buf_send(handle, (uint8_t *)send_data1, 21);
        radio_mode_set(handle, RX_MODE);
      }
      else if(strcmp((const char *)recv_data, (const char *)"VRP2?") == 0)
      {
       HAL_LPTIM_Counter_Start_IT(&hlptim1, PERIOD);
        get_rtc();
        sprintf(send_data2, "   VRP2:%.2f:%02d-%02d-%02d", v_vrp2, NOWTIME.Hours, NOWTIME.Minutes, NOWTIME.Seconds);        
        radio_buf_send(handle, (uint8_t *)send_data2, 21);
        radio_mode_set(handle, RX_MODE);
      }
      radio_mode_set(handle, RX_MODE);	//Receive Mode
  }
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_14)
  {
    oled_mode = !oled_mode;
  }
  if(GPIO_Pin == GPIO_PIN_10)
  {
    get_lora_flag = 1;
  }
}

uint16_t num = 1;
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
  if(num!=10)
  {
    num++;
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);
  }
  else
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
    num = 1;
    HAL_LPTIM_Counter_Stop_IT(&hlptim1);
  }
}

Task_Main.h

#ifndef _TASK_MAIN_H_
#define _TASK_MAIN_H_

#include "main.h"
#include "stm32l0xx_hal.h"
#include "rtc.h"
#include "sx127x_lora.h"
#include "oled.h"
#include "stdio.h"
#include "string.h"
#include "stm32l0xx_it.h"
#include "adc.h"
#include "lptim.h"

void Task_BrdInit(void);
void Task_Main(void);
void lora_recv(void);
void get_oled(void);
void get_adc(void);
void get_rtc_dis(void);
void get_adc_dis(void);
void get_rtc(void);

#endif

stm32l0xx_it.c

/* USER CODE BEGIN Includes */
#include "Task_Main.h"
/* USER CODE END Includes */

/* USER CODE BEGIN TD */
bool get_rtc_flag = 0;
extern bool recv_flag;
/* USER CODE END TD */

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
  static uint16_t rtc_num= 0;
  
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  rtc_num++;
  if(rtc_num>=800)
  {
    rtc_num = 0;
    get_rtc_flag = 1;
  }
  /* USER CODE END SysTick_IRQn 1 */
}
  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

T-Y_yang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值