所有关于电路

为每个字节UART通信ACK /纳

鲁卡

线程启动

鲁卡

加入1月25日,2018年
12
我的意思是,你的计划在实践中不能使用的通道更可靠,因为它是完全天真的和低效的。串行连接的误比特率是众所周知的了。处理这些问题的方案,这看起来不像你也记录了无处不在。甚至天真的计划,至少使用的数据块将更有意义。你“纠正”的错误冗余如果你检查实际数据的错误。一个简单的校验和,或通过CRC数据会让你开始在可靠的数据传输。

包的大小可以被预期的误码率计算(比特误码率)的通道。我真的认为你会找到更多的学习做一个简单但实用的误差修正方案。
如果有任何好的源关于纠错UART(或相似的)交流我会乐意深入它,了解现实生活实际系统实现UART通信工作。但是我还没有找到关于这个话题即使我真的寻找它。

目前,只有错误检查是在硬件层面上——这是框架和泛滥。你建议我应该专注于基于软件纠错校验和和CRC和忽略硬件基础的(被微处理器的内部逻辑)?
班

加入,2019年1月27日
2829年
如果有任何好的源关于纠错UART(或相似的)交流我会乐意深入它,了解现实生活实际系统实现UART通信工作。但是我还没有找到关于这个话题即使我真的寻找它。

目前,只有错误检查是在硬件层面上——这是框架和泛滥。你建议我应该专注于基于软件纠错校验和和CRC和忽略硬件基础的(被微处理器的内部逻辑)?
这是精确的我建议什么。你可以从这里开始:

https://users.ece.cmu.edu/ ~•库普曼/ des_s99 /编码/

如果你需要深入概念,你会知道关键字寻找其他来源。错误检测和校正的基本原理不改变基于物理层。你会学到更多如果你试图让类似的描述文档。

我希望它有帮助。
Papabravo

Papabravo

2006年加入2月24日
15643年
如果框架(FERR)或溢出(OERR)错误发生在接收数据时,接收器传输NACK,否则ACK。

如果有其他任何澄清,我愿意解释。,)
我有一个职业生涯跨越了半个世纪。在所有的时候,我可以计算框架和溢出错误结合在一只手的手指。可行的方法来创建它们的唯一方法就是故意的。你在浪费你的时间与这一个。
鲁卡

线程启动

鲁卡

加入1月25日,2018年
12
我有一个职业生涯跨越了半个世纪。在所有的时候,我可以计算框架和溢出错误结合在一只手的手指。可行的方法来创建它们的唯一方法就是故意的。你在浪费你的时间与这一个。
哦,好的。像我这样的人很难与现实世界零经验假设框架或溢出不会导致任何问题。
所以只有的错误处理方式,真正重要的是数据完整性验证(使用CRC、校验和奇偶校验等)?
MrChips

MrChips

10月2日,2009年加入
23192年
UART可能不会使用这些天,但在我看来是足够好的。我不是说我要用它控制航天飞机. .
我不知道你有这种印象。UART串行通信在日常使用数量巨大的装置。

学习如何与uart串行通讯是一个很好的起点。你需要后退一步,三个步骤向前为了理解如何实现安全的数字通信。

后退一步
学习如何发送和接收一个字节。
学习在一个字节错误检测和校正方案。了解奇偶校验,冗余。
学习在n个字节错误检测和校正方案。了解横向和纵向平价、CRC校验和错误校正码。

三个步骤向前
没人会实现ACK /纳单一字节传输因为效率低下的人已经指出。数据将发送数据包。研究包传输。想象在互联网上通信。如何发送方知道包是不正确/正确接收,必须重新发送/继续传播?
MrChips

MrChips

10月2日,2009年加入
23192年
框架的错误,溢出错误,奇偶校验误差硬件传输问题很少发生。
当这些发生数据损坏。

你需要3个步骤和实施安全包级别的错误检测和校正。

作为一个例子,当一个数据包传输时,它能被发送到100种不同的设备。你的设备是如何知道它是预期的接收者时,数据包被损坏?
djsfantasi

djsfantasi

2010年加入4月11日
7605年
框架的错误,溢出错误,奇偶校验误差硬件传输问题很少发生。
当这些发生数据损坏。

你需要3个步骤和实施安全包级别的错误检测和校正。

作为一个例子,当一个数据包传输时,它能被发送到100种不同的设备。你的设备是如何知道它是预期的接收者时,数据包被损坏?
我想因为他是只使用两个设备在自我教育项目。beplay网页版本
BobaMosfet

BobaMosfet

于2009年7月1日加入欧盟
1587年
@Lu Ka你想做什么没有什么不妥。你想学习你有很多,你想要回答许多问题,需要耐心。

你在说什么叫做“握手”。你必须确定你想使用“协议”。这个协议应该描述:

碰撞检测
错误指示/校正
数据包大小
计时方法

你可以同步(时间)或异步交流(不需要或共享时间模型)。听起来你想要的是asych——为了做到这一点,您必须创建逻辑允许双方确定发生了什么,和约束时,每一方都是有一个失败,如x秒后超时,并重新开始。

你在做你的框架/错误检测?如果是这样,你必须设计。如果你让UART这么做——根据其能力——这可能是透明的。

沟通并不难,它只是脉冲。但是由于你正在与_signals_你需要明白信号电压参考,和电流提供足够的能量信号旅行给定导体的长度。你允许电流越少,较弱的信号,更容易出错,或甚至使它。太多,你可以得到一个反弹——一个阻抗失配。

你需要看数据表,并理解它,您正在使用的单片机及其UART,这样您就可以满足电气要求设计者需要你跟进。代码_logic_之外。
ApacheKid

ApacheKid

加入1月12日,2015年
385年
的想法:我想建立公司发射机和接收机之间的通信;公司的一些基本的错误处理。我想实现ACK(确认)/纳(negative-acknowledgement)的错误处理方式。我目前只传输数据从一个设备(PIC18F46K80)和接收它与另一个(PIC18F452)发射机(T)发送“有用的”数据和接收方(右)接受数据和发送回发射机应答或纳克每字节的数据发送。

设置:因为有点复杂,我做了流程图为每个发射机和接收机(只有代码的主要方面考虑)。

查看附件233461

这是代码发射机(PIC18F46K80)。代码接收方并不相同,但类似于这一个。我也使用LED显示程序执行的当前位置(例如,当程序遍历“错误”路径或者当遍历“正常运行”路径)和接收的数据解释(LED条形图并行连接PORTD)但这是不包括在这里(改善代码的可读性):

C:
# include < xc。h > # include < stdint。h > # include < stdbool。h > # include " config_bits。h”空白osc_initialize(无效);空白uart_initialize(无效);空白uart_receive (uint8_t * c);空白uart_transmit (uint8_t * c);空白__interrupt () high_isr(无效);uint8_t data_rec; // received data storage variable uint8_t isr_flag = 0; // used to indicate completion of ISR uint8_t ack = 0x06; // acknowledgement code uint8_t nack = 0x15; // negative acknowledgement code // INTIALIZE INTERNAL OSCILLATOR REGISTERS void osc_initialize(void){ OSCCONbits.SCS = 0b10; // set internal oscillator block OSCCONbits.IRCF = 0b101; // set clock frequency to 4MHz while(OSCCONbits.HFIOFS == 0); // wait for oscillator frequency to stabilize } // INITIALIZE UART REGISTERS void uart_initialize(void){ // RX and TX inputs port initialization TRISDbits.TRISD6 = 1; TRISDbits.TRISD7 = 1; SPBRG2 = 25; // SPBRG = ((F_osc/BaudRate)/64)-1 => at F_osc = 4MHz, BaudRate = 2400, low speed TXSTA2bits.BRGH = 0; // 8-bit data mode setting for transmitter/receiver TXSTA2bits.SYNC = 0; // asynchronous mode RCSTA2bits.SPEN = 1; // RX and TX set as serial port pins TXSTA2bits.TXEN = 1; // transmitter enable RCSTA2bits.CREN = 1; // receiver enable INTCONbits.GIEH = 1; // must be set for HP interrupt to be generated INTCONbits.GIEL = 1; // must be set for LP interrupt to be generated PIE3bits.RC2IE = 1; // enable USART receive interrupt } // UART TRANSMISSION FUNCTION void uart_transmit(uint8_t *tran){ do{ TXREG2 = *tran; // load the value of "tran" into TXREG (data stored into TXREG, then send into TSR) while(TXSTAbits.TRMT == 0); // wait for data to be loaded into TSR and send while(isr_flag == 0); // loop is terminated after ISR isr_flag = 0; // reset "isr_flag" } while(data_rec != ack); // got NACK (or anything else) -> re-transmit current data } // UART RECEPTION FUNCTION void uart_receive(uint8_t *rec){ // MAIN ERROR - overrun if(RCSTA2bits.OERR){ RCSTA2bits.CREN = 0; // to clear error, reception module must be reset RCSTA2bits.CREN = 1; RCREG2; // dummy read - part of module reset RCREG2; // dummy read *rec = nack; // current setting: if(OERR); discard data and re-transimission } // MINOR ERROR - framing else if(RCSTA2bits.FERR){ RCREG2; // dummy read - part of module reset *rec = nack; // current setting: if(FERR); discard data and re-transmission } // NORMAL OPERATION else{ *rec = RCREG2; // store received data to "rec" } } // ISR WHEN REQUEST FOR RECEPTION HAPPENS void __interrupt() high_isr(void){ INTCONbits.GIEH = 0; if(PIR3bits.RC2IF){ uart_receive(&data_rec); isr_flag = 1; } INTCONbits.GIEH = 1; } void main(void) { TRISC = 0; TRISD = 0; LATC = 0; LATD = 0; osc_initialize(); uart_initialize(); uint8_t data_tran[] = {"ABCDE"}; //character set to be transmitted while(1){ for(int i = 0; data_tran; i++){ // GENERATE DELAY WHILE CONTINUOUSLY CALL TRANSMISSION for(float j = 0; j < 5; j += 0.1){ uart_transmit(&data_tran); } } } return; }
代码的解释:从main(),我呼吁uart_transmit()函数,它传送一个字符的时间(和产生足够的延迟,所以我可以观察到数据传输LED条形图(连续接收的数据并行输出PORTD))。字符发送后,发射机只是从接收器等待ACK的传播或纳——如果它ACK,传递下一个字符;如果它被纳,重新发送当前字符直到ACK。
至于接收机,它等待在main()为ISR请求(循环)。数据加载到RSR登记后,uart_read()函数执行。如果收到的数据没有任何错误,数据输出PORTD,发送ACK发射机和程序返回主()。如果有一个错误关于接待的性格,PORTD数据保持不变(错误数据被丢弃),纳发送到发射机和程序返回主要(),在那里等待重新传输的性格。

现实生活中实现:首先,程序甚至不会正确地开始,如果TX和RX线路(设备)的两边不稍微加载(添加1 m欧姆电阻接地在双方两针)。否则,项目按预期的方式工作,如果没有特殊事件,如隔离的数据行(和触发的FERR发射机或接收机模拟错误处理)。如果发生这种情况,领导表明程序遍历“错误”路径无关的但是当我往回连接线路,路径回到“正常运行”只不时(这是最奇怪的事实)。同时,重置两个设备同时也不时地工作。

结论(问题):我觉得有一些问题关于计时,当错误是(或应该是)复位和程序是(或应该)回到“正常运行”的道路。然而,我不能理解,我定时误差失踪。
字符传输后,F452等到TSR是空的(即使没有必要,因为它等待ACK /克)。F452接收到字符后,uart_receive()之后才RSR充满ACK /克”传播,uart_transmit()立即结束,而不是等待TMRT设置——因为项目需要回到uart_receive()然后回到ISR回主()在新的中断之前由于从46 k80重新传输。

考虑时间的事实,我真的自己不能进一步解决这个问题。

编辑:我意识到需要上拉电阻UART正常运作(RX不是捡噪音),但听觉后,现在该项目甚至不开始执行;也就是说,数据不会开始传输并没有显示任何错误。
另一个事实是,当它工作(如果没有使用电阻器),也应该从发射机传输的数据如果任何数据行断开连接;也就是说,如果任何错误触发。但它不是传播——只要任何错误出现,TX线(发射机)高。

主持人注意:代码标记用于代码
这里有很多,所以有很多失败和错误,我认为你是想太多,太多不同的东西在一个项目在同一时间。

如果你想要得到一些东西感觉像ack /纳也许流控制等等,然后尝试远离这些单片机和C等,得到一些理解没有不稳定的麻烦硬件或车低水平UART的代码。

这两个设备和全部或半双工通信吗?
T

trebla

加入2019年6月29日
316年
数组的定义data_tran []因为我想发送一个字符数组(当然一个接一个)。有什么不对吗?
如果你想发送一个字节数组fom()的每个周期之前你最好计算数组大小为()循环,然后使用数组大小为()循环条件检查。例如,您可以计算数组大小如下:

C:
tx_size = * (&data_tran + 1) - data_tran;
如果数据传输速度极低,只需要发送一个字节,然后你可以发送多次相同的字节(3)和每次读它。如果任何错误发生在传播你看到它通过比较主发送和接收的字节或比较所有接收机接收字节。这是非常简单的协议开始,当然它远非理想。您可以添加一些特殊序列启动,停止,电源和错误条件如果你想尝试UART迹象。有一些通信协议等单向传输LANC传输多次使用。
MrChips

MrChips

10月2日,2009年加入
23192年
TS是不打算实现任何有用的只是学习编程算法在使用UART串行通信。没有人应答/纳单一字节,因为它是低效的。相反,TS应该发送一个包,其中包括:

<开始> <消息> <校验和> < >结束

与平价包含在每个字节传送。

如果接收方收到一个有效数据包然后接收器发送ACK,否则接收器没有。
发射机使用超时作为指标,包是没有收到。

问题在于在任何应用程序时你必须坐下来考虑所有可能的故障场景,以设计一个算法工作。换句话说,问问你自己,如果什么?