This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Dear TI expert,
Now i am designing a BMS with use MSP430F1611 UART1 communication with one host, the host use modbus protocol, only two device, so i use the asynchronous communication formats, the idle-line format is used for the protocol.
the serial port configuration as follow: baud rate is 9600, data bit is 8, no parity bit, two stop bit
the modbus protocol like this:0x01 0x03 addresshi addresslo numhi numlo crc16lo crc16hi
the uart1 configure as follow:
void VMU_UART_INIT_9600 (void)
{
BCSCTL1 |= XTS; //high frequency mode
UCTL1 |= SWRST; // Initial uart
UTCTL1 = SSEL0; // ACLk(32768), default charactor, not address
UBR01 = 0xC0; //Baud rate :9600 ACLK: 1843200/192 = 9600
UBR11 = 0x00;
UMCTL1 = 0x00;
UCTL1 |= CHAR + SPB; //8 bit, no parity check, two stop bits
P3SEL |= 0xc0; //P3.7 RX,P3.6 TX
P3DIR |= 0x40;
P5DIR |= BIT4; // Transceiver DE,RE enable
P5OUT &= ~BIT4; // DE=0, R/E/=0 RX is default state, not TX
UCTL1 &= ~SWRST; // start uart
ME2 = UTXE1 + URXE1; // uart1 tx and rx module enable
IE2 |= URXIE1;
}
ISR receive as follows:
Since I can't judge the start and end of a packet, my idea is to wait for the next byte to be set to URXIFG and read the receive buffer register when the first byte received is 0x01, 1200 is timeout value
#pragma vector=UART1RX_VECTOR
__interrupt void RX_VMU_BYTE (void)
{
U8 i;
U16 time;
VMURS485Buf[0]=RXBUF1;
if (VMURS485Buf[0] == 0x01)
{
for (time =0; time <1200 && !(IFG2&URXIFG1); time++)
if (time < 1200)
VMURS485Buf[1]= RXBUF1;
if (VMURS485Buf[1] == 0x03)
{
for (i = 2; i < 8; i++)
{
for (time =0; time <1200 && !(IFG2&URXIFG1); time++)
if (time < 1200)
VMURS485Buf[i] = RXBUF1;
}
}
UART_Response(VMURS485Buf);
}
}
when i use the serialport software send command 0x01 0x03 0x00 0x01 0x00 0x06 crclo crchi
but VMURS485Buf[1]= RXBUF1; is 0x01 not 0x03
the value 1200 is timeout
Hi,
The timeout value 1200 is your max length of UART data?
Have you try receive all data store in table, those is correct? right?
I think if you would like use 0x01 as the first byte, you just use this code is OK:
if(RXBUF1 == 0x01) { } then { }
Thanks!
Best Regards
Johnson
The timeout value 1200 is your max length of UART data?
yes, the timeout less than 1200
Have you try receive all data store in table, those is correct? right?
VMURS485Buf[VMU_Rec_Num] = RXBUF1;
if (VMU_Rec_Num < MAX_SIZE)
{
VMU_Rec_Num++;
}
in isr, i use the above code, no problem
I think if you would like use 0x01 as the first byte, you just use this code is OK:
i will try
the follow code, i used in multiprocess address bit, no problem, runs ok,i do not why use asynchronous communication formats failed.
#pragma vector=UART0RX_VECTOR
__interrupt void UART0_RX0 () {
U8 i;
U16 time;
//U16 TempCRC;
if(URCTL0&URXWIE){
i=Buffer_URX;
if((i ==RAM_Module_ID)){ //add broadcast
URCTL0&=~URXWIE;
for(time=0;(time<UART_Time_out)&&!(IFG1&URXIFG0);time++);
if(time<UART_Time_out) {
Recdata[0]=Buffer_URX;
if(i ==RAM_Module_ID){
if(Recdata[0]==3){
for(i=1;i<7;i++){
for(time=0;(time<UART_Time_out)&&!(IFG1&URXIFG0);time++);
if(time<UART_Time_out)
Recdata[i]=Buffer_URX;else i=7;
}
}else
{
MMAddr0_Enble();
return;
}
This is a horrible way to receive serial data. Stuck in an ISR until the packet is complete. Yuck. I wrote an interrupt driven packet receiver using a state machine. When a complete packet arrives, the ISR sends a message to the main routine.
I have to wonder about those MCLK dependent timeouts. What is MCLK? Is the timeout period sufficiently greater than a character time? Why not use __delay_cycles()?
Get the thing working without timeouts first.
Another thing to look at is your RS485 receiver. When nothing is driving the bus, does it return to a MARK (logic high) state? If it floats or does other odd things then the UART may be busy receiving garbage when you send the first character.
**Attention** This is a public forum