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.

MSP430F2618串口UART模式下RS485通信不成功

Other Parts Discussed in Thread: MSP430F2618

MCU:MSP430F2618

RS485接口芯片:MAX3485

采用第三方开发板作为主机(MCU),从机为一个RS485协议的气体传感器模块

通信要求:通用 R S 4 8 5 总线,所有控制板连接在一条 R S 4 8 5 总线上;

通信方式:通用异步接收 /发送( UART),波特率为 9 60 0,数据位为 8 位, 1 位停止位,偶校验;
我写的的程序主要函数如下,完整程序在附件里,看不出问题出在哪里,就是不能成功实现RS485通信,主机发送指令后,从机返回的数据无法接收到,到底是主机发送格式的问题,还是从机返回数据主机没收到,我无法判断出来,请专家帮忙看看,谢了!

//*************************************************************************
// 系统时钟初始化
//*************************************************************************
void Clock_Init()
{
BCSCTL1 &= ~XT2OFF; //打开XT2振荡器
BCSCTL3 |= XT2S_2; // Mode 2 for XT2 : 3 - 16 MHz
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (uint i = 0xFF; i > 0; i--); // Time for flag to set
}
while (IFG1 & OFIFG); // OSCFault flag still set?
IFG1 &= ~OFIFG;
BCSCTL2 |= SELM_2+SELS; //MCLK为8MHZ,SMCLK为8MHZ
}

//***********************************************************************
// MSP430串口初始化
//*************************************************************************
void UART_Init()
{
UCA1CTL1 |= UCSWRST;
UCA1CTL0 |= UCPEN + UCPAR; //奇偶校验被启用,偶校验,8位数据模式

UCA1CTL1 |= UCSSEL_2; //SMCLK为串口时钟 + UCBRKIE
UCA1BR0 = 0x34; //波特率设置
UCA1BR1 = 0x00; //9600bps@8MHz
UCA1MCTL |= UCBRF_1+UCOS16;
/*
UCA1CTL1 |= UCSSEL_1; // CLK = ACLK
UCA1BR0 = 0x03; // 32kHz/9600 = 3.41
UCA1BR1 = 0x00; //
UCA1MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3
*/
P3SEL|= BIT6 + BIT7; //设置IO口为第二功能模式,启用UART功能
P3DIR|= BIT6; //设置TXD1口方向为输出
UCA1CTL1 &= ~UCSWRST;
UC1IE |= UCA1RXIE; //接收中断启用
}

//***********************************************************************
// CRC16 码直接计算法
//*pSendBuf:首字节指针
//nEnd:数据校验长度
//*************************************************************************
unsigned int GetCheck(unsigned char *pSendBuf,unsigned char nEnd)
{
unsigned char i,j;
unsigned int wCrc = (unsigned int)(0xffff);
for(i = 0;i<nEnd;i++)
{
wCrc ^= (unsigned int)(pSendBuf[i]);
for(j = 0;j<8;j++)
{
if(wCrc&0x01)
{
wCrc >>=1;
wCrc ^= 0xA001;
}
else wCrc >>=1;
}
}
return wCrc;
}

//*************************************************************************
// 串口1发送数据函数
//*************************************************************************

void Send_Byte(uchar data)
{
while(!(UC1IFG & UCA1TXIFG)); //发送寄存器空的时候发送数据
UCA1TXBUF = data;
}

//*************************************************************************
// 串口1发送字符串函数
//*************************************************************************
void Send_CMD(uchar *s,uchar n)
{
uint crc16;
crc16 = GetCheck(s,n-2); //CRC16校验
s[n-2] = crc16 & 0xff; //校验低
s[n-1] = (crc16>>8) & 0xff; //校验高
RS485_CTR1; //切换到发送状态
// delay_us(100);
for(uchar i=0;i<n;i++)
{
Send_Byte(s[i]);
}
while(!(UC1IFG & UCA1TXIFG));
// delay_us(200);
RS485_CTR0; //切换到接收状态
}


RS485.7z
  • 我用示波器观察了MAX3485的RS485信号输出,与我程序中设定的一样,问题可能是出现在发送与接收模式的切换上,我发现发完数据后切换到接收模式,接收数据线上存在中间电平状态,就是基于高低电平信号之间,很奇怪,估计通信错误就是这个产生的,但这到底是什么原因造成的?

  • 我也遇到和你相似的问题,我是利用STM32做了其他几块功能板卡,STM32板卡之间利用485通信正常,一旦我把利用430做的功能板卡插入设备中整个485总线通信就无法被识别了(利用示波器能观测到波形),我不存在收发电平转换(我利用了两个MAX485芯片:一收一发)。希望可以交流一下。

  • 您好,请问您的问题解决了吗?这个收发模式到底怎么切换,我的485通讯也是用的max3485,现在通信也有点问题,希望能交流下。谢谢!

  • 这类通讯类的问题,没有太好的办法,建议用逻辑分析仪观察一下时序

  • 我最近也遇到这个问题了,特点是MSP430发送的最后一个字符串恒为FF。

    问题就出在把RS485芯片切换为接受状态的时机。

    判断的是IFGX寄存器的UCA0TXIFG 位是否被置位,然而该位被置位只是表示UCAXTXBUF 为空,可以发送下一位,实际上这时数据仍然在移位寄存器中发送,这时把RS485切换为中断就会导致最后一个字符接受错误。

    应该改为判断UCAxSTAT寄存器(状态寄存器)的UCBUSY位,该位是指示USCI是否正在发送或者接受,这样就可以了。

    我也是翻了用户指南才了解的。