赞
踩
通过对题目解读,一共会用到如下外设和资源:GPIO、OLED、LED、Lora模块、矩阵按键、电位器、继电器等。
软件层面需要使用到:定时器、中断、ADC
通信协议:IIC(OLED控制)、SPI(Lora通信)
我个人看到题目之后,是先从NODE.B开始编写的,除了Lora通信控制的部分,我是先写完NODE.B,再去写NODE.A的。先完成两个模块的一些基本功能(比如OLED显示、继电器控制、AD采集、按键等),最后再实现两边的通信。
定时器和外部中断设置好后,一定要记得使能(enable)
ADC使用的是通道8和通道9
其余的配置同NODE.A一致,除了GPIO由于多了几个引脚可能配置不一样。
CUBEMX可能有些地方配置有些多余,这里仅供参考。
这里只展示主函数部分,详细请看压缩包
- /* USER CODE END Header */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "i2c.h"
- #include "spi.h"
- #include "tim.h"
- #include "gpio.h"
-
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include "stdio.h"
- #include "lora.h"
- #include "oled.h"
- /* USER CODE END Includes */
-
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
- void key_check(void);
- void lora_proc(void);
- void oled_proc(void);
- uint16_t Scan_Col1(void);
- uint16_t Scan_Col2(void);
- /* USER CODE END PTD */
-
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
-
- /* USER CODE END PD */
-
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- struct key{
- uint8_t B1;
- uint8_t B2;
- uint8_t B4;
- uint8_t B5;
- }key1;
- struct show{
- float CV;
- float PV;
- uint8_t K1;
- uint8_t K2;
- uint8_t mode;
- }show1;
-
- uint8_t Lora_Txbuff[6];
- uint8_t Lora_Rxbuff[7];
- uint8_t Strbuff[17];
- uint8_t key_value;
- uint8_t Tx_flag;
-
- /* USER CODE END PM */
-
- /* Private variables ---------------------------------------------------------*/
-
- /* USER CODE BEGIN PV */
-
- /* USER CODE END PV */
-
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- /* USER CODE BEGIN PFP */
-
- /* 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_I2C3_Init();
- MX_SPI1_Init();
- MX_TIM2_Init();
- /* USER CODE BEGIN 2 */
- //OLED_Init();
- HAL_NVIC_DisableIRQ(TIM2_IRQn);
- HAL_TIM_Base_Start_IT(&htim2);
- LORA_Init();
-
-
- Write(ROW1,RESET);
- Write(ROW2,RESET);
- key_value=0;
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- lora_proc();
- key_check();
- oled_proc();
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
-
- }
- /* USER CODE END 3 */
- }
-
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
-
- /** Configure the main internal regulator output voltage
- */
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
-
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_3;
- RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
- 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_DIV1;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
- {
- Error_Handler();
- }
- PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C3;
- PeriphClkInit.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
- {
- Error_Handler();
- }
- }
-
- /* USER CODE BEGIN 4 */
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- static uint16_t ms=0;
- static uint8_t s=0;
- if(++ms==999)
- {
- ms=0;
- if(++s==3)
- {
- s=0;
- Write(LD5,SET);
- HAL_NVIC_DisableIRQ(TIM2_IRQn);
- }
- }
- }
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
-
- switch(GPIO_Pin)
- {
- case GPIO_PIN_1:
- key_value=Scan_Col1();
- while(Read(COL1)==0);
- break;
- case GPIO_PIN_0:
- key_value=Scan_Col2();
- while(Read(COL2)==0);
- break;
- default:
- break;
- }
- }
-
- void key_check(void)
- {
- if(key_value != 0)
- {
- switch(key_value)
- {
- case 1:
- key1.B1=1;
- break;
- case 2:
- key1.B2=1;
- static uint8_t oled_flag=1;
- if(oled_flag==1)
- {
- OLED_Init();
- oled_flag=0;
- }
- Write(LD5,RESET);
- HAL_NVIC_EnableIRQ(TIM2_IRQn);
- break;
- case 4:
- key1.B4=1;
- break;
- case 5:
- key1.B5=1;
- break;
- default:
- break;
- }
- Tx_flag=1;
- key_value=0;
- }
- }
- uint16_t Scan_Col1(void)
- {
- static uint16_t ucKey_val=0; //设立变量存键值
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_SET);//拉高3列的电平
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_SET);
- //遍历列
- for(uint8_t i=0;i<2;i++)
- {
- HAL_NVIC_DisableIRQ(EXTI0_1_IRQn);//关闭ROW1的中断
- switch(i){
- case 0:
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_RESET);//拉低列1
- if(HAL_GPIO_ReadPin(COL1) == 0)//读取键值
- ucKey_val = 1;
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_SET);//拉高列1
- break;
- case 1:
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_RESET);//拉低列2
- if(HAL_GPIO_ReadPin(COL1) == 0)//读取键值
- ucKey_val = 4;
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_SET);//拉高列2
- break;
- default:
- break;
- }
- }
- //拉低三列的电平
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_RESET);
- //打开ROW1中断
- HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
-
- return ucKey_val;
- }
- uint16_t Scan_Col2(void)
- {
- static uint16_t ucKey_val=0; //设立变量存键值
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_SET);//拉高3列的电平
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_SET);
- //遍历列
- for(uint8_t i=0;i<2;i++)
- {
- HAL_NVIC_DisableIRQ(EXTI0_1_IRQn);//关闭ROW1的中断
- switch(i){
- case 0:
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_RESET);//拉低列1
- if(HAL_GPIO_ReadPin(COL2) == 0)//读取键值
- ucKey_val = 2;
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_SET);//拉高列1
- break;
- case 1:
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_RESET);//拉低列2
- if(HAL_GPIO_ReadPin(COL2) == 0)//读取键值
- ucKey_val = 5;
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_SET);//拉高列2
- break;
- default:
- break;
- }
- }
- //拉低三列的电平
- HAL_GPIO_WritePin(ROW1,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(ROW2,GPIO_PIN_RESET);
- //打开ROW1中断
- HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
-
- return ucKey_val;
- }
-
- void lora_proc(void)
- {
- if(Tx_flag==1)
- {
- Tx_flag=0;
- Lora_Txbuff[0]='Z'; //数据校验
- Lora_Txbuff[1]=key1.B1;
- Lora_Txbuff[2]=key1.B2;
- Lora_Txbuff[3]=key1.B4;
- Lora_Txbuff[4]=key1.B5;
- Lora_Txbuff[5]='F';
- LORA_Tx(Lora_Txbuff,sizeof(Lora_Txbuff));
- //清空
- key1.B1=0;
- key1.B2=0;
- key1.B4=0;
- key1.B5=0;
- }
- if(LORA_Rx(Lora_Rxbuff)==6&&Lora_Rxbuff[0]=='Y')
- {
- show1.CV=(float)Lora_Rxbuff[1]/10;
- show1.PV=(float)Lora_Rxbuff[2]/10;
- show1.K1=Lora_Rxbuff[3];
- show1.K2=Lora_Rxbuff[4];
- show1.mode=Lora_Rxbuff[5];
- }
- }
-
- void oled_proc(void)
- {
-
- sprintf((char*)Strbuff," %.1fV - %.1fV ",show1.CV,show1.PV);
- OLED_ShowString(0,Strbuff);
- sprintf((char*)Strbuff," %d%d%d ",show1.K1,show1.K2,show1.mode);
- OLED_ShowString(2,Strbuff);
- }

- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "adc.h"
- #include "i2c.h"
- #include "spi.h"
- #include "tim.h"
- #include "gpio.h"
-
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include "stdio.h"
- #include "stdlib.h"
- #include "oled.h"
- #include "lora.h"
- /* USER CODE END Includes */
-
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
-
- /* USER CODE END PTD */
-
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
-
- /* USER CODE END PD */
-
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- void get_adc(void); //ADC采样控制
- void adc_Prog(void);
- void para_Prog(void);
- void relay_Prog(void);
- void show_Prog(void);
- void led_prog(void);
- void lora_Prog(void); //Lora通信设置
- /* USER CODE END PM */
-
- /* Private variables ---------------------------------------------------------*/
-
- /* USER CODE BEGIN PV */
- uint16_t Adc_val[2];
- struct Adc{
-
- uint16_t RP1; //RP1电压
- uint16_t RP2; //RP2电压
- uint16_t CV; //电压差
- uint16_t PV; //电压参数
- }val;
-
- struct time{
-
- uint16_t us; //定时微秒
- uint16_t ms; //定时毫秒
- uint16_t s; //定时器秒
- }time;
-
- uint8_t Lora_Txbuff[6];
- uint8_t Lora_Rxbuff[7];
- uint8_t Strbuff[17]; //OLED显示字符串
- uint8_t dis_Mode; //模式切换标志位
- uint8_t work_Mode; //模式选择
- uint8_t adc_flag; //ADC采样控制
- uint8_t tx_flag;
- /* USER CODE END PV */
-
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- /* USER CODE BEGIN PFP */
-
- /* 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_ADC_Init();
- MX_I2C3_Init();
- MX_TIM2_Init();
- MX_SPI1_Init();
- /* USER CODE BEGIN 2 */
- OLED_Init();
- LORA_Init(); //lora初始化
- HAL_TIM_Base_Start_IT(&htim2); //打开定时器2
- dis_Mode=0;
- work_Mode=0;
- val.PV=10;
- adc_flag=1;
- tx_flag=0;
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
- led_prog();
- show_Prog();
- relay_Prog();
- lora_Prog();
- }
- /* USER CODE END 3 */
- }
-
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
-
- /** Configure the main internal regulator output voltage
- */
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
-
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_3;
- RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
- 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_DIV1;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
- {
- Error_Handler();
- }
- PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C3;
- PeriphClkInit.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
- {
- Error_Handler();
- }
- }
-
- /* USER CODE BEGIN 4 */
- /*外部中断*/
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
- if(HAL_GPIO_ReadPin(USER)==0)
- if(++dis_Mode==2)
- dis_Mode=0;
- }
- /*定时器中断*/
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if(++time.ms==99)
- {
- time.ms=0;
- adc_flag=1;
- }
-
- }
- void get_adc(void)
- {
- HAL_ADC_Start(&hadc);
- if(HAL_ADC_PollForConversion(&hadc,10)==HAL_OK)
- Adc_val[0]=HAL_ADC_GetValue(&hadc);
- if(HAL_ADC_PollForConversion(&hadc,10)==HAL_OK)
- Adc_val[1]=HAL_ADC_GetValue(&hadc);
- val.RP1=(int)(Adc_val[1]*3.3/4095*10);
- val.RP2=(int)(Adc_val[0]*3.3/4095*10);
- }
- /*ADC显示程序*/
- void adc_Prog(void)
- {
- sprintf((char*)Strbuff," RP1:%.1fV ",(float)val.RP1/10);
- OLED_ShowString(0,Strbuff);
- sprintf((char*)Strbuff," RP2:%.1fV ",(float)val.RP2/10);
- OLED_ShowString(2,Strbuff);
- }
- void para_Prog(void)
- {
- sprintf((char*)Strbuff," CV:%.1fV ",(float)val.CV/10);
- OLED_ShowString(0,Strbuff);
- sprintf((char*)Strbuff," PV:%.1fV ",(float)val.PV/10);
- OLED_ShowString(2,Strbuff);
- }
- void relay_Prog(void)
- {
- if(work_Mode==0)
- {
- if(val.CV>val.PV)
- {
- HAL_GPIO_WritePin(Relay1,OFF);
- HAL_GPIO_WritePin(Relay2,ON);
- }
- else
- {
- HAL_GPIO_WritePin(Relay1,ON);
- HAL_GPIO_WritePin(Relay2,OFF);
- }
- }
- }
-
- /*OLED显示*/
- void show_Prog(void)
- {
- if(adc_flag==1)
- {
- get_adc();
- adc_flag=0;
- val.CV=abs(val.RP1-val.RP2);
- }
- if(dis_Mode==0)
- adc_Prog();
- else
- para_Prog();
- }
- /*LED指示灯*/
- void led_prog(void)
- {
- if(work_Mode==0)
- HAL_GPIO_WritePin(LD5,OFF);
- else
- HAL_GPIO_WritePin(LD5,ON);
- }
- void lora_Prog(void)
- {
- if(tx_flag==1)
- {
- tx_flag=0;
- Lora_Txbuff[0]='Y'; //数据校验
- Lora_Txbuff[1]=(int)(val.CV);
- Lora_Txbuff[2]=(int)(val.PV);
- Lora_Txbuff[3]=Read(Relay1);
- Lora_Txbuff[4]=Read(Relay2);
- Lora_Txbuff[5]=work_Mode;
- LORA_Tx(Lora_Txbuff,sizeof(Lora_Txbuff));
- }
- if(LORA_Rx(Lora_Rxbuff)==6&&Lora_Rxbuff[0]=='Z'&&Lora_Rxbuff[5]=='F')
- {
- if(Lora_Rxbuff[1]==1)
- {
- if(++work_Mode==2)
- work_Mode=0;
- }
- if(Lora_Rxbuff[2]==1)
- {
- tx_flag=1;
- }
- if(Lora_Rxbuff[3]==1)
- {
- switch(work_Mode)
- {
- case 0:
- val.PV+=1;
- break;
- case 1:
- HAL_GPIO_TogglePin(Relay1);
- break;
- default:
- break;
- }
- }
- if(Lora_Rxbuff[4]==1)
- {
- switch(work_Mode)
- {
- case 0:
- val.PV-=1;
- break;
- case 1:
- HAL_GPIO_TogglePin(Relay2);
- break;
- default:
- break;
- }
- }
- }
- }
- /* USER CODE END 4 */

效果还没拍视频,后期再补上
这是本人第一次写这么多内容的blog,还有本人语文素养比较低。可能有些措辞不当或者语句不通顺的地方,希望能够指正。
代码总体来说的话,大部分是自己编写的,有一部分是借鉴网上的大佬的代码。由于本人C语言功底比较薄弱,所以有些语法写的很笨。或许有更好更高效的方法,也希望能给我指出一些建议。
第四次参加蓝桥杯了,之前参加的是单片机和嵌入式组。今年是第一次参加物联网,也是最后一次参加蓝桥杯了。赛前没有很好的准备,赛场上只完成了部分功能,赛后经过不断完善,基本上将所有功能都实现了。虽然没有在赛场上完成全部功能,但是赛后能把所有功能都实现,也算是不给自己留下太多遗憾了。
夸克网盘:链接:https://pan.quark.cn/s/6e1ee164fceb 提取码:sdSs
百度网盘:链接:https://pan.baidu.com/s/16Qw5IuQn-rivRKj6Fb_RAg?pwd=h8tu 提取码:h8tu
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。