1、准备开发板
这里我选用了一块带以太网口插卡4G的DTU终端,可实现2G/3G/4G信号远距离数据透明传输通讯,以太网100Mbps有线传输通讯,通过工业RS232/485/422等接口直接连接设备进行无线远程传输。4G DTU在工业自动化上具有非常广泛的应用,而且具有传输数据量大,传输速度快,传输时延低,传输质量稳定的特点。弥补了NB模块传输速度慢、传输数据量少等缺点。尤其适合数据采集点分散、位置偏远、无人职守、有线通讯安装施工不便、成本高的行业,例如气象、环保、水利、电力、农业、交通、石油管线监控、城市管网监控、工业监控等,极大提高了数据通讯能力,节约人力物力成本,实现了数据通讯的跨越。
2、STM32CubeMX生成代码
搜索并选择芯片型号
配置系统时钟
配置Debug
配置串口
配置时钟树
STM32F103RE的最高主频可达到72M,最后使HCLK = 72Mhz即可:
生成工程设置
代码生成配置
生成代码
生成成功
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
USART_INFO_STRUCT usart1Info;
int fputc(int ch, FILE *stream)
{
/* 堵塞判断串口是否发送完成 */
while((USART1->ISR & 0X40) == 0);
/* 串口发送完成,将该字符发送 */
USART1->TDR = (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_UartDMAHandler(&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++] = '