我有一个与微控制器的“传输”相关的问题。微控制器可以接收,但无法发送。
这是我之前提出的问题的另一个问题[这里]
下面是与微控制器的 max485 接口:
这是我的代码快照:
// RS485
TRISBbits.TRISB6 = INPUT_PIN; // RX - RB6/RP38 PIN<42>
TRISBbits.TRISB7 = OUTPUT_PIN; // TX - RB7/RP39 PIN<43>
TRISBbits.TRISB8 = OUTPUT_PIN; // !RE/DE Control Pin RB8/RP40 PIN<44>
// RS485 Config
#define RS485_TX PORTBbits.RB6 // RS485 Transmitter
#define RS485_RX LATBbits.LATB7 // RS485 Reciever
#define RS485_CTRL LATBbits.LATB8 // RS485 Control Pin
// UART ISR
void __attribute__((interrupt, no_auto_psv)) _U4RXInterrupt(void)
{
rs485Char = U4RXREG;
RS485_CTRL = 1; // Enable driver
U4TXREG = rs485Char;
RS485_CTRL = 0; // disable driver RE/DO
}
void InitRs485(void){
// configure U1MODE
U4MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
U4MODEbits.URXINV = 1; // 1:URXINV Idle state is '0' ; 0=UxRX Idle state is '1';
U4MODEbits.ABAUD = 0; // Bit5 No Auto baud (would require sending '55')
U4MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U4MODEbits.PDSEL = 0; // 0 : 8 bit,no parity; 1 : 8 bit,even parity; 2 : 8 bit,odd parity; 3 : 9 bit,no Parity
U4MODEbits.STSEL = 1; // 1 : 2 Stop bits; 0 : 1 Stop bits
U4MODEbits.LPBACK = 0; // Lookback disable
U4STAbits.URXISEL = 0; // Interrupt flag bit is set when a character is received
// Load a value into Baud Rate Generator.
U4BRG = BRGVAL_RS485; // 60Mhz osc, 9600 Baud
// Load all values in for U1STA SFR
U4STAbits.UTXISEL1 = 0; // Bit15 Int when Char is transferred (1/2 config!)
U4STAbits.UTXISEL0 = 0; // Bit13 Other half of Bit15
U4STAbits.UTXINV = 1; // 1:UxTX Idle state is '0' ; 0=UxTX Idle state is '1';
U4STAbits.UTXBRK = 0; // Bit11 Disabled
U4STAbits.UTXEN = 0; // Bit10 TX pins controlled by peripheral
U4STAbits.URXISEL = 0; // Bits6,7 Int. on character received
IPC22bits.U4RXIP = 7;
IPC22bits.U4TXIP = 7;
IFS5bits.U4TXIF = 0; // Clear the Transmit Interrupt Flag
IEC5bits.U4TXIE = 0; // Enable Transmit Interrupts
IFS5bits.U4RXIF = 0; // Clear the Receive Interrupt Flag
IEC5bits.U4RXIE = 0; // Enable Receive Interrupts
RPOR2bits.RP39R = 0x1D; // dsPic33EP512GM604 => RP39 as U4TX PIN<43>
_U4RXR = 38; // dsPic33EP512GM604 => RP38 as U4RX PIN<42>
U4MODEbits.UARTEN = 1; // And turn the peripheral on
U4STAbits.UTXEN = 1;
// Hardware control bits
IEC5bits.U4RXIE = 1;
IFS5bits.U4RXIF = 0;
RS485_CTRL = 0; // disable driver; Receive Enable
}
在上面的代码中,我有一个 UART 接收中断例程。
每当接收到任何字符时,UART ISR 都会接收到它,但无法发送回任何内容。
在我的 ISR 中,我试图发回收到的字符。
此问题可能与 max485 控制引脚 (!RE/DE) 有关,在我的代码中称为RS485_CTRL 。
所以,我试图纠正这个问题,如下所示:
如果 ISR 写成
rs485Char = U4RXREG; RS485_CTRL = 1; // Enable driver U4TXREG = rs485Char;
然后微控制器发送2字节,第一个是接收到的字符,第二个字节是假字节,即。0x00之后,ISR 没有接收到任何字符。
如果 ISR 写成:
rs485Char = U4RXREG; RS485_CTRL = 0; // Disable driver U4TXREG = rs485Char; RS485_CTRL = 1; // Enable driver
比它传输接收到的第一个字符。但是在 ISR 进入无限循环之后,即。接收一个 NULL 字符并发送一个 NULL 字符。
根据 RS485 实施规则,
RS485_CTRL (!RE/DE) 应为 0 以接收数据
RS485_CTRL (!RE/DE) 应为 1 以传输数据。
我的微控制器充当从属设备,因此默认情况下我将其保持在监听模式。但是当收到数据时,我无法传输。
请帮我找出我的错误???
根据@linuxfan 给出的建议,正确的 ISR 应如下所示:
// UART ISR
void __attribute__((interrupt, no_auto_psv)) _U4RXInterrupt(void)
{
rs485Char = U4RXREG;
RS485_CTRL = 1; // Enable driver
U4TXREG = rs485Char;
while(!U4STAbits.TRMT); // wait until character is transffered successfully
RS485_CTRL = 0; // disable driver RE/DO
}
现在我的代码按预期工作正常。