打印
[疑难问答]

双串口SBUF数据错乱

[复制链接]
2722|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nickyamw|  楼主 | 2014-7-22 15:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
芯片用的是MA805-64和82FE216

现象:
        我用串口0连485以57600波特率跟上位机通信,用串口1以9600波特率跟一个模块A通信
        模块A要经常通信,每次都要发0x02回应模块A,但间隔不会太长
        问题是串口0跟上位机繁忙通信时,发给上位机的数据中会混入串口1的0x02,而且此时模块A会由于收不到回应而挂了
        例如我要发送 00 AA BB CC DD EE FF 11 给上位机
        但有时会出现00 AA BB CC DD 02 EE FF (上位机的只显示8个字节)
        或00 AA BB 02 CC DD EE FF  

怀疑是串口0跟串口1的SBUF由于页切换不够快而导致这个问题。
我手上的那份805-64中文的DATASHEET没说页切换的时间,二姨家有知道的朋友么?


沙发
mg_sz| | 2014-7-23 09:15 | 只看该作者
串口0和串口1 SBUF 的页切换是实时的,否则,你只要发送快,都会错.
楼主可以检查一下,有没有别的地方切换了页,而没有切回来.

使用特权

评论回复
板凳
nickyamw|  楼主 | 2014-7-26 16:19 | 只看该作者
mg_sz 发表于 2014-7-23 09:15
串口0和串口1 SBUF 的页切换是实时的,否则,你只要发送快,都会错.
楼主可以检查一下,有没有别的地方切换了页 ...

只在串口0和串口1的串口中断里切换过页,用来读写SBUF

使用特权

评论回复
地板
nickyamw|  楼主 | 2014-7-26 17:00 | 只看该作者
mg_sz 发表于 2014-7-23 09:15
串口0和串口1 SBUF 的页切换是实时的,否则,你只要发送快,都会错.
楼主可以检查一下,有没有别的地方切换了页 ...

默认串口0优先级比串口1优先级要高,而程序里并没改变优先级,就搞不懂怎么了。串口1的数据发送前先将页写成1,再写进SBUF里

使用特权

评论回复
5
mg_sz| | 2014-7-30 11:50 | 只看该作者
在中断中改变页,请在中断中保存页值..

使用特权

评论回复
6
nickyamw|  楼主 | 2014-8-13 14:35 | 只看该作者
mg_sz 发表于 2014-7-30 11:50
在中断中改变页,请在中断中保存页值..

怎样保存页值?不是直接写那个页寄存器就行了么?

使用特权

评论回复
7
mg_sz| | 2014-8-15 08:32 | 只看该作者
好我解释一下:你的程序一直在用串口0 在发送,在主程序中一直在做这个动作.此时BUF 的页值是串口0的.
假设此时,进到串口1中断,在中断中您没有保存页值,那么出中段时,页值就改变了,如果此时,您没有重新写页值,就继续发送串口0.此时数据就出错了.  不明白可以电话给我.左上角的电话可以找到我.我们电话沟通.

使用特权

评论回复
8
nickyamw|  楼主 | 2014-9-6 11:26 | 只看该作者
mg_sz 发表于 2014-8-15 08:32
好我解释一下:你的程序一直在用串口0 在发送,在主程序中一直在做这个动作.此时BUF 的页值是串口0的.
假设此 ...

不好意思,这么久才回复。

我使用双串口是这样的流程:
两个串口都使用中断才收发数据。
当有中断产生就进去处理,首先是把页改为相应的值,例如串口0的中断则先把页设成0,再进去处理,再去把数据放进buf里,搞定之后退出中断。

对于版主你在7楼的回复里说由于退出中断后页值改变
这个BUF不是同一个逻辑地址不同的物理寄存器么,那我把页设置之后,往BUF里一写就应该是写进相应的寄存器了吧,怎么会因为我退出中断而把串口1的发送寄存器的内容,连接到了串口0的发送那里呢?

使用特权

评论回复
9
nbsmaps| | 2014-9-17 10:47 | 只看该作者
可能是这样,一进中断,改变了页地址,而此时刚好还有数据在发送或接收,从而出错

使用特权

评论回复
10
mg_sz| | 2014-9-18 09:23 | 只看该作者
nickyamw 发表于 2014-9-6 11:26
不好意思,这么久才回复。

我使用双串口是这样的流程:

我再细看了一下您程序的结果,应该是发送串口1 时,页面变了.您可以这样修改一下:
进中断时压栈SFRPI, 出中断时出栈SFRPI. 您再试试.

使用特权

评论回复
11
nickyamw|  楼主 | 2014-11-18 15:51 | 只看该作者
nbsmaps 发表于 2014-9-17 10:47
可能是这样,一进中断,改变了页地址,而此时刚好还有数据在发送或接收,从而出错
...

我串口0跟串口1 波特率不同,上位机收到的数据中,我串口1 的那一个字节的数据是加塞进串口0发送的那一串数据中,
要是这样的话,那加塞进去的那个串口1 的数据应该是像成为UART的噪音吧,又或者说,我刚写进去SBUF的那字节数据会被后来串口0的数据覆盖吧。要是刚好改变了页地址,而有数据收发,怎么会那么完整地被上位机接收到了呢?

使用特权

评论回复
12
nickyamw|  楼主 | 2014-11-18 16:15 | 只看该作者
mg_sz 发表于 2014-9-18 09:23
我再细看了一下您程序的结果,应该是发送串口1 时,页面变了.您可以这样修改一下:
进中断时压栈SFRPI, 出中 ...

串口1发送的程序如下,这么短,应该不至于刚把页面切换,就遇上了串口0的中断了吧?之前试过把串口1的中断优先级高于串口0的,但这个问题还是存在。

void Uart1_Send_Byte(uchar Send_Byte)
{
        SFRPI = 0x01;
        ACC = Send_Byte;
        TB81 = P;
        SBUF1 = Send_Byte;       
}



我不用汇编,用串口1的时候,进中断就要把SFRPI写1,出中断的时候也写一次SFRPI为1 ,这样子行么?

使用特权

评论回复
13
mg_sz| | 2014-11-19 09:07 | 只看该作者
本帖最后由 mg_sz 于 2014-11-19 09:12 编辑

定义两个变量在中断里保存SFRPI,
unsigned char BakSfrpi_U0;
unsigned char BakSfrpi_U1;

// 串口0中断程序
void Int_Uart0() interrupt 4
{
          BakSrfpi_U0=SFRPI;
          SFRPI=0;
         //......  用户程序
         //.....
        SFRPI=BakSfrpi_U0;
}

// 串口1中断程序
void Int_Uart1() interrupt 12
{
          BakSrfpi_U1=SFRPI;
          SFRPI=1;
         //......  用户程序
         //.....
        SFRPI=BakSfrpi_U1;
}

//串口0发送程序
void Uart0SendByte(unsigned char tByte)
{
          SFRPI=0;
         //........   
}

//串口1发送程序
void Uart1SendByte(unsigned char tByte)
{
          SFRPI=1;
         //........   

        SFRPI=0;
}

使用特权

评论回复
14
nickyamw|  楼主 | 2014-11-22 15:24 | 只看该作者
mg_sz 发表于 2014-11-19 09:07
定义两个变量在中断里保存SFRPI,
unsigned char BakSfrpi_U0;
unsigned char BakSfrpi_U1;

好的,谢谢版主!

我发现同事的程序里也有这样的设置,去保存SFRPI,
我去试试这样子。

顺道还试试用串口1的时候直接关了串口0:)

使用特权

评论回复
15
hnkf118| | 2014-12-15 14:17 | 只看该作者
主要还是程序没控制好。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

252

帖子

0

粉丝