硬汉嵌入式论坛

 找回密码
 立即注册
查看: 424|回复: 2
收起左侧

串口接收comGetChar(COM1,&read)使用百思不得其解

[复制链接]

5

主题

29

回帖

44

积分

新手上路

积分
44
QQ
发表于 2025-3-14 10:13:18 | 显示全部楼层 |阅读模式
遇到一个没有想明白的事情:用串口接收指令(不定长的),但是指令是以0D0A(换行、回车)结束,结束之后再去指令的运行处理。
1. 接收是用while(comGetChar(COM1,&read))循环进行,设想串口接收缓冲器是有指令就在循环中,保存指令,碰到0D,0A,本次指令就结束,代码这样进行的:
                while(comGetChar(COM1,&read))
                {
                    if(read !='\n' && read !='\r')
                    {
                        shellMsg.msg_buf[shellMsg.idx] = read;
             shellMsg.idx++;


             PRINT_MSG("22");  //这条语句取消就接受不正常   
             
                    }
                    else
                    {
                       if(++command_end_flag == 2)
                       {
                shellMsg.msg_buf[shellMsg.idx]='\0';
                shellMsg.idx = 0;
                 shellMsg.state = SHELLMSG_WAITTING_DEAL_FINISH_COMMAND;


                  command_end_flag = 0;
                  break;
                       }


                    }
                }


奇怪在若是没有上面的PRINT_MSG("22")    这条语句取话接始终进入不了else中,也就是没法进行0D0A的结束的处理。


2. 所以加上没用的PRINT_MSG("22") ,随便打印输出什么都可以,这是一种解决方案,一直想不明白,翻看论坛,看到硬汉建议状态机,使用状态机,没有使用while,也可以解决。
                                if(comGetChar(COM1,&read))
                                {
                                        switch(ucStatus)
                                        {
                                                case 0:
                                                        if( read =='\r') //'\r' 是一个转义字符,表示回车,为0D
                                                        {
                                                                ucStatus = 1;
                                                        }
                                                        else
                                                        {
                                                                shellMsg.msg_buf[shellMsg.idx] = read;
                                                                shellMsg.idx++;
                                                       
                                                        }
                                                        break;
                                                case 1:
                                                        if(read =='\n')//'\n' 是一个转义字符,表示换行(newline),为0A
                                                        {
                                                                shellMsg.msg_buf[shellMsg.idx]='\0';//'\0' 常用于字符串结束标志,为00;
                                                                shellMsg.idx = 0;
                                                                shellMsg.state = SHELLMSG_WAITTING_DEAL_FINISH_COMMAND;
                                                                ucStatus = 0;
                                                        }
                                                        break;
                                                default:
                                                        break;
                                                       
                                        }


3. 难道是while循环的问题?时间的问题?没有搞明白,请硬汉或者其他有经验的群友帮思考思考!

回复

使用道具 举报

95

主题

530

回帖

830

积分

金牌会员

积分
830
发表于 2025-3-14 13:21:47 | 显示全部楼层
怀疑是comGetChar(COM1,&read)没数据的时候返回0,你就退出while造成的。
共产主义一定胜利!
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115653
QQ
发表于 2025-3-14 16:18:22 | 显示全部楼层
应该是楼上群友的问题。你可以while死循环,while里面判断comGetChar(COM1,&read)

类似8266的AT串口,不过这里做了个超时,防止出错了一直在while里面

[C] 纯文本查看 复制代码
uint8_t ESP8266_WaitResponse(char *_pAckStr, uint16_t _usTimeOut)
{
	uint8_t ucData;
	uint16_t pos = 0;
	uint32_t len;
	uint8_t ret;

	len = strlen(_pAckStr);
	if (len > 255)
	{
		return 0;
	}

	/* _usTimeOut == 0 表示无限等待 */
	if (_usTimeOut > 0)
	{
		bsp_StartTimer(ESP8266_TMR_ID, _usTimeOut);		/* 使用软件定时器3,作为超时控制 */
	}
	while (1)
	{
		bsp_Idle();				/* CPU空闲执行的操作, 见 bsp.c 和 bsp.h 文件 */

		if (_usTimeOut > 0)
		{
			if (bsp_CheckTimer(ESP8266_TMR_ID))
			{
				ret = 0;	/* 超时 */
				break;
			}
		}

		if (comGetChar(COM_ESP8266, &ucData))
		{
			ESP8266_PrintRxData(ucData);		/* 将接收到数据打印到调试串口1 */

			if (ucData == _pAckStr[pos])
			{
				pos++;
				
				if (pos == len)
				{
					ret = 1;	/* 收到指定的应答数据,返回成功 */
					break;
				}
			}
			else
			{
				pos = 0;
			}
		}
	}
	return ret;
}

评分

参与人数 1金币 +10 收起 理由
hongqi1O29 + 10 很给力!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-9 15:46 , Processed in 0.442416 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表