概述
前言
公司的产品嵌入式主机要更换短信模块,临时搞一台。
老模块原来直接做在板子上,这次生产后,同事将老模块吹下来了。
新短信模块是个小模块产品,同事将壳子拆掉,将产品板子塞进主机箱。
新短信模块原来是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串口不能通讯的问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复