单片机学习小组
直播中

梁宏满

7年用户 970经验值
私信 关注

如何利用4G DTU终端去实现串口中断的收发模式呢

如何利用4G DTU终端去实现串口中断的收发模式呢?有哪些操作步骤呢?

回帖(1)

高颖

2022-1-17 15:07:18
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++] = '';        //在数组最后添加,这样可以截断字符串
                                printf("usart1Info.rxBuf:%srn",usart1Info.rxBuf);                //打印字符串
                                usart1Info.InfBit.finishFlag = REC_WAIT;                                //将标志位设置成等待接收状态
                                usart1Info.InfBit.dataLen = 0;                                                        //将接收的数据长度设置为0
                }


  }
  /* USER CODE END 3 */




编译工程


4、配置烧录器




5、烧录代码


6、实验现象

举报

更多回帖

发帖
×
20
完善资料,
赚取积分