搜索
查看: 7362|回复: 6

[Lora] 【LoRa模块_E32-TTL-100】+节点端代码实现

[复制链接]

该用户从未签到

32

主题

1829

帖子

177

蝴蝶豆

论坛元老

最后登录
2021-5-11
发表于 2018-4-22 12:48:13 | 显示全部楼层 |阅读模式
本帖最后由 Angel_YY 于 2018-4-22 12:47 编辑

上一篇 【LoRa模块_E32-TTL-100】+PC端代码实现
在上一篇,PC端代码实现之后,今天来实现节点端代码。
0001.jpg
如图所示,节点端使用了STM32F031 Nucleo开发板,通过串口外接LoRa模块E32-TTL-100,此外连接了光照强度传感器,温湿度传感器DHT11。
0002.png
STM32F031的开发板原理图如上图所示。其中PA9~PA12连接了LoRa模块,PB5~PB7连接DHT11,PB0连接光照传感器,PA3、PA4连接两路继电器。
0005.png
在STM32CubeMX中进行管脚配置。
0004.png
生成工程后,使用IAR开始编写代码。
其中主要代码文件main.c的内容如下:

  1. /**
  2.   ******************************************************************************
  3.   * @file           : main.c
  4.   * @brief          : Main program body
  5.   ******************************************************************************
  6.   ** This notice applies to any and all portions of this file
  7.   * that are not between comment pairs USER CODE BEGIN and
  8.   * USER CODE END. Other portions of this file, whether
  9.   * inserted by the user or by software development tools
  10.   * are owned by their respective copyright owners.
  11.   *
  12.   * COPYRIGHT(c) 2018 STMicroelectronics
  13.   *
  14.   * Redistribution and use in source and binary forms, with or without modification,
  15.   * are permitted provided that the following conditions are met:
  16.   *   1. Redistributions of source code must retain the above copyright notice,
  17.   *      this list of conditions and the following disclaimer.
  18.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  19.   *      this list of conditions and the following disclaimer in the documentation
  20.   *      and/or other materials provided with the distribution.
  21.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  22.   *      may be used to endorse or promote products derived from this software
  23.   *      without specific prior written permission.
  24.   *
  25.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  29.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  31.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  32.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  33.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35.   *
  36.   ******************************************************************************
  37.   */
  38. /* Includes ------------------------------------------------------------------*/
  39. #include "main.h"
  40. #include "stm32f0xx_hal.h"
  41. #include "adc.h"
  42. #include "tim.h"
  43. #include "usart.h"
  44. #include "gpio.h"

  45. /* USER CODE BEGIN Includes */
  46. #include "hal_temp_hum.h"
  47. /* USER CODE END Includes */

  48. /* Private variables ---------------------------------------------------------*/

  49. /* USER CODE BEGIN PV */
  50. /* Private variables ---------------------------------------------------------*/
  51. //定义继电器状态变量
  52. uint8_t ucWindRelayStat=0;   //设置通风继电器默认为关闭
  53. uint8_t ucWarmRelayStat=0;   //设置加温继电器默认为关闭
  54. uint8_t ucTemperature=0;     //温度
  55. uint8_t ucHumidity=0;        //湿度
  56. uint8_t ucLightValue=0;      //光照
  57. uint16_t AD_Value = 0;
  58. // 定义接收和发送缓冲区
  59. uint8_t aRxBuffer[20];
  60. uint8_t aTxBuffer[20];

  61. /* USER CODE END PV */

  62. /* Private function prototypes -----------------------------------------------*/
  63. void SystemClock_Config(void);

  64. /* USER CODE BEGIN PFP */
  65. /* Private function prototypes -----------------------------------------------*/

  66. /* USER CODE END PFP */

  67. /* USER CODE BEGIN 0 */

  68. /* USER CODE END 0 */

  69. /**
  70.   * @brief  The application entry point.
  71.   *
  72.   * @retval None
  73.   */
  74. int main(void)
  75. {
  76.   /* USER CODE BEGIN 1 */

  77.   /* USER CODE END 1 */

  78.   /* MCU Configuration----------------------------------------------------------*/

  79.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  80.   HAL_Init();

  81.   /* USER CODE BEGIN Init */

  82.   /* USER CODE END Init */

  83.   /* Configure the system clock */
  84.   SystemClock_Config();

  85.   /* USER CODE BEGIN SysInit */

  86.   /* USER CODE END SysInit */

  87.   /* Initialize all configured peripherals */
  88.   MX_GPIO_Init();
  89.   MX_USART1_UART_Init();
  90.   MX_ADC_Init();
  91.   MX_TIM17_Init();
  92.   /* USER CODE BEGIN 2 */
  93.   //初始化E32的M0和M1,进入透传模式
  94.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11,GPIO_PIN_RESET);//设置E32配置引脚为低电平
  95.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12,GPIO_PIN_RESET);//设置E32配置引脚为低电平
  96.   //初始化DHT11的电源和地引脚,因为开发板电源和地不够用,这里使用GPIO代替
  97.   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_SET);  //高电平给DHT11电源供电
  98.   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6,GPIO_PIN_RESET);//低电平接DHT11的GND
  99.   //初始化LED,默认熄灭
  100.   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3,GPIO_PIN_RESET);  //设置LED为高低平,熄灭LED
  101.   //初始化继电器,默认关闭
  102.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_RESET);
  103.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_RESET);
  104.   //延时200毫秒
  105.   HAL_Delay(200);
  106.   //初始化DHT11
  107.   DHT11_Init();
  108.   
  109. // 开启串口接收中断
  110.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 5);
  111.   /* USER CODE END 2 */

  112.   /* Infinite loop */
  113.   /* USER CODE BEGIN WHILE */
  114.   while (1)
  115.   {
  116.   //获取温湿度
  117.   DHT11_Read_Data(&ucTemperature, &ucHumidity);
  118.   //获取光照强度
  119.   HAL_ADC_Start(&hadc);//启动ADC装换
  120.   HAL_ADC_PollForConversion(&hadc, 500);//等待转换完成,第二个参数表示超时时间,单位ms.
  121.   if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))//判断转换完成标志位是否设置
  122.   {
  123.     AD_Value = HAL_ADC_GetValue(&hadc);//读取ADC转换数据,数据为12位右对齐,范围为0~2^12-1,即0~4095.
  124.     ucLightValue=(uint8_t)(AD_Value>>4);//降低精度为8bit,数据范围0-255.
  125.   }
  126.   //组织要发送的串口数据
  127.   aTxBuffer[0]=0x55;//目标地址高字节
  128.   aTxBuffer[1]=0xaa;//目标地址低字节
  129.   aTxBuffer[2]=0x17;//目标信道
  130.   aTxBuffer[3]=0x01;//节点号
  131.   aTxBuffer[4]=0x01;//网关号
  132.   aTxBuffer[5]=ucTemperature;//温度
  133.   aTxBuffer[6]=ucHumidity;//湿度
  134.   aTxBuffer[7]=ucLightValue;//光照强度
  135.   aTxBuffer[8]=0x00;//通风继电器和加热继电器状态清零
  136.   aTxBuffer[9]=0x0d;//回车
  137.   aTxBuffer[10]=0x0a;//换行
  138.   
  139.   //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3,GPIO_PIN_RESET);//LED灯关闭,只要有一个继电器打开,LED就会亮
  140.   //设置继电器状态
  141.   if(ucWindRelayStat>0)//如果通风继电器要求打开
  142.   {
  143.     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_SET);
  144.     //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3,GPIO_PIN_SET);//led显示继电器状态
  145.     aTxBuffer[8]|=0x01;  //设置通风继电器状态
  146.   }else{
  147.     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_RESET);
  148.   }
  149.   if(ucWarmRelayStat>0)//如果加热继电器要求打开
  150.   {
  151.     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_SET);
  152.     //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3,GPIO_PIN_SET);//led显示继电器状态
  153.     aTxBuffer[8]|=0x02;//设置加热继电器状态
  154.   }else{
  155.     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_RESET);
  156.   }
  157.   //串口发送数据
  158.   HAL_UART_Transmit(&huart1, (uint8_t *)aTxBuffer, 11,0xFFFF);
  159.   HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
  160.   //延时1秒
  161.   HAL_Delay(1000);
  162.   /* USER CODE END WHILE */

  163.   /* USER CODE BEGIN 3 */

  164.   }
  165.   /* USER CODE END 3 */

  166. }

  167. /**
  168.   * @brief System Clock Configuration
  169.   * @retval None
  170.   */
  171. void SystemClock_Config(void)
  172. {

  173.   RCC_OscInitTypeDef RCC_OscInitStruct;
  174.   RCC_ClkInitTypeDef RCC_ClkInitStruct;
  175.   RCC_PeriphCLKInitTypeDef PeriphClkInit;

  176.     /**Initializes the CPU, AHB and APB busses clocks
  177.     */
  178.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSI14;
  179.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  180.   RCC_OscInitStruct.HSI14State = RCC_HSI14_ON;
  181.   RCC_OscInitStruct.HSICalibrationValue = 16;
  182.   RCC_OscInitStruct.HSI14CalibrationValue = 16;
  183.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  184.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  185.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  186.   RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
  187.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  188.   {
  189.     _Error_Handler(__FILE__, __LINE__);
  190.   }

  191.     /**Initializes the CPU, AHB and APB busses clocks
  192.     */
  193.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  194.                               |RCC_CLOCKTYPE_PCLK1;
  195.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  196.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  197.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  198.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  199.   {
  200.     _Error_Handler(__FILE__, __LINE__);
  201.   }

  202.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  203.   PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
  204.   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  205.   {
  206.     _Error_Handler(__FILE__, __LINE__);
  207.   }

  208.     /**Configure the Systick interrupt time
  209.     */
  210.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  211.     /**Configure the Systick
  212.     */
  213.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  214.   /* SysTick_IRQn interrupt configuration */
  215.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  216. }

  217. /* USER CODE BEGIN 4 */
  218. // 实现串口中断回调函数
  219. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  220. {
  221.   /* Prevent unused argument(s) compilation warning */
  222.   UNUSED(huart);
  223.   // 功能代码,串口接收到数据后判断并设置继电器标记变量。
  224.   if((aRxBuffer[0]==0x01)&&(aRxBuffer[1]==0x01))//如果网关和节点地址正确
  225.   {
  226.     if((aRxBuffer[2]&0x01)>0)//如果通风继电器要求打开
  227.     {
  228.       ucWindRelayStat=1;
  229.     }else{
  230.       ucWindRelayStat=0;
  231.     }
  232.     if((aRxBuffer[2]&0x02)>0)//如果加热继电器要求打开
  233.     {
  234.       ucWarmRelayStat=1;
  235.     }else{
  236.       ucWarmRelayStat=0;
  237.     }
  238.   }
  239.   //开启下一次中断
  240.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 5);
  241. }
  242. /* USER CODE END 4 */

  243. /**
  244.   * @brief  This function is executed in case of error occurrence.
  245.   * @param  file: The file name as string.
  246.   * @param  line: The line in file as a number.
  247.   * @retval None
  248.   */
  249. void _Error_Handler(char *file, int line)
  250. {
  251.   /* USER CODE BEGIN Error_Handler_Debug */
  252.   /* User can add his own implementation to report the HAL error return state */
  253.   while(1)
  254.   {
  255.   }
  256.   /* USER CODE END Error_Handler_Debug */
  257. }

  258. #ifdef  USE_FULL_ASSERT
  259. /**
  260.   * @brief  Reports the name of the source file and the source line number
  261.   *         where the assert_param error has occurred.
  262.   * @param  file: pointer to the source file name
  263.   * @param  line: assert_param error line source number
  264.   * @retval None
  265.   */
  266. void assert_failed(uint8_t* file, uint32_t line)
  267. {
  268.   /* USER CODE BEGIN 6 */
  269.   /* User can add his own implementation to report the file name and line number,
  270.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  271.   /* USER CODE END 6 */
  272. }
  273. #endif /* USE_FULL_ASSERT */

  274. /**
  275.   * @}
  276.   */

  277. /**
  278.   * @}
  279.   */

  280. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码
代码中都做了详细的中文注释,这里不用在解释了。
通过测试,在节点端每隔一秒发送一次数据,在PC端接收数据后可以发送控制数据到节点端对节点继电器进行控制。节点端每发送一次数据LED灯点亮或者熄灭一次,同时在PC端代码同样是接收到节点端数据后会点亮或者熄灭一次LED灯进行提示。至此基于LoRa模块E32_TTL_100的智能农业蔬菜大棚监控系统的嵌入式代码部分的核心代码算是完成了,当然目前的代码只是实现了基本功能,距离商业化的产品还有很大差距。后期会持续跟踪需求进一步完善,朝着真正的产品持续演进。最后再次感谢社区,感谢破总给予这次LoRa模块的试用机会。         

PS:本来计划做一个数据传输距离测试的,可是之前开发都是在电脑上使用USB数据线连接两块开发板,均能正常发送接收,临出门进行测试换上了两个充电宝,发现两个开发板的代码都不能正常工作了(LED灯不再闪烁),开始以为是功率不足,换到手机充电器上试试依然不行,基本可以肯定是usb的D+和D-检测不到信号,导致开发板工作异常,换到一个笔记本上,没有安装ST的驱动,发现依然无法工作,安装驱动后发现了虚拟串口,此时开发板就能正常工作了,所以判定STlink部分的代码会判断USB通讯正常,才会给STM32F031部分进行供电。于是自己把一颗USB线剪断,接了电源线直接到Nucleo外接Pin的电源管脚Vin和GND,Nucleo正常工作了。但是PC端的STM32F103最小系统板还是不能使用充电宝,我在找找原因,近期如果能解决,再补一个传输距离的测试。

节点端代码: LoRaNode.zip (14.51 MB, 下载次数: 280)
回复

使用道具 举报

该用户从未签到

0

主题

4

帖子

0

蝴蝶豆

初级会员

最后登录
2018-6-25
发表于 2018-6-25 14:43:12 | 显示全部楼层
这一节的节点实现和前面pc端代码实现那一节一样e32都是定点模式吗?
回复 支持 反对

使用道具 举报

该用户从未签到

32

主题

1829

帖子

177

蝴蝶豆

论坛元老

最后登录
2021-5-11
 楼主| 发表于 2018-6-25 15:17:05 | 显示全部楼层
cccjr 发表于 2018-6-25 14:43
这一节的节点实现和前面pc端代码实现那一节一样e32都是定点模式吗?

是的,两者配套点对点传输。
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

2

帖子

0

蝴蝶豆

新手上路

最后登录
2019-11-9
发表于 2019-11-9 12:25:06 | 显示全部楼层
感谢分享!
回复

使用道具 举报

该用户从未签到

12

主题

1392

帖子

45

蝴蝶豆

金牌会员

最后登录
2021-8-25
发表于 2020-4-15 10:51:02 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

该用户从未签到

0

主题

364

帖子

0

蝴蝶豆

金牌会员

最后登录
2023-2-14
发表于 2020-4-27 12:25:12 | 显示全部楼层
谢谢分享
回复

使用道具 举报

该用户从未签到

0

主题

7

帖子

0

蝴蝶豆

新手上路

最后登录
2020-9-18
发表于 2020-9-18 16:19:11 | 显示全部楼层
感谢楼主分享,收藏了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-20 03:31 , Processed in 1.192986 second(s), 43 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表