我是靠谱客的博主 震动帆布鞋,最近开发中收集的这篇文章主要介绍解决了一次模块间TTL串口不能通讯的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

公司的产品嵌入式主机要更换短信模块,临时搞一台。
老模块原来直接做在板子上,这次生产后,同事将老模块吹下来了。

新短信模块是个小模块产品,同事将壳子拆掉,将产品板子塞进主机箱。
新短信模块原来是RS232通讯,过的SP3232, 走的DB9串口。
同事将SP3232拆掉,将短信模块从模组出来的TTL的串口收发和主机箱中MCU的TTL收发连在一起。
用2根排线连接的。

2个板子之间的收发为 A-TX => B-RX, A-RX => B-TX.
2个板子通过供电(220V=>12V开关电源)的GND相连通,用万用表的通断档量过,确实是通的。

看起来没啥问题。
准备写段程序,将老短信模块操作换成新短信模块操作,看起来很容易啊:)

最开始在产品程序上找到发短信的函数,就替换这个函数就行。
结果发串口包后,收不到短信模块的串口回包。这…

我生产的同事从来就没错过。我就在折腾程序,一定是我写错了。
查来查去也看不出错在哪里…
正好下班了,准备申请封闭一天,看看这2个模块之间不能通讯的问题出在哪里。

试验

写专门的测试工程

因为产品程序我只是维护者,没准哪里我没搞对。
先写个HAL库程序试试。
MCU是STM32F103VET6, 就将RCC, SYS, UART4留出来,生成框架程序。然后将收发测试代码写上,看看疗效。
不行啊,没反应,始终没串口回包。

将同事在2个模块之间的排线从中间剪断。

单独测试MCU的TTL串口

因为同事就接了2根通讯线(TX/RX), 我从MCU所在的板子上找到一个GND, 又接出一根线。
查了下淘宝,买过好几个TTL转USB串口的通讯模块。翻了几个零件箱,就找到一个。
将TTL转串口模块和MCU所在模块用3根线连在一起(A-RX => B-TX, A-TX => B-RX, A-GND => B-GND )
刚才写的HAL库测试程序已经在MCU里面,将TTL转串口模块接在本本的USB口。在本本上运行串口助手,按照16进制显示,可以看到MCU发来的内容。用串口助手循环发送一段内容,用JLINK跑MCU的程序,可以看到能接收到本本串口助手发来的内容。

这说明MCU所在板子TTL通讯是好的。

单独测试新短信模块

将TTL转串口模块和新短信模块用3根线连在一起(A-RX => B-TX, A-TX => B-RX, A-GND => B-GND )
将TTL转串口模块接在本本的USB口。
用本本上的串口助手发标准AT指令给短信模块,短信模块回答OKrn.

这说明短信模块的TTL通讯是好的。

这说明,我同事帮我做的样机还是靠谱的。
那问题出哪里了?2个模块对一起就不能通讯了?

组合测试2个模块对接在一起的情况

是不是我同事将收发接反了? 看着原理图也不像。他从来就没做错过事情。
将MCU所在模块和新短信模块用3根线连在一起(A-RX => B-TX, A-TX => B-RX, A-GND => B-GND )
还是在MCU上跑,现在能通讯了。

问题解决

比较同事给我搭的样机和我现在能通讯的环境。
唯一的差别就在我多拉了一条GND.
只能估计是2个模块之间的地有电位差吧。但是用外用表量,同事给我搭的样机,2个模块之间的GND确实是通的。

HAL库串口(UART4)测试代码

int main(void)
{
  /* USER CODE BEGIN 1 */
  int RxLen = 0;
  HAL_StatusTypeDef rc = HAL_OK;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

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

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_UART4_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    
    /* USER CODE BEGIN 3 */
    HAL_GPIO_WritePin(LED_RUN_GPIO_Port, LED_RUN_Pin, GPIO_PIN_RESET);
    HAL_Delay(500);
    HAL_GPIO_WritePin(LED_RUN_GPIO_Port, LED_RUN_Pin, GPIO_PIN_SET);
    
    // huart4
    // HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    strcpy((char*)sz_buf, "ATrn");
    rc = HAL_UART_Transmit(&huart4, sz_buf, 4, 400); // 这里超时没用, 硬件正常直接就发出去了.
    if (HAL_OK != rc) {
      HAL_Delay(100);
      continue;
    }
    
    // HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    memset(sz_buf, 0, sizeof(sz_buf));
    
    // AT指令回包不定长,给出的接收缓冲区一定比回包长度长,
    // 这里的超时接收500ms有用. 每次都是HAL_TIMEOUT
    rc = HAL_UART_Receive(&huart4, sz_buf, sizeof(sz_buf), 500); 
    RxLen = huart4.RxXferSize - huart4.RxXferCount;
    if ((HAL_OK != rc) && (HAL_TIMEOUT != rc)) {
      HAL_Delay(100);
      continue;
    }

    sz_buf[10] = (uint8_t)RxLen;
  }
  /* USER CODE END 3 */
}

最后

以上就是震动帆布鞋为你收集整理的解决了一次模块间TTL串口不能通讯的问题的全部内容,希望文章能够帮你解决解决了一次模块间TTL串口不能通讯的问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部