STC8G1K17串口9600通信,丢数据,请问如何解决。
新手,第一次用STC8G单片机,程序从ISP下载软件复制过来的,时钟11.592M,波特率设置的9600,在用串口调试助手 进行数据收发测试的时候,丢数据。每秒发12字节数据。20%的机率丢一个字节数据。
具体代码如下
void UartIsr() interrupt 4
{
uint8_t rx;
if (TI)
{
TI = 0;
busy0 = 0;
}
if (RI)
{
RI = 0;
rx = SBUF;
SBUF = rx;LED = !LED; //收到的数据直接发送回去
busy0 = 1;
}
}
初始化
#define FOSC 11059200UL
#define BRT (65536 - FOSC / 9600 / 4)
TMOD = 0x00;//UART1
SCON = 0x50;
AUXR |= 0x40;
TL1 = BRT;
TH1 = BRT >> 8;
TR1 = 1;
ES = 1;
EA = 1;
宇宙第一强的单片机,肯定不会是这个样子。大神帮帮我。
目前尝试,
1. 数据处理不过来? 将时钟调高到18.432M,无果
2.难道是这个UART1 不行?我又调了UART2进行测试,仍是会丢数据。
3.波特率太高了??使用4800bps.仍是一样会丢
丢数据可以理解,但是约20%的概率。这个什么保证通信正常。。。 是不是你单片机的振荡频率不准,误差过大 magiczero 发表于 2021-1-29 19:46
是不是你单片机的振荡频率不准,误差过大
用的是IRC 频率11.592M
下载程序的时候提示
. 用户设定频率: 11.059MHz
. 调节后的频率: 11.062MHz
. 频率调节误差: 0.022%
这个用9600波特率 不够吗 同时考虑到是不是串口转换器 时钟不准。可是
我的UART1 接CP2102 UART2 接CH341 。不会两个都不准吧?
另外, 整个系统目前就用了串口,没有别的中断干扰。 看你的RC误差是没有问题的,不过还是接一个实际的外部晶振测试下看看 就是这样的结果,我的也是丢数据。 magiczero 发表于 2021-1-29 19:51
看你的RC误差是没有问题的,不过还是接一个实际的外部晶振测试下看看
整个电路 我都没有放置晶振
也不打算放置晶体了,相同的hex文件 刷到STC8A8K64S4A12这个芯片上,收发数据正常无丢数据
现在真的是没辙了 不舍的六年 发表于 2021-1-29 20:44
就是这样的结果,我的也是丢数据。
有解决办法吗,丢的数据没有规律,可靠性不行啊。。。 从0-255发256个数据看哪个数据丢失,有没有规律 mPiDDR 发表于 2021-1-29 20:56
有解决办法吗,丢的数据没有规律,可靠性不行啊。。。
你难道没听说过时钟漂移? 你这样写不丢才怪了!自己搜 ring buffer,写个小fifo wye11083 发表于 2021-1-29 21:04
你难道没听说过时钟漂移? 你这样写不丢才怪了!自己搜 ring buffer,写个小fifo ...
感谢你们的回复,这些简单的可能,我还是会考虑得到的。
1. 9600的波特率已够低,时钟再偏5% 也不会有问题。
2. FIFO 我一直有在用。贴上来的程序只是做简明环回测试、 正常程序是中断填充FIFO 在主程序取数据处理。
3. 用FIFO 来收,主程序处理的时候,环回发送,也一样会丢,
楼上的楼上,目前看没有规律。、
这个写法应该是有问题的(至少我不会这样写),如果单片机自带fifo的(或发送寄存器有两个的),这样写一般不会有问题。我个人猜测可能是这样的,数据收到写道发送寄存器,这个时间不会完全一致,在发送还没有发送完成的时候,这个时候写道发送寄存器,会导致你写入sbuf失败,你说你用过fifo也有问题,不妨把fifo的代码也发上来,让大家分析一下,问题很可能就在细微处。 楼上应该是正解!
9600bps,又是这么简单的测试,就是查询方式也不会有什么问题。 设置IO模式 把串口发送管脚设置为推挽输出 youkebing 发表于 2021-1-29 21:57
这个写法应该是有问题的(至少我不会这样写),如果单片机自带fifo的(或发送寄存器有两个的),这样写一般 ...
估计lz的fifo也是按那个方法写的。。事实上程序需要先填fifo,如果busy就通过中断继续写,否则程序立刻发起写。我921600bps都跑得欢,lz这9600都能丢数据也是太牛13了(不排除lz电路连接有问题,通常是地电平不相等,etc)。 等等官方权威回复……
不过这种很基础的操作,官方肯定测试过吧,真有问题也应该发现了 本帖最后由 mPiDDR 于 2021-1-30 09:07 编辑
youkebing 发表于 2021-1-29 21:57
这个写法应该是有问题的(至少我不会这样写),如果单片机自带fifo的(或发送寄存器有两个的),这样写一般 ...
是的,我也不会这样写。但是为了方便大家看得清楚、
目前经过折腾 可以确定的是: 是在接收的时候出现丢失。这个字节没有收到,也就没法发送回去。
再次对上面的回复,发送程序是没有问题的。
wye11083 提醒的好,希望是硬件连接的问题。买的是简单开发板,连接了5VGNDTX RX 四条线。下载程序也是用这条线。如果是连接线有问题,为何官方ISP能顺序刷?
另外,说TX端口需要推挽输出的,这个也尝试过了。没有改变。
发这帖子,希望能找到低级的错误。初始化的代码楼主位
相同的hex 一个字节不改,刷到STC8A8K64S4A12上,跑得很好,数据环回没有丢失。都是用相同内部IRC时钟
把代码贴出来。
xdata uint8_t wptr; //不管有没有加xdata 结果一样
xdata uint8_t rptr;
xdata uint8_t ucUartRxbuf = {0}; //接收缓冲
void Uart2Isr() interrupt 8
{
if (S2CON & 0x02)
{
S2CON &= ~0x02;
busy = 0;
}
if (S2CON & 0x01)
{
S2CON &= ~0x01;
ucUartRxbuf = S2BUF;
wptr &= 0x3f;
}
}
//主程序读取接收数据
uint8_t UART2_Read(uint8_t* dat){
if(rptr == wptr)return 0;
dat = ucUartRxbuf;
rptr &= 0x3f;
}
//发送
void Uart2Send(uint8_t dat)
{
while (busy);
_nop_();_nop_();_nop_();
busy = 1;
S2BUF = dat;
}
//主循环while (1)
uint8_t Usart_Rx_Num;uint8_t UARTRX;
Usart_Rx_Num = UART2_Read(&UARTRX);
if(Usart_Rx_Num!=0){
Uart2Send(UARTRX);
}
本帖最后由 mPiDDR 于 2021-1-30 09:20 编辑
mPiDDR 发表于 2021-1-30 09:00
是的,我也不会这样写。但是为了方便大家看得清楚、
目前经过折腾 可以确定的是: 是在接收的时候出现丢 ...
由于对STC8 不熟悉,下载程序的界面也一并截图,看哪里有不对的
正在检测目标单片机 ...
单片机型号: STC8G1K17-20/16PIN
固件版本号: 7.3.10U
当前芯片的硬件选项为:
. 内部IRC振荡器的频率: 11.062MHz
. 掉电唤醒定时器的频率: 35.475KHz
. 振荡器放大增益使能
. P3.2和P3.3与下次下载无关
. 上电复位时增加额外的复位延时
. 复位引脚用作普通I/O口
. 检测到低压时复位
. 低压检测门槛电压 : 2.00 V
. 上电复位时,硬件不启动内部看门狗
. 上电自动启动内部看门狗时的预分频数为 : 256
. 空闲状态时看门狗定时器停止计数
. 启动看门狗后,软件可以修改分频数,但不能关闭看门狗
. 下次下载用户程序时,将用户EEPROM区一并擦除
. 下次下载用户程序时,没有相关的端口控制485
. 下次下载时不需要校验下载口令
. 内部参考电压: 1195 mV (参考范围: 1100~1300mV)
. 内部安排测试时间: 2020年3月16日
单片机型号: STC8G1K17-20/16PIN
固件版本号: 7.3.10U
开始调节频率 ...
调节后的频率: 11.062MHz (0.022%)
正在重新握手 ... 成功
当前的波特率: 115200
正在擦除目标区域 ... 完成 !
芯片出厂序列号 : F757C465094F53
正在下载用户代码 ... 完成 !
正在设置硬件选项 ... 完成 !
更新后的硬件选项为:
. 内部IRC振荡器的频率: 11.062MHz
. 掉电唤醒定时器的频率: 35.475KHz
. 振荡器放大增益使能
. P3.2和P3.3与下次下载无关
. 上电复位时增加额外的复位延时
. 复位引脚用作普通I/O口
. 检测到低压时复位
. 低压检测门槛电压 : 2.00 V
. 上电复位时,硬件不启动内部看门狗
. 上电自动启动内部看门狗时的预分频数为 : 256
. 空闲状态时看门狗定时器停止计数
. 启动看门狗后,软件可以修改分频数,但不能关闭看门狗
. 下次下载用户程序时,将用户EEPROM区一并擦除
. 下次下载用户程序时,没有相关的端口控制485
. 下次下载时不需要校验下载口令
. 内部参考电压: 1195 mV (参考范围: 1100~1300mV)
. 内部安排测试时间: 2020年3月16日
. 芯片出厂序列号 : F757C465094F53
单片机型号: STC8G1K17-20/16PIN
固件版本号: 7.3.10U
. 用户设定频率: 11.059MHz
. 调节后的频率: 11.062MHz
. 频率调节误差: 0.022%
操作成功 !(2021-01-30 09:03:39) mPiDDR 发表于 2021-1-30 09:00
是的,我也不会这样写。但是为了方便大家看得清楚、
目前经过折腾 可以确定的是: 是在接收的时候出现丢 ...
楼主,你仔细看看,这个和你写的是一样吗? 本帖最后由 mPiDDR 于 2021-1-30 09:48 编辑
youkebing 发表于 2021-1-30 09:34
楼主,你仔细看看,这个和你写的是一样吗?
大致说一下吧,整个硬件串口1 专用下载的,串口2我用来与主控制器通信。
目前测试,在9600下,串口2的丢码率高于串口1。
谢谢你的提醒。因为串口2丢码的情况下,我才去调的串口1 想对比看。结果很失望
void Uart2Init()
{
S2CON = 0x10;
T2L = BRT;
T2H = BRT >> 8;
AUXR = 0x14;
busy = 0;
TMOD = 0x00;//UART1
SCON = 0x50;
AUXR |= 0x40;
TL1 = BRT;
TH1 = BRT >> 8;
TR1 = 1;
wptr = 0x00;
rptr = 0x00;
busy0 = 0;
}
ps :
11.592M 确是我打字错了 实际代码中。
#define FOSC 11059200UL//22118400UL//
#define BRT (65536 - FOSC / 9600 / 4)
>>>程序从ISP下载软件复制过来的,时钟11.592M,波特率设置的9600,
. 用户设定频率: 11.059MHz
. 调节后的频率: 11.062MHz
. 频率调节误差: 0.022%
11.592M、11.0592M,总感觉好神奇 mPiDDR 发表于 2021-1-30 09:45
大致说一下吧,整个硬件串口1 专用下载的,串口2我用来与主控制器通信。
目前测试,在9600下,串口2的丢 ...
上次买过一个小板,晚上抽空测试一下 mPiDDR 发表于 2021-1-30 09:05
由于对STC8 不熟悉,下载程序的界面也一并截图,看哪里有不对的
方便的话,把你的测试工程也发上来,我一会测试一下看看,我就不用重新建项目了‘ 为什么不用个数组先接收完全部数据后,再一一发出呢? 这样收到就发,收到就发.串口时序不会错乱吗? mPiDDR 发表于 2021-1-30 09:45
大致说一下吧,整个硬件串口1 专用下载的,串口2我用来与主控制器通信。
目前测试,在9600下,串口2的丢 ...
刚才随便找了个程序测试,我都是正常的,完全没有丢包,我的单片机型号: STC8G1K08-20/16PIN 在SBUF = rx上面加入TI=0试试,印象中51的标准串口写SBUF时必须要确保TI已清除,而你这程序存在执行SBUF = rx时TI为1的可能 youkebing 发表于 2021-1-30 10:42
方便的话,把你的测试工程也发上来,我一会测试一下看看,我就不用重新建项目了‘ ...
问题找到了。
uint8_t UART2_Read(uint8_t* dat){
if(rptr == wptr)return 0;
dat = ucUartRxbuf;
rptr &= 0x3f;
return 1; //之前省了此处 属于代码bug
}
总结一下,STC8G 不能在中断里直接发送。STC8A却可以?
现在使用FIFO接收处理,已无丢失数据。
感谢 楼上各位的回复。
再次证明STC处理器 宇宙最强。
附工程代码。
mPiDDR 发表于 2021-1-30 09:45
大致说一下吧,整个硬件串口1 专用下载的,串口2我用来与主控制器通信。
目前测试,在9600下,串口2的丢 ...
上传个测试图片
mPiDDR 发表于 2021-1-30 11:38
问题找到了。
uint8_t UART2_Read(uint8_t* dat){
if(rptr == wptr)return 0;
既然找到原因了,那我就不测试了 youkebing 发表于 2021-1-30 11:46
既然找到原因了,那我就不测试了
找到什么呀,“STC8G 不能在中断里直接发送”,想想可能不可能 “STC8G 不能在中断里直接发送”,这个结论不可能吧? fxhfxh 发表于 2021-1-30 14:26
“STC8G 不能在中断里直接发送”,这个结论不可能吧?
可以在中断里发,但是会有机率丢失数据, 这样的回答更严谨吧
具体看上面的代码,只希望这样的情况,只出现在个别的芯片。至少我手上的块是这样。
mPiDDR 发表于 2021-1-30 15:53
可以在中断里发,但是会有机率丢失数据, 这样的回答更严谨吧
具体看上面的代码,只希望这样的情况,只出 ...
好的,手上也有8G的芯片,有时间了,在中断里收发试一试。 mPiDDR 发表于 2021-1-30 15:53
可以在中断里发,但是会有机率丢失数据, 这样的回答更严谨吧
具体看上面的代码,只希望这样的情况,只出 ...
我的测试程序就在中断里发的 宇宙最强STC处理器 肯定不会存在如此问题了,不然怎么叫宇宙最强 youkebing 发表于 2021-1-30 11:43
上传个测试图片
你这个代码可以共享一下吗?谢谢 中断里发送的前提是 清除 发送完毕的标志位(sfr)。
然后 把数据放到sbuf里面。最后会发出去 检查硬件。
tx,rx的线尽量短,太长了就会发生错误。 检查硬件。
tx,rx的线尽量短,太长了就会发生错误。 mangolu 发表于 2021-1-31 04:13
你这个代码可以共享一下吗?谢谢
就是官方的例程 youkebing 发表于 2021-1-31 09:38
就是官方的例程
不懂是官方哪个例程?我其实不是STC,最近也发现丢失数据,我程序写得不好吧,所以想参考一下。 mangolu 发表于 2021-1-31 10:01
不懂是官方哪个例程?我其实不是STC,最近也发现丢失数据,我程序写得不好吧,所以想参考一下。 ...
第6个例程(06-串口1中断模式与电脑收发测试),你参考一下吧
youkebing 发表于 2021-1-31 19:05
第6个例程(06-串口1中断模式与电脑收发测试),你参考一下吧
好的,谢谢 不要使用中断方式发送数据
页:
[1]