C 如何通过UART发送多个端口的数据?

C 如何通过UART发送多个端口的数据?,c,microcontroller,pic,uart,C,Microcontroller,Pic,Uart,我已经更改了接收器的代码,但发射器基本相同,因此,在接收器中,我取消了中断,而是在循环中读取数据,每次检查RC2IF\u位的状态,检查的顺序与发射器发送数据的顺序相同,以确保哪个端口发送数据。 问题是在对Proteus的模拟中,当我接收到数据并输出到LED上时,它们工作得很好,数据被正确发送,但是在模拟的中间,当我观看它时,我发现它们改变状态一目了然,例如,如果我发送PORTA=0X2D收到相同的值,右侧LED亮起,但在一秒钟内熄灭,然后再次亮起,这是编写的代码中的问题吗 /*This is

我已经更改了接收器的代码,但发射器基本相同,因此,在接收器中,我取消了中断,而是在循环中读取数据,每次检查
RC2IF\u位的状态,检查的顺序与发射器发送数据的顺序相同,以确保哪个端口发送数据。
问题是在对Proteus的模拟中,当我接收到数据并输出到LED上时,它们工作得很好,数据被正确发送,但是在模拟的中间,当我观看它时,我发现它们改变状态一目了然,例如,如果我发送
PORTA=0X2D
收到相同的值,右侧LED亮起,但在一秒钟内熄灭,然后再次亮起,这是编写的代码中的问题吗

 /*This is the transmitter code*/
void UART2_TX_init ();      //UART2 transmission initialization function porototype
void SEND_data (int output);     //Send data function prototype


void main()
{
     ANSELA = 0X00;        //Disable analogue function on PORTA
     ANSELE = 0X00;        //Disable analogue function on PORTE
     ANSELF = 0X00;        //Disable analogue function on PORTF
     TRISA = 0XFF;         // SET PORTA AS INPUT (AUTOMATIC BUTTONS)
     TRISB = 0XFF;         //SET PORTB AS INPUT (OFF BUTTONS)
     TRISD = 0XFF;         //SET PORTD AS INPUT (MANUAL BUTTONS)
     TRISE = 0XFF;         //SET PORTE AS INPUT (HIGH BUTTONS)
     TRISF = 0XFF;         //SET PORTF AS INPUT (LOW BUTTONS)
     TRISC = 0XFF;         //SET PORTC AS INPUT (TRIP BUTTONS)
     TRISG0_bit = 0;    //set PORTC pin0 as output for MAX487 DE pin
     PORTG.F0= 1;      //set PORTC pin0 HIGH , set    MAX487 as transmitter.
     UART2_TX_init();      //call UART1 transmission initialization

     while (1)
     {
                SEND_data(PORTA);   //send data of automatic
                delay_ms(10);
               SEND_data(PORTB);    //send data of off
               delay_ms(10);
               SEND_data(PORTD);    //send daata of manual
               delay_ms(10);
               SEND_data(PORTE);   //send data of high
               delay_ms(10);
               SEND_data(PORTF);   //send data of low
               delay_ms(10);
               SEND_data(PORTC);   //send data of TRIP
               delay_ms(10);
    }
}

 /*This function takes the data needed to be send
   as an integer. Wait for the TSR to be empty and
   start the transmission*/

void SEND_data (int output)
{
         while (!TRMT_TX2STA_bit){};    //checks if TSR is empty or not if empty TRMT_BIT is set and write to transmit register
         TX2REG = output;        //write data to be send in the transmission register

}




/*This function initializes the UART2 as an asynchronous
 transmitter at a baud rate of 9600kbps*/

void UART2_TX_init ()
{
    BAUD2CON = 0X08;
    BRGH_TX2STA_bit = 1;
    SP2BRGL = 207;
    SYNC_TX2STA_bit = 0X00;
    SPEN_RC2STA_bit = 0X01;
    TRISG1_bit = 0X01;
    TRISG2_bit = 0X01;
    TXEN_TX2STA_bit = 0X01;

}




/*This is the receiver code*/
void UART2_RX_init ();   // Receiver initialization function prototype
void main()
{

     ANSELA = 0X00;       // Disable analog function on PORTA
     ANSELE = 0X00;       // Disable analog function on PORTE
     ANSELF = 0X00;       // Disable analog function on PORTF
     TRISA = 0X00;        //set PORTA as output
     TRISB = 0X00;        //set PORTB as output
     TRISD = 0X00;        //set PORTD as output
     TRISE = 0X00;        //set PORTE as output
     TRISF = 0X00;        //set PORTF as output
     TRISC = 0X00;        //set PORTF as output
     PORTA = 0x00;        //clear PORTA
     PORTB = 0x00;        //clear PORTB
     PORTD = 0x00;        //clear PORTD
     PORTE = 0x00;        //clear PORTE
     PORTF = 0x00;        //clear PORTF
     PORTC = 0x00;        //clear PORTC
     TRISG0_bit = 0x00;   //set PORTC pin0 as output for MAX487 RE pin
     PORTG.F0 = 0x00;     // set PORTC pin0 as LOW , set MAX487 as receiver
     UART2_RX_init();     //call receiver initialization function
     while (1)
     {
             while (!RC2IF_bit) ;      //check if the RCIF flag is up to tell if there is a new data
             PORTA =~ RC2REG;          //write the new data to the specified port
             while (!RC2IF_bit) ;
             PORTB =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTD =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTE =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTF =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTC =~ RC2REG;
     }


}
/*This function initializes UART2 as an asynchronous
  receiver at a baud rate of 9600kbps with continous
  reception NO INTERRUPT ON RECEIVE*/
void UART2_RX_init ()
{
    BAUD2CON = 0X08;
    BRGH_TX2STA_bit = 1;
    SP2BRGL = 207;
    SYNC_TX2STA_bit = 0X00;
    SPEN_RC2STA_bit = 0X01;
    TRISG1_bit = 0X01;
    TRISG2_bit = 0X01;
    CREN_RC2STA_bit = 0X01;
}

首先,我想说几句关于协议设计的话。任何通信协议,如果您希望它是可靠的,应该至少实现两件事:帧同步和错误检查。好的,有一些专门的协议不使用帧并将数据表示为连续流,但这绝对不是您的情况。所以,如果你不想搞乱奇怪的bug,我强烈建议你实现这些东西

现在谈谈你的代码。它看起来像是
GET_data
等待传输寄存器为空并向其写入一个字节。我看不出有什么问题。但是你的接收者看起来很可疑。您等待设置
RCIF
标志,然后从输入寄存器
RCREG
读取5次。但是非零的
RCIF
意味着您收到了一个字节。您不能等待一次
RCIF
,然后多次读取
RCREG
。在从
RCREG
读取之前,您应该等待
RCIF

我很乐意为您提供一个工作代码的示例,但我无法提供一个适合您当前体系结构的简单解决方案。 我可以给你举个例子,告诉你如何正确地做这件事,但它看起来会完全不同。

有些事情:

  • UART接收ISR应尽可能短,只需将数据写入缓冲区,且绝对不包含任何延迟例程
  • 对每个接收到的字节使用一个中断
  • 以startbyte开始您的帧。e、 g
    'S'
  • 以校验和字节结束帧
  • 在缓冲区中检测到完整的帧(开始字节+数据字节+正确的检查数)后,在主循环中进行端口写入

请在您的问题中添加更多细节,说明发生了什么以及您希望发生什么。“另一张图片上接收到的输出似乎闪烁且不稳定”,我不清楚。在不知道具体控制器的情况下,只需考虑一下:
中断的行为可能取决于时间。如果(RCIF\U位==1)
是什么意思?接收缓冲区中是否正好/至少有一个字节可用?假设
RCREG
读取最后接收的字节。有FIFO吗?如果还没有新数据呢?也许在
中断
中,您应该只读取1个字节,并使用一个静态计数器来决定哪个
端口..F
发送这个字节。整个想法是我想从一些交换机读取输入,每个端口上有五个交换机,然后通过UART将该数据发送到另一个PIC,在该PIC中,它打开相应端口的相应位。当我为任意三个端口发送数据时,程序工作正常,但当我添加另一个端口时,接收器上的指示灯持续闪烁,并且发送的数据未正确接收。切勿在接收中断中设置延迟。中断程序应该尽可能短。@aymanmagdy您应该将问题添加到更多信息中,而不是在注释中回答。我的问题也意在暗示你应该思考什么。正如其他人在答案中所写,您的协议需要同步。您的接收器实现可能多次读取相同的数据,这将导致数据写入错误的端口。如果有任何示例可以指导我,我将不胜感激。@aymanmagdy您是使用操作系统还是想要裸机解决方案?除了读写端口,你的程序还需要做其他事情吗?不,我只想读取端口的值,发送它,在接收器上读取它,等等其他端口。