基于STM32的蓝牙物联网节点设计

基于STM32的蓝牙物联网节点设计

  • 1.前言
  • 2.过程记录
    • 2.1 电路板设计
    • 2.2 程序设计
  • 结束语

1.前言

大三上学期我们就要做课程设计了,之前的学长学姐都是十个人一组,到我们老师觉得十个人太水就把我们弄成了三人一组,然后让我们用一个多月的时间去做物联网节点设计。
开始后一两天就给我们每组发了开发板,一款是普中的51单片机开发板,一款是正点原子的潘多拉开发板,然后就让我们自己选题开工了。我之前学STM32的时候买了几个核心板、蓝牙模块和TFT屏幕,然后就打算用手上有的东西区实现了。
程序写到一半,我们又去问了老师几个问题,老师跟我们讲说还要自己做电路设计,最少要有焊接过程,正好之前我还有PCB设计的一些经验,虽然不是很会,但当时觉得做一个这样的小板子应该不成问题。
最后就开始动手了。
Github地址:https://github.com/sin1111yi/STM32F1-HC05-board

2.过程记录

2.1 电路板设计

之前学STM32的时候,用的是野火的F103指南者开发板,又买了几个C8T6和RCT6的开发板。最初学STM32的动力也是在B站上看到别人的一个视频,自己做了双模的蓝牙键盘,当时觉得有点意思也想自己试试,然后就开始学这个了。

2.1.1 原理图设计

原理图做了好多参照(复制) ,最后得到了缝合怪开发板。因为是基于蓝牙的节点设计,所以选择直接板载蓝牙模块,然后就去参照了正点原子ATK-HC05的原理图。
基于STM32的蓝牙物联网节点设计_第1张图片
把这个集成到电路板上就可以让老师比较信服这个是我们自己做的,因为当时板子做出来老师也对这个板子的来源有一点怀疑,当然最终还是相信了。

最后剩下的就是把别人的原理图照着画一遍,得到最终的原理图。
基于STM32的蓝牙物联网节点设计_第2张图片
2.1.2 PCB设计

原理图用立创EDA画出来,然后用AutoCAD做了一个边框,EDA转换成PCB后导入边框层,最后排原件走线。唯一要注意的就是蓝牙模块天线要放在边缘,并且下面不要敷铜。
基于STM32的蓝牙物联网节点设计_第3张图片
基于STM32的蓝牙物联网节点设计_第4张图片
PCB就这样画好了,然后当然就是薅羊毛5元打样然后做SMT,做SMT的时候有的元件没有的话也只能自己买回来焊接。

成品做出来后就开始烧程序,最初上电的时候看上去都没有问题,蓝牙模块也正常运行了起来了,但是烧程序就执行不了,一直卡在HardFault_Handler()。做了一天debug,最后发现是BOOT0没有拉低,抱着死马当活马医的心态换了把它换成了磁珠,结果就好了。

实际上Type-C接口也是不能用的,所以我也没有去测试CH340部分能不能使用。
基于STM32的蓝牙物联网节点设计_第5张图片
最终成品就是这样,也就是它陪着我走完了课程设计的这段路,也许下个学期还会继续用它。

2.2 程序设计

整个任务之前也说了是由三个人一起完成,我负责这个节点,其他两个人各负责一个节点,他们两个用学校发的51单片机开发板,我用上面做的这个板子。

设计上,我们打算做的是智能家居系统,本来的设想很宏大,结果实现起来都是在下位机出了问题,最后只能一直缩减,最后完全按照计划做出来的也只有上位机。

程序流程直接贴一个图
基于STM32的蓝牙物联网节点设计_第6张图片
最后看指导书要求还能统计网络流量,就用TIM2做了一个定时,然后收发数据包都计数,两秒算一次就能得到网络内的数据流量。

代码上串口通信用了USART1和USART2,直接移植了野火的代码。滴答定时器也是移植,TFT显示也是移植,自己只写了几个函数让它可以做到自动换行和半屏清空,用来做分开显示。

main.c

#include 
#include 
#include "HC_05.h"
#include "Host_usart.h"
#include "TFT_LCD.h"
#include "RGB.h"
#include "General_TIM.h"

/**
 * @author sin1111yi
 * @date 2020/12/19
 * @brief now it can use usart2(PA2, PA3) to send or receive data 
 *      change _MODE_ to change start mode
*/

#define _MODE_ 1 // 0-Quick Start  1-Normal Start

#if _USE_HOST_USART_1_
extern volatile uint8_t StrLen1;
extern volatile uint8_t USART1_RECV_END_FLAG;
#endif

#if _USE_HOST_USART_2_
extern volatile uint8_t StrLen1;
extern volatile uint8_t USART2_RECV_END_FLAG;
#endif

extern volatile uint32_t Real_T;
extern volatile uint8_t flag;
uint32_t TIM2_Time = 0;

//Used in Monitor_Init() and stm32f10x_it.c
uint32_t SendPack = 0;
uint32_t RecvPack = 0;
uint32_t SendBits = 0;
uint32_t RecvBits = 0;
char SendMonitor[8] = {0};
char RecvMonitor[8] = {0};

uint16_t i = 0, j = 0, k = 0;

void System_StartUp(void);
void Monitor_Init(void);
void DataTraf_Display(void);

#if _USE_HOST_USART_1_
void USART1_Loop(void);
void USART1_Wait(void);
#endif

#if _USE_HOST_USART_2_
void USART2_Loop(void);
void USART2_Wait(void);
#endif

int main()
{
    System_StartUp();
    Monitor_Init();
    GENERAL_TIM_Init();

    while (1)
    {
        DataTraf_Display();

#if _USE_HOST_USART_1_
        USART1_Loop();
        SysTick_DelaySyncUs(200);
#endif

#if _USE_HOST_USART_2_
        USART2_Loop();
#endif
        SysTick_DelaySync(200);
        LCD_Clear(WHITE);
    }
}

void System_StartUp()
{
    LCD_Init();
    LED_Init();
    HOST_Usart_Config();
    LED_Red(On);

#if _USE_HOST_USART_1_
    memset(USART1_DataBuff, 0, 128 * sizeof(char));
    memset(USART1_RecvBuff, 0, 128 * sizeof(char));
    memset(USART1_SendBuff, 0, 128 * sizeof(char));
#endif

#if _USE_HOST_USART_2_
    memset(USART2_DataBuff, 0, 128 * sizeof(char));
    memset(USART2_RecvBuff, 0, 128 * sizeof(char));
    memset(USART2_SendBuff, 0, 128 * sizeof(char));
#endif

#if _MODE_
    LCD_Clear(WHITE);
    SysTick_DelaySyncUs(50);
    LCD_Clear(RED);
    SysTick_DelaySyncUs(50);
    LCD_Clear(GREEN);
    SysTick_DelaySyncUs(50);
    LCD_Clear(BLUE);
    SysTick_DelaySyncUs(50);
    LCD_Clear(BLACK);

    LCD_Clear(WHITE);
    LCD_Showimage(18, 10, 89, 89, gImage_ZMYsWork);
    LCD_CharsDisaplay(30, 105, GRAY1, WHITE, "By 969Yay");
    SysTick_DelaySync(500);
    LCD_Clear(YELLOW);

    LCD_CharsDisaplay(28, 58, YELLOW, GREEN, "CQUPT2020");
    SysTick_DelaySync(1000);
    LCD_Clear(GRAY2);

    LCD_CharsDisaplay(10, 10, WHITE, GRAY2, "MADE BY:");
    LCD_CharsDisaplay(10, 40, WHITE, GRAY2, "Member 1");
    LCD_CharsDisaplay(10, 70, WHITE, GRAY2, "Member 2");
    LCD_CharsDisaplay(10, 100, WHITE, GRAY2, "Member 3");
    SysTick_DelaySync(1000);
    LCD_Clear(BLACK);

#endif

#if !_MODE_
    LCD_Clear(BLACK);
    SysTick_DelaySync(500);
    LCD_CharsDisaplay(18, 56, RED, BLACK, "Quick Start!");
    SysTick_DelaySync(1000);
#endif
    LCD_Clear(WHITE);
    LED_Red(Off);
}

void Monitor_Init(void)
{
    SendPack = 0;
    RecvPack = 0;
    SendBits = 0;
    RecvBits = 0;

    SendMonitor[4] = 'B';
    SendMonitor[5] = '/';
    SendMonitor[6] = 's';

    RecvMonitor[4] = 'B';
    RecvMonitor[5] = '/';
    RecvMonitor[6] = 's';
}

void DataTraf_Display(void)
{
    LCD_CharsDisaplay(4, 4, RED, WHITE, "SEND: ");
    LCD_CharsDisaplay(50, 4, BLACK, WHITE, SendMonitor);
    LCD_CharsDisaplay(4, 108, RED, WHITE, "RECV: ");
    LCD_CharsDisaplay(50, 108, BLACK, WHITE, RecvMonitor);
}

#if _USE_HOST_USART_1_
void USART1_Loop(void)
{
    HOST_UsartSendByte(HOST_USART1, HC05_HOSTCmds[2]);
    SendPack++;

    if (USART1_RECV_END_FLAG == 1)
    {
        LED_Green(On);
        SysTick_DelaySyncUs(100);
        USART1_RECV_END_FLAG = 0;
        HOST_UsartSendString(HOST_USART1, USART1_RecvBuff);

        if (flag)
        {
            LCD_HalfClear(RED, 0);
            LED_Red_On;
            LCD_CharsDisaplay(16, 30, WHITE, RED, "WARNING :");
            LCD_DisplayOneChar(80, 30, WHITE, RED, USART1_RecvBuff[0]);
            LCD_DisplayOneChar(88, 30, WHITE, RED, USART1_RecvBuff[1]);
            LCD_DisplayOneChar(96, 30, WHITE, RED, USART1_RecvBuff[2]);
        }
        else
        {
            LED_Red_Off;
            LCD_CharsDisaplay(4, 30, BLACK, WHITE, "Temperature:");
            All_LCD_CharsDisplay(8, 46, GREEN, WHITE, USART1_RecvBuff);
            memset(USART1_RecvBuff, 0, 128 * sizeof(char));
            SysTick_DelaySync(200);
            //LCD_HalfClear(WHITE, 0);
        }
        LED_Green(Off);
        return;
    }
    USART1_Wait();
    return;
}
void USART1_Wait()
{
    LCD_CharsDisaplay(8, 32, BLACK, WHITE, "Waiting");

    for (i = 0; i < 3; i++)
    {
        LCD_CharsDisaplay(64 + 8 * i, 32, BLACK, WHITE, ". ");
        if (USART1_RECV_END_FLAG == 1)
        {
            LCD_Clear(WHITE);
            return;
        }
        SysTick_DelaySync(300);
    }

    for (i = 0; i < 3; i++)
    {
        LCD_CharsDisaplay(88 - 8 * i, 32, BLACK, WHITE, "  ");
        if (USART1_RECV_END_FLAG == 1)
        {
            LCD_Clear(WHITE);
            return;
        }
        SysTick_DelaySync(300);
    }
}
#endif

#if _USE_HOST_USART_2_
void USART2_Loop(void)
{
    HOST_UsartSendByte(HOST_USART2, HC05_HOSTCmds[3]);
    SendPack++;

    if (USART2_RECV_END_FLAG == 1)
    {
        LED_Blue(On);
        SysTick_DelaySyncUs(100);
        USART2_RECV_END_FLAG = 0;
        HOST_UsartSendString(HOST_USART2, USART2_RecvBuff);

        LCD_CharsDisaplay(4, 70, BLACK, WHITE, "Illumination:");
        All_LCD_CharsDisplay(8, 86, BLUE, WHITE, USART2_RecvBuff);
        memset(USART2_RecvBuff, 0, 128 * sizeof(char));
        SysTick_DelaySyncUs(200);
        //LCD_HalfClear(WHITE, 1);
        LED_Blue(Off);
        return;
    }
    USART2_Wait();
    return;
}
void USART2_Wait()
{
    LCD_CharsDisaplay(8, 80, BLACK, WHITE, "Waiting");

    for (i = 0; i < 3; i++)
    {
        LCD_CharsDisaplay(64 + 8 * i, 80, BLACK, WHITE, ". ");
        if (USART2_RECV_END_FLAG == 1)
        {
            LCD_Clear(WHITE);
            return;
        }
        SysTick_DelaySync(300);
    }

    for (i = 0; i < 3; i++)
    {
        LCD_CharsDisaplay(88 - 8 * i, 80, BLACK, WHITE, "  ");
        if (USART2_RECV_END_FLAG == 1)
        {
            LCD_Clear(WHITE);
            return;
        }
        SysTick_DelaySync(300);
    }
}
#endif

stm32f10x_it.c

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "HC_05.h"
#include "Host_usart.h"
#include "RGB.h"
#include "TFT_LCD.h"
#include "General_TIM.h"
#include 
#include 

/* User Variable -------------------------------------------------------------*/
// HOST_USART1_IRQHandler()
volatile uint8_t StrLen1 = 0;
volatile uint8_t USART1_RECV_END_FLAG = 0;
// HOST_USART2_IRQHandler()
volatile uint8_t StrLen2 = 0;
volatile uint8_t USART2_RECV_END_FLAG = 0;
//for data processing
volatile uint32_t Real_T = 0;
volatile uint8_t flag = 0;
extern volatile uint32_t TIM2_Time; //TIM2
//Data traffic mointor
extern uint32_t SendPack;
extern uint32_t RecvPack;
extern uint32_t SendBits;
extern uint32_t RecvBits;
extern char SendMonitor[8];
extern char RecvMonitor[8];

#define Warning_T 295 //29.5 degree C

/** @addtogroup STM32F10x_StdPeriph_Template
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************/

/**
  * @brief  This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
void SVC_Handler(void)
{
}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}

/**
  * @brief  This function handles PendSVC exception.
  * @param  None
  * @retval None
  */
void PendSV_Handler(void)
{
}

/**
  * @brief  This function handles SysTick Handler.
  *         SysTick_Handler has already defined in "SysTick.h"
  * @param  None
  * @retval None
  */

/*
void SysTick_Handler(void)
{
}
*/

/**
 * @brief  Serial interrupt service function
 *         defined in "Host_usart.h"
 * @param  None
 * @retval None
*/
#if _USE_HOST_USART_1_

void HOST_USART1_IRQHandler()
{
  if (USART_GetFlagStatus(HOST_USART1, USART_IT_RXNE) == SET)
  {
    if (USART_ReceiveData(HOST_USART1) == '\n')
    {
      StrLen1 = 0;
      USART1_RECV_END_FLAG = 1;

      Real_T = ((uint32_t)USART1_RecvBuff[0] - '0') * 1000 +
               ((uint32_t)USART1_RecvBuff[1] - '0') * 100 +
               ((uint32_t)USART1_RecvBuff[2] - '0') * 10 +
               ((uint32_t)USART1_RecvBuff[4] - '0');
      if (Real_T >= Warning_T)
        flag = 1;
      else
        flag = 0;
      memset(USART1_DataBuff, 0, 128 * sizeof(char));
    }
    else
    {
      if (StrLen1 == 0)
        memset(USART1_RecvBuff, 0, 128 * sizeof(char));
      USART1_DataBuff[StrLen1] = USART_ReceiveData(HOST_USART1);
      USART1_RecvBuff[StrLen1] = USART1_DataBuff[StrLen1];
      StrLen1++;
    }

    RecvPack++;
  }
  if (USART_GetITStatus(HOST_USART1, USART_IT_RXNE) != RESET)
    USART_ClearITPendingBit(HOST_USART1, USART_IT_RXNE);
}

#endif

#if _USE_HOST_USART_2_

void HOST_USART2_IRQHandler()
{
  if (USART_GetFlagStatus(HOST_USART2, USART_IT_RXNE) == SET)
  {
    if (USART_ReceiveData(HOST_USART2) == '\n')
    {
      StrLen2 = 0;
      USART2_RECV_END_FLAG = 1;
      memset(USART2_DataBuff, 0, 128 * sizeof(char));
    }
    else
    {
      if (StrLen2 == 0)
        memset(USART2_RecvBuff, 0, 128 * sizeof(char));
      USART2_DataBuff[StrLen2] = USART_ReceiveData(HOST_USART2);
      USART2_RecvBuff[StrLen2] = USART2_DataBuff[StrLen2];
      StrLen2++;
    }

    RecvPack++;
  }
  if (USART_GetITStatus(HOST_USART2, USART_IT_RXNE) != RESET)
    USART_ClearITPendingBit(HOST_USART2, USART_IT_RXNE);
}

#endif

void GENERAL_TIM_IRQHandler(void)
{
  if (TIM_GetITStatus(GENERAL_TIM, TIM_IT_Update) != RESET)
  {
    TIM2_Time++;
    if (TIM2_Time == 2000)
    {
      TIM2_Time = 0;
      SendBits = SendPack * 8 / 2;
      RecvBits = RecvPack * 8 / 2;

      SendMonitor[0] = SendBits / 1000 + '0';
      SendMonitor[1] = (SendBits % 1000) / 100 + '0';
      SendMonitor[2] = (SendBits % 100) / 10 + '0';
      SendMonitor[3] = SendBits % 10 + '0';

      RecvMonitor[0] = RecvBits / 1000 + '0';
      RecvMonitor[1] = (RecvBits % 1000) / 100 + '0';
      RecvMonitor[2] = (RecvBits % 100) / 10 + '0';
      RecvMonitor[3] = RecvBits % 10 + '0';

      SendPack = 0;
      RecvPack = 0;
      SendBits = 0;
      RecvBits = 0;
    }
    TIM_ClearITPendingBit(GENERAL_TIM, TIM_FLAG_Update);
  }
}

/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************/

/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
/*void PPP_IRQHandler(void)
{
}*/

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

结束语

体验还行,找队友一定要靠谱,这次也多亏了队友靠谱才能顺利完成。

你可能感兴趣的:(单片机,stm32,c++,蓝牙,程序设计)