1、准备开发板

这里我选用了一块带以太网口插卡4G的DTU终端,可实现2G/3G/4G信号远距离数据透明传输通讯,以太网100Mbps有线传输通讯,通过工业RS232/485/422等接口直接连接设备进行无线远程传输。4G DTU在工业自动化上具有非常广泛的应用,而且具有传输数据量大,传输速度快,传输时延低,传输质量稳定的特点。弥补了NB模块传输速度慢、传输数据量少等缺点。尤其适合数据采集点分散、位置偏远、无人职守、有线通讯安装施工不便、成本高的行业,例如气象、环保、水利、电力、农业、交通、石油管线监控、城市管网监控、工业监控等,极大提高了数据通讯能力,节约人力物力成本,实现了数据通讯的跨越。

android 4G优先以太网 4g和以太网_嵌入式


android 4G优先以太网 4g和以太网_物联网_02

2、STM32CubeMX生成代码

android 4G优先以太网 4g和以太网_单片机_03

搜索并选择芯片型号

android 4G优先以太网 4g和以太网_嵌入式_04

配置系统时钟

android 4G优先以太网 4g和以太网_单片机_05

配置Debug

android 4G优先以太网 4g和以太网_物联网_06

配置串口

android 4G优先以太网 4g和以太网_物联网_07

android 4G优先以太网 4g和以太网_物联网_08

配置时钟树

STM32F103RE的最高主频可达到72M,最后使HCLK = 72Mhz即可:

android 4G优先以太网 4g和以太网_物联网_09


android 4G优先以太网 4g和以太网_单片机_10

生成工程设置

android 4G优先以太网 4g和以太网_单片机_11

代码生成配置

android 4G优先以太网 4g和以太网_物联网_12

生成代码

android 4G优先以太网 4g和以太网_嵌入式_13

生成成功

android 4G优先以太网 4g和以太网_stm32_14

3、在MDK中编写代码

在usart.h下的用户代码区编写以下代码

/* USER CODE BEGIN Includes */
#if defined ( __CC_ARM  )
#pragma anon_unions
#endif
/* USER CODE END Includes */

/* USER CODE BEGIN Private defines */

#define RX_BUF_MAX_LEN 256		  //最大接收缓存字节数

typedef struct 
{
	
	unsigned short dataLenPre;		//上一次的长度数据,用于比较
	
	union{
		unsigned short InfAll;
		struct 
		{
			unsigned short dataLen : 15;			//接收数据长度
			unsigned short finishFlag : 1;		//接收完成标志
		}InfBit;
	};
	unsigned char rxBuf[RX_BUF_MAX_LEN];			//接收缓存

} USART_INFO_STRUCT;


#define REC_OK		1	//接收完成标志
#define REC_WAIT	0	//接收未完成标志

extern USART_INFO_STRUCT usart1Info;

/* USER CODE END Private defines */

/* USER CODE BEGIN Prototypes */

void USART_Interupt_Enable(void);
void USER_UartHandler(UART_HandleTypeDef* huart,USART_INFO_STRUCT* usartInfo);

/* USER CODE END Prototypes */

在usart.c中编写以下代码

/* USER CODE BEGIN 0 */

#include <stdio.h>

USART_INFO_STRUCT usart1Info;

int fputc(int ch, FILE *stream)
{
    /* 堵塞判断串口是否发送完成 */
    while((USART1->SR & 0X40) == 0);

    /* 串口发送完成,将该字符发送 */
    USART1->DR = (uint8_t) ch;

    return ch;
}

/* USER CODE END 0 */

/* USER CODE BEGIN 1 */

void USART_Interupt_Enable(void)
{

	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);                //空闲中断使能
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); 							//接收中断使能
	
}


void USER_UartHandler(UART_HandleTypeDef* huart,USART_INFO_STRUCT* usartInfo)
{
		unsigned char ucCh;

		if((__HAL_UART_GET_FLAG(huart,UART_FLAG_RXNE)!=RESET))
			{
				ucCh=(uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); 
				
				if(usartInfo->InfBit.dataLen >= sizeof(usartInfo->rxBuf))
				{			
					usartInfo->InfBit.dataLen = 0; //防止串口被刷爆
				}
				usartInfo->rxBuf[usartInfo->InfBit.dataLen++] = ucCh;
				__HAL_UART_CLEAR_FLAG(huart,UART_FLAG_RXNE); 
			}
		if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)!=RESET))//进入空闲中断
			{ 
				usartInfo->InfBit.finishFlag = REC_OK;
				ucCh = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); 
			}
}


/* USER CODE END 1 */

在stm32f1xx_it.c中的USART1_IRQHandler函数的用户代码区编写以下代码

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
  USER_UartHandler(&huart1,&usart1Info);	//用户中断代码
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

在main.c下的main函数下的用户代码区编写以下代码

/* USER CODE BEGIN 2 */
  USART_Interupt_Enable();	//使能串口接收中断和空闲中断
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	 if(usart1Info.InfBit.finishFlag == REC_OK)		//如果接收成功
		{
				usart1Info.rxBuf[usart1Info.InfBit.dataLen++] = '\0';	//在数组最后添加\0,这样可以截断字符串
				printf("usart1Info.rxBuf:%s\r\n",usart1Info.rxBuf);		//打印字符串
				usart1Info.InfBit.finishFlag = REC_WAIT;				//将标志位设置成等待接收状态
				usart1Info.InfBit.dataLen = 0;							//将接收的数据长度设置为0
		}

  }
  /* USER CODE END 3 */

编译工程

android 4G优先以太网 4g和以太网_物联网_15

4、配置烧录器

android 4G优先以太网 4g和以太网_stm32_16

android 4G优先以太网 4g和以太网_单片机_17


android 4G优先以太网 4g和以太网_android 4G优先以太网_18

5、烧录代码

android 4G优先以太网 4g和以太网_stm32_19

6、实验现象

android 4G优先以太网 4g和以太网_android 4G优先以太网_20