搜索
bottom↓
回复: 34

单片机如何接收上位机传来的字符串?

[复制链接]

出0入0汤圆

发表于 2013-2-26 22:00:18 | 显示全部楼层 |阅读模式
问题是:如何完整的接收上位机发送过来的字符串(如:abcdef),而不是单字符,上位机如果发送字符串是不是连续不停的发送?即使我们在取SBUF寄存器的数据,但在这时上位机还在不停的发送后一个字节的数据。求高手过招..给个整个理解过程,有代码就更为好了!小弟在此谢过了!

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入12汤圆

发表于 2013-2-26 22:07:31 | 显示全部楼层
中断









出0入264汤圆

发表于 2013-2-26 22:57:16 来自手机 | 显示全部楼层
中断+缓冲

出0入4汤圆

发表于 2013-2-26 23:11:41 | 显示全部楼层
字符是一个bit一个bit发来的,接收时,接收8bit就收到一个字节的内容,会放到缓存中.
缓存大小有不同,有的单片机就一个,即一个byte.这样接收到8bit即一byte就要主程序进行读取,读取的同时,硬件会继续接收接下来的bit

也有的缓存较大,这样就可以接收多个字节,程序再一次读取全部接收到的byte
不论是字母,如abc,还是数字123.都是传输的二进制数,两边协议相同就不会错.

出0入0汤圆

 楼主| 发表于 2013-2-27 08:21:11 | 显示全部楼层
laujc 发表于 2013-2-26 23:11
字符是一个bit一个bit发来的,接收时,接收8bit就收到一个字节的内容,会放到缓存中.
缓存大小有不同,有的单片 ...

嗯,上位机发送一个字符串,下位机利用串口中断RI 来接收,即中断一次就进入中断函数接收一个字符(例:recive=SBUF),但在接收字符的同时,上位机也在继续发接着后一个字符的数据,那在这时候我们在中断函数中读取的那个字符会不会已经被修改过了?从而导致乱码.?

出0入0汤圆

 楼主| 发表于 2013-2-27 08:22:48 | 显示全部楼层
skynet 发表于 2013-2-26 22:07
中断

是不是只需要在中断函数里面读取下来就ok?然后每来一个字符就进中断一次就读取一次?

出0入0汤圆

 楼主| 发表于 2013-2-27 08:23:22 | 显示全部楼层
mcu_lover 发表于 2013-2-26 22:57
中断+缓冲

是不是只需要在中断函数里面读取下来就ok?然后每来一个字符就进中断一次就读取一次?

出0入264汤圆

发表于 2013-2-27 08:29:07 来自手机 | 显示全部楼层
xtl2012 发表于 2013-2-27 08:23
是不是只需要在中断函数里面读取下来就ok?然后每来一个字符就进中断一次就读取一次? ...

接收中断里面把数据读取到缓冲区,主循环解析这个缓冲区即可。

出0入4汤圆

发表于 2013-2-27 10:58:11 | 显示全部楼层
xtl2012 发表于 2013-2-27 08:21
嗯,上位机发送一个字符串,下位机利用串口中断RI 来接收,即中断一次就进入中断函数接收一个字符(例:reciv ...

是连续接收到8bit后,才放到buf中的.
有的单片机,当所有buf里都有接收的数据,而且没有被读取,就不会更新buf,而是产生一个溢出标志或溢出中断.

连续接收8bit数据,需要一段时间,在接收完成后,立即产生中断,中断后读取buf的时间很短的,几个指令周期就够了,远小于接收8bit的时间.
不会产生影响.

出0入0汤圆

发表于 2013-2-27 11:10:03 | 显示全部楼层
本帖最后由 r166 于 2013-2-27 11:12 编辑
xtl2012 发表于 2013-2-27 08:21
嗯,上位机发送一个字符串,下位机利用串口中断RI 来接收,即中断一次就进入中断函数接收一个字符(例:reciv ...


单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会覆盖,

芯片使用前数据手册还是要仔细看一看的。

出0入0汤圆

 楼主| 发表于 2013-3-1 09:57:33 | 显示全部楼层
laujc 发表于 2013-2-27 10:58
是连续接收到8bit后,才放到buf中的.
有的单片机,当所有buf里都有接收的数据,而且没有被读取,就不会更新bu ...

    嗯嗯,谢谢你拉.!

出0入0汤圆

 楼主| 发表于 2013-3-1 09:58:46 | 显示全部楼层
r166 发表于 2013-2-27 11:10
单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...

thanks!!!!

出0入0汤圆

发表于 2013-3-1 10:02:57 | 显示全部楼层
单片机只能一个字符一个字符进行接收,如果需要接收字符串需在的单片机程序中进行判断。如在传输过程中设置特殊字符、使用定时器设置超时时间等。

出0入4汤圆

发表于 2013-3-1 10:09:03 | 显示全部楼层
mengfc 发表于 2013-3-1 10:02
单片机只能一个字符一个字符进行接收,如果需要接收字符串需在的单片机程序中进行判断。如在传输过程中设置 ...

一般网络传输时,都是按bit传输的.
连续接收指定的字节后,会产生中断到程序.

出70入0汤圆

发表于 2013-3-1 10:55:36 | 显示全部楼层
开个数组作为缓存,每中断一次向数组中写一个字符,注意不要溢出!

出0入0汤圆

发表于 2013-3-1 11:01:21 | 显示全部楼层
laujc 发表于 2013-3-1 10:09
一般网络传输时,都是按bit传输的.
连续接收指定的字节后,会产生中断到程序. ...

串行通讯在物理层确实是按bit传输的,但是我说一个字符(字节)一个字符传输的是指面对单片机程序设计而言,因为每接收到一个字符51都会产生一个中断事件。

出0入0汤圆

发表于 2013-3-1 11:05:34 | 显示全部楼层
》单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...
上面这个回复对于51单片机是错误的,51单片机只能多缓冲一个字符,如果不及时取走会被覆盖掉的,你详细的看一下51的手册。

出0入4汤圆

发表于 2013-3-1 11:58:12 | 显示全部楼层
mengfc 发表于 2013-3-1 11:05
》单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...

没注意是51单片机,
现在好多单片机都是在51的基础上改进,越做越好了.

出0入0汤圆

 楼主| 发表于 2013-3-1 21:13:44 | 显示全部楼层
mengfc 发表于 2013-3-1 11:05
》单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...

嗯,谢谢你,

出0入0汤圆

发表于 2013-3-2 07:48:03 来自手机 | 显示全部楼层
产生接收中断的事件是数据寄存器不为空,片子接收时的内部步骤具体看手册。在中断时处理不要超过接收一个字节所需要的时间就行

出0入0汤圆

发表于 2013-3-2 09:26:38 | 显示全部楼层
我又回来了,账号被封一年.

出0入0汤圆

发表于 2013-3-2 10:05:35 | 显示全部楼层
可以收到一个字符然后向上位机返回一个“Rxed”表示已经收到,然后上位机发送下一个字符

出0入0汤圆

 楼主| 发表于 2013-3-2 10:50:51 | 显示全部楼层
SilverBullet 发表于 2013-3-2 10:05
可以收到一个字符然后向上位机返回一个“Rxed”表示已经收到,然后上位机发送下一个字符 ...

那这个你要修改上位机软件或者自己做一个符合这样规格的软件才行呀,这样也就不符RS232协议的

出0入0汤圆

发表于 2013-3-2 11:42:03 | 显示全部楼层
xtl2012 发表于 2013-3-2 10:50
那这个你要修改上位机软件或者自己做一个符合这样规格的软件才行呀,这样也就不符RS232协议的 ...

上位机软件不是你自己的吗?
如果不能修改的话只能在中断里面把字符保存到一个缓冲区并保证这个保存过程比接受下个字符的速度快了

出0入0汤圆

 楼主| 发表于 2013-3-2 19:01:27 | 显示全部楼层
SilverBullet 发表于 2013-3-2 11:42
上位机软件不是你自己的吗?
如果不能修改的话只能在中断里面把字符保存到一个缓冲区并保证这个保存过程 ...

是的....

出0入0汤圆

发表于 2013-3-2 19:10:36 | 显示全部楼层
先把通讯协议弄清楚,一帧是等长的还是变长的?

出0入0汤圆

发表于 2013-4-30 15:23:19 | 显示全部楼层
一般用什么样的协议来保证传送数据的准确性

出0入0汤圆

发表于 2013-4-30 15:24:30 | 显示全部楼层
laujc 发表于 2013-2-26 23:11
字符是一个bit一个bit发来的,接收时,接收8bit就收到一个字节的内容,会放到缓存中.
缓存大小有不同,有的单片 ...

那么如何来确保我发送到数据的准确性,确保数据并没有丢失!

出0入0汤圆

发表于 2013-4-30 15:44:33 | 显示全部楼层
本帖最后由 13hoop 于 2013-4-30 15:47 编辑

大家都说到了
单片机收到数据进入中断  中断中清buf
取出char
在接收第二个
如此反复....

还有如果上位机是自己的  注意波特率
不光要和下位机一致

还要注意到windows设备管理器中查看  你的串口的波特率
有时候只在软件中设置不行  
最好能保证所有波特率一致

出0入0汤圆

发表于 2013-4-30 17:12:52 | 显示全部楼层
void UART_Interrupt (void) interrupt 4
{
        uchar i,l;
        uint n;
        if (RI==1)
        {
                i=0;
                l=0;
                while((RI==1)&&(l==0))
                {
                        RI=0;
                        UART_rcv_buf[i] = SBUF;
                        i++;
                        n=0;
                        if(i >= 4) {l=1;}            
                        while((RI==0)&&(l==0))                                                                  //判断是否超时
                        {
                                if(n>10000){l=1;}
                                n++;
                    }             
            }
        }
        TI = 0;
        RI = 0;
        if((UART_rcv_buf[0]==0xA0)&&(UART_rcv_buf[3]==0xFF))
        {                  
           UART_r_process();                  
        }
}

出0入0汤圆

发表于 2013-4-30 17:15:59 | 显示全部楼层
中断接一个,存一个。

出0入0汤圆

发表于 2013-4-30 17:19:29 | 显示全部楼层
采用DMA+超时中断也可以实现。适合大数据量的传输。

出0入0汤圆

发表于 2013-4-30 17:22:45 | 显示全部楼层
建立一个字符数组就可以了,
unsigned char di[]="china book book" ;

出0入0汤圆

发表于 2013-4-30 18:07:14 | 显示全部楼层
将字符串拆成单个字符一个一个的发送给单片机

出0入0汤圆

发表于 2014-7-9 15:59:36 | 显示全部楼层
接收时(写)使用队列。
解析时(读)使用状态机
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 03:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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