的想法:我想建立公司发射机和接收机之间的通信;公司的一些基本的错误处理。我想实现ACK(确认)/纳(negative-acknowledgement)的错误处理方式。我目前只传输数据从一个设备(PIC18F46K80)和接收它与另一个(PIC18F452)发射机(T)发送“有用的”数据和接收方(右)接受数据和发送回发射机应答或纳克每字节的数据发送。
设置:因为有点复杂,我做了流程图为每个发射机和接收机(只有代码的主要方面考虑)。
这是代码发射机(PIC18F46K80)。代码接收方并不相同,但类似于这一个。我也使用LED显示程序执行的当前位置(例如,当程序遍历“错误”路径或者当遍历“正常运行”路径)和接收的数据解释(LED条形图并行连接PORTD)但这是不包括在这里(改善代码的可读性):
代码的解释:从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线(发射机)高。
主持人注意:代码标记用于代码
设置:因为有点复杂,我做了流程图为每个发射机和接收机(只有代码的主要方面考虑)。
这是代码发射机(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()为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线(发射机)高。
主持人注意:代码标记用于代码
附件
-
237.8 KB 观点:9
-
4.1 KB 观点:1
-
4 KB 观点:0
主持人:最后编辑的