xtl2012 发表于 2013-2-26 22:00:18

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

问题是:如何完整的接收上位机发送过来的字符串(如:abcdef),而不是单字符,上位机如果发送字符串是不是连续不停的发送?即使我们在取SBUF寄存器的数据,但在这时上位机还在不停的发送后一个字节的数据。求高手过招..给个整个理解过程,有代码就更为好了!小弟在此谢过了!

skynet 发表于 2013-2-26 22:07:31

中断









mcu_lover 发表于 2013-2-26 22:57:16

中断+缓冲

laujc 发表于 2013-2-26 23:11:41

字符是一个bit一个bit发来的,接收时,接收8bit就收到一个字节的内容,会放到缓存中.
缓存大小有不同,有的单片机就一个,即一个byte.这样接收到8bit即一byte就要主程序进行读取,读取的同时,硬件会继续接收接下来的bit

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

xtl2012 发表于 2013-2-27 08:21:11

laujc 发表于 2013-2-26 23:11 static/image/common/back.gif
字符是一个bit一个bit发来的,接收时,接收8bit就收到一个字节的内容,会放到缓存中.
缓存大小有不同,有的单片 ...

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

xtl2012 发表于 2013-2-27 08:22:48

skynet 发表于 2013-2-26 22:07 static/image/common/back.gif
中断

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

xtl2012 发表于 2013-2-27 08:23:22

mcu_lover 发表于 2013-2-26 22:57 static/image/common/back.gif
中断+缓冲

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

mcu_lover 发表于 2013-2-27 08:29:07

xtl2012 发表于 2013-2-27 08:23
是不是只需要在中断函数里面读取下来就ok?然后每来一个字符就进中断一次就读取一次? ...

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

laujc 发表于 2013-2-27 10:58:11

xtl2012 发表于 2013-2-27 08:21 static/image/common/back.gif
嗯,上位机发送一个字符串,下位机利用串口中断RI 来接收,即中断一次就进入中断函数接收一个字符(例:reciv ...

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

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

r166 发表于 2013-2-27 11:10:03

本帖最后由 r166 于 2013-2-27 11:12 编辑

xtl2012 发表于 2013-2-27 08:21 static/image/common/back.gif
嗯,上位机发送一个字符串,下位机利用串口中断RI 来接收,即中断一次就进入中断函数接收一个字符(例:reciv ...

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

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

xtl2012 发表于 2013-3-1 09:57:33

laujc 发表于 2013-2-27 10:58 static/image/common/back.gif
是连续接收到8bit后,才放到buf中的.
有的单片机,当所有buf里都有接收的数据,而且没有被读取,就不会更新bu ...

    嗯嗯,谢谢你拉.!

xtl2012 发表于 2013-3-1 09:58:46

r166 发表于 2013-2-27 11:10 static/image/common/back.gif
单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...

thanks!!!!

mengfc 发表于 2013-3-1 10:02:57

单片机只能一个字符一个字符进行接收,如果需要接收字符串需在的单片机程序中进行判断。如在传输过程中设置特殊字符、使用定时器设置超时时间等。

laujc 发表于 2013-3-1 10:09:03

mengfc 发表于 2013-3-1 10:02 static/image/common/back.gif
单片机只能一个字符一个字符进行接收,如果需要接收字符串需在的单片机程序中进行判断。如在传输过程中设置 ...

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

绿茶山人 发表于 2013-3-1 10:55:36

开个数组作为缓存,每中断一次向数组中写一个字符,注意不要溢出!

mengfc 发表于 2013-3-1 11:01:21

laujc 发表于 2013-3-1 10:09 static/image/common/back.gif
一般网络传输时,都是按bit传输的.
连续接收指定的字节后,会产生中断到程序. ...

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

mengfc 发表于 2013-3-1 11:05:34

》单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...
上面这个回复对于51单片机是错误的,51单片机只能多缓冲一个字符,如果不及时取走会被覆盖掉的,你详细的看一下51的手册。

laujc 发表于 2013-3-1 11:58:12

mengfc 发表于 2013-3-1 11:05 static/image/common/back.gif
》单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...

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

xtl2012 发表于 2013-3-1 21:13:44

mengfc 发表于 2013-3-1 11:05 static/image/common/back.gif
》单片机不会那样RZ的,你要读取的数据的正在接受的数据不在同一个地方的,除非没有及时取走,否则是不会 ...

嗯,谢谢你,

BloathX 发表于 2013-3-2 07:48:03

产生接收中断的事件是数据寄存器不为空,片子接收时的内部步骤具体看手册。在中断时处理不要超过接收一个字节所需要的时间就行

xjzxl 发表于 2013-3-2 09:26:38

{:titter:}我又回来了,账号被封一年.

SilverBullet 发表于 2013-3-2 10:05:35

可以收到一个字符然后向上位机返回一个“Rxed”表示已经收到,然后上位机发送下一个字符

xtl2012 发表于 2013-3-2 10:50:51

SilverBullet 发表于 2013-3-2 10:05 static/image/common/back.gif
可以收到一个字符然后向上位机返回一个“Rxed”表示已经收到,然后上位机发送下一个字符 ...

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

SilverBullet 发表于 2013-3-2 11:42:03

xtl2012 发表于 2013-3-2 10:50 static/image/common/back.gif
那这个你要修改上位机软件或者自己做一个符合这样规格的软件才行呀,这样也就不符RS232协议的 ...

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

xtl2012 发表于 2013-3-2 19:01:27

SilverBullet 发表于 2013-3-2 11:42 static/image/common/back.gif
上位机软件不是你自己的吗?
如果不能修改的话只能在中断里面把字符保存到一个缓冲区并保证这个保存过程 ...

是的....

i55x 发表于 2013-3-2 19:10:36

先把通讯协议弄清楚,一帧是等长的还是变长的?

lu976046395 发表于 2013-4-30 15:23:19

一般用什么样的协议来保证传送数据的准确性

lu976046395 发表于 2013-4-30 15:24:30

laujc 发表于 2013-2-26 23:11 static/image/common/back.gif
字符是一个bit一个bit发来的,接收时,接收8bit就收到一个字节的内容,会放到缓存中.
缓存大小有不同,有的单片 ...

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

13hoop 发表于 2013-4-30 15:44:33

本帖最后由 13hoop 于 2013-4-30 15:47 编辑

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

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

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

SunnyTrip 发表于 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 = 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==0xA0)&&(UART_rcv_buf==0xFF))
        {                  
           UART_r_process();                  
        }
}

BigWolf 发表于 2013-4-30 17:15:59

中断接一个,存一个。

tiancaigao7 发表于 2013-4-30 17:19:29

采用DMA+超时中断也可以实现。适合大数据量的传输。

benqme 发表于 2013-4-30 17:22:45

建立一个字符数组就可以了,
unsigned char di[]="china book book" ;

benqme 发表于 2013-4-30 18:07:14

将字符串拆成单个字符一个一个的发送给单片机

songshanxiaozi 发表于 2014-7-9 15:59:36

接收时(写)使用队列。
解析时(读)使用状态机
页: [1]
查看完整版本: 单片机如何接收上位机传来的字符串?