发新帖我要提问
12
返回列表
打印
[国产单片机]

模拟串口发送数据有时漏发几个字节

[复制链接]
楼主: 一叶倾城wwq
手机看帖
扫描二维码
随时随地手机跟帖
21
xch| | 2019-1-8 18:17 | 只看该作者 回帖奖励 |倒序浏览
应该是定时不准引起的.  建议定时中断服务开始就立刻发送事先准备的1bit数据. 发送后在准备下一拍数据.
定时器中断优先级设定为最高.

使用特权

评论回复
22
一叶倾城wwq|  楼主 | 2019-1-9 11:23 | 只看该作者
mohanwei 发表于 2019-1-7 16:34
问题相当多……
你这种定时中断+多分支多跳转的,相位抖动太大了
建议重新写一个查询法+软件延时的单字节 ...

是的,最近在一本书上看到“主程序很难和定时器同步”,我理解下来:非要同步,如我这里在主程序里while等待,是存在问题的,我在考虑换种方法了,可能方法本身就有问题

使用特权

评论回复
23
一叶倾城wwq|  楼主 | 2019-1-9 11:27 | 只看该作者
gx_huang 发表于 2019-1-7 16:55
即使只有一个中断,关定时器也会增加抖动,有些指令只要1t,有些要好多t,进中断的时间不一样,这就产生 ...

现在已经更换了赋值方法为TH0=0XFF;TL0+=153;没有使用八位自动重装,今天上午测试只出现过一次漏发几字节的情况

使用特权

评论回复
24
一叶倾城wwq|  楼主 | 2019-1-9 11:30 | 只看该作者
千岁寒 发表于 2019-1-8 11:24
可能是串口線的影響 或者 是波特率不那麼精確!

有这个可能,我的串口线为TX和RX各通过一个1K电阻连接为一根通信线,至于波特率的问题,我测试过别人的9600MCU通信也是80us和120us这个样子,并非精准的104us,应该不是波特率的问题

使用特权

评论回复
25
一叶倾城wwq|  楼主 | 2019-1-9 11:33 | 只看该作者
edan_lee 发表于 2019-1-8 12:53
看波形不对,忽长忽短。长是不是因为发生了更高或者同级优先级的中断? 9600 的位宽应该是在104us的样子。 ...

波特率的问题,我测试过别人的9600MCU通信也是80us和120us这个样子,并非精准的104us,应该在它的冗错范围之内吧?长的时候并未发生其他中断,这个在我刚写串口的时候就测试过,出来的波形长度就这个样子,我也很纳闷,也调过初值,一直得不到精准的104!

使用特权

评论回复
26
一叶倾城wwq|  楼主 | 2019-1-9 11:37 | 只看该作者

感谢您的思路,您这是放在定时器里的发送函数吧?我这两天也阅读过其他人写的代码,发现也都是用的在定时器里赋值发送,不像我这样在主函数置一堆标志和赋值然后还在主程序等待,在考虑换这种实现方法

使用特权

评论回复
27
一叶倾城wwq|  楼主 | 2019-1-9 11:40 | 只看该作者
li880wert 发表于 2019-1-8 17:50
定时器时间改80us,你定时器里面2个除法就占用了20us.你原来定时100的变成120了, ...

受教了,一个除法占用10us时间?能科普下吗?我现在改了上面楼层说的TH0=0XFF;TL0+=153;但波形也是80和120。

使用特权

评论回复
28
一叶倾城wwq|  楼主 | 2019-1-9 11:43 | 只看该作者
xch 发表于 2019-1-8 18:17
应该是定时不准引起的.  建议定时中断服务开始就立刻发送事先准备的1bit数据. 发送后在准备下一拍数据.
定 ...

我也觉得是刚好在发送漏掉那几个字节时,要么波形抖了下,要么时间不对导致波形长度不在9600的冗错范围之内,对了,请问这个有一定的冗错范围,但大概是多少?查了下没找到

使用特权

评论回复
29
ayb_ice| | 2019-1-9 13:16 | 只看该作者
就这么点东西,应该不会有什么问题

#define u8 unsigned char
sbit TXD = P0^0;


void Delay_9600(void)
{
        //移植此处
}

#pragma disable
void SendByte(u8 ucData)
{
        u8 i;
       
        TXD = 0;
        Delay_9600();
       
        for (i=0; i<8; i++)
        {
                ucData >>= 1;
                TXD = CY;
                Delay_9600();
        }
       
        TXD = 1;
        Delay_9600();
}

void SendString(u8* pStr)
{
        while (1)
        {
                u8 c = *pStr++;
                if (c != '\0')
                {
                        SendByte(c);
                }
                else
                {
                        break;
                }
        }
       
}

使用特权

评论回复
30
xch| | 2019-1-9 16:00 | 只看该作者
一叶倾城wwq 发表于 2019-1-9 11:43
我也觉得是刚好在发送漏掉那几个字节时,要么波形抖了下,要么时间不对导致波形长度不在9600的冗错范围之 ...

  一般在启始位同步下降沿,同步误差最大值是0.5bit位宽,其余误差是10比特累积误差由baudrate误差引起。
收发时钟不同步引起。 理想状况可以接受5% 总比特率误差。
做得最好的硬件,可以忽略启始位同步误差,可以支持不到10%的码率误差。

使用特权

评论回复
31
edan_lee| | 2019-1-9 21:17 | 只看该作者
一叶倾城wwq 发表于 2019-1-9 11:37
感谢您的思路,您这是放在定时器里的发送函数吧?我这两天也阅读过其他人写的代码,发现也都是用的在定时 ...

不是哦,是等查询定时器溢出代替软件延时。用串口测试工具收发,几万个字节都没有错。接收也是模拟的。这样做有一个不好的地方,就是发送的优先级很低,很容易被中断干扰。所以我的中断设计都是尽量快进快出。

使用特权

评论回复
评论
一叶倾城wwq 2019-1-9 23:25 回复TA
@edan_lee :知道了,我先把波形调对再测数据,估计就是波形上的问题导致的 
edan_lee 2019-1-9 21:20 回复TA
你的波形一定是有问题的。我用逻辑分析仪看过,硬件的串口虽然也不是104uS但是也是接近的。而且不会是一忽长忽短。 
32
linqing171| | 2019-1-9 22:01 | 只看该作者
前几天说了,你的逻辑分析仪是40us采一个数,结果要么是80us,要么是120us,你还老在纠结你的输出不是104us。
抖动再大,你这几行代码也就是几us,不可能40us的抖动啊。

start+8+1=10bit的时间,抖动不能超过±50%=±0.5bit,换句话说,一个bit不能超过5%,则总的10bit的累积时间就没有问题。

你再仔细读一下前面我7楼的回复。

我7楼的第三条是这个意思:
1 你把所有的P12都替换成NextTxd;
2 你定义个新的变量叫NextTxd;
3 发送前把NextTxd=1; 也就是串口的idle状态,也就是start之前和stop之后的状态。
4 进入定时器中断,第一句P12=NextTxd;
5 定时器因为自动重载了,所以从定时器一进来的地方去掉。

不过已经说了,7楼第三条只是减小了一点抖动,意义不大,根据分析问题在7楼的第四条等这种情况下。

使用特权

评论回复
33
linqing171| | 2019-1-9 22:42 | 只看该作者
上句说错了,
3 发送前把NextTxd=0; 也就是串口的idle状态,也就是start之前和stop之后的状态。

你这个因为是连续丢字节,而你加上逻辑分析仪就不出现了,应该是你的地线没有接好,逻辑分析仪让你的地信号更稳定了,而且你串联的1k电阻导致驱动能力有点弱。所以换跟连线吧,不完全是抖动把波形变差了。
我以前用9600串1k发送8M的二进制大文件,一直也挺稳定的。

晶振的偏差不要超过5%,否则会有误码,两个bit的stop会略微好点。

使用特权

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

本版积分规则