TI中文支持网
TI专业的中文技术问题搜集分享网站

cc2530中UART转RS485,RS485通讯方向的控制问题

如图所示,P0.0控制RS485的收发.。高电平发送数据,低电平接收数据。

UART转RS485的方法是发送前将P0.0置为高电平,发送完成后置为低电平。

我是在DMA发送完成的中断里加入的P0.0置低控制  P0 &= ~0x01;(见下面的图)

现在的问题是数据还没有发完,P0.0就变成低电平了,这样就导致了UART上的数据不能从RS485总线上发送出去。

P0 &= ~0x01;这一句究竟应该放在哪里?希望得到各位的帮助

ZIGBEE协议栈用的是2.3.0-1.4.0

VV:

你好,

如果在Tx Done的中断里面不加 P0 &= ~0x01的话,应该是可以把数据发送完成的对吧?

把DMA传输的MOSI信号和P0.0信号都放在示波器上看,应该在DMA一次发送过程中P0.0的信号一直为高的,对吗?还是说一次发送还没完成,P0.0就变低了?

比方说你传输10个字节,P0.0的变低是在什么位置?

关于DMA的配置是否有问题?

lu zhizhong:

回复 VV:

你好,谢谢你的回答。

不管在Tx Done的中断里加不加P0 &=~0x01,数据都是可以发送的。(uart波特率设置的9600)

把P0 &=~0x01加到Tx Done的中断里,在示波器上测发送引脚P0.3和485控制引脚P0.0,P0.0的高电平在数据还没发出时就变低了,如下图所示:

如果中断里不加P0 &=~0x01这句,P0.0就不会有电平变化,说明中断是执行了。我现在觉得这个中断是DMA将待发送到数据搬运到UART的BUFFER中产生的,但UART模块还没有将数据发送出去,但是DMA的中断却将P0.0提前变低了。不知道我理解的对不对?所以我认为要找的应该是UART发送完成的中断,但UART好像又没有设置中断,所以现在该如何解决这个问题,没有头绪了。

DMA的配置如下:

/****************************************************************************** * @fn HalUARTInitDMA * * @brief Initialize the UART * * @param none * * @return none *****************************************************************************/static void HalUARTInitDMA(void){ halDMADesc_t *ch;

P2DIR &= ~P2DIR_PRIPO; P2DIR |= HAL_UART_PRIPO;

#if (HAL_UART_DMA == 1) PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O to Alt. 1 location on P0.#else PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O to Alt. 2 location on P1.#endif PxSEL |= UxRX_TX; // Enable Tx and Rx peripheral functions on pins. ADCCFG &= ~UxRX_TX; // Make sure ADC doesnt use this. UxCSR = CSR_MODE; // Mode is UART Mode. UxUCR = UCR_FLUSH; // Flush it.

// Setup Tx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX );

// The start address of the destination. HAL_DMA_SET_DEST( ch, DMA_UDBUF );

// Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

// One byte is transferred each time. HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE );

// The bytes are transferred 1-by-1 on Tx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX );

// The source address is incremented by 1 byte after each transfer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 );

// The destination address is constant – the Tx Data Buffer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 );

// The DMA Tx done is serviced by ISR in order to maintain full thruput. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE );

// Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

// DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH );

// Setup Rx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX );

// The start address of the source. HAL_DMA_SET_SOURCE( ch, DMA_UDBUF );

// Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

/* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx. * The byte after the Rx Data Buffer is the Baud Cfg Register, * which always has a known value. So init Rx buffer to inverse of that * known value. DMA word xfer will flip the bytes, so every valid Rx byte * in the Rx buffer will be preceded by a DMA_PAD char equal to the * Baud Cfg Register value. */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD );

// The bytes are transferred 1-by-1 on Rx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX );

// The source address is constant – the Rx Data Buffer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 );

// The destination address is incremented by 1 word after each transfer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 ); HAL_DMA_SET_DEST( ch, dmaCfg.rxBuf ); HAL_DMA_SET_LEN( ch, HAL_UART_DMA_RX_MAX );

// The DMA is to be polled and shall not issue an IRQ upon completion. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE );

// Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

// DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH );}

lu zhizhong:

回复 VV:

又用示波器测试了一下,测试结果如下:

1.发送一个字节时

2.发送两个字节时

3.发送四个字节

4.发送更多数据时

lu zhizhong:

回复 lu zhizhong:

哪位大神出来指点一下

xin kuang:

回复 lu zhizhong:

您好!请问您的MAX485控制问题解决了吗?我也遇到同样问题。还希望您多多赐教。我的邮箱puyunxk@163.com.QQ879882500

lu zhizhong:

回复 xin kuang:

DMA的方式没能解决,后来改成中断的方式就可以了

guang zhang:

回复 lu zhizhong:

我也遇到了类似的问题,我的是无法接收,改用中断单独写程序可以接收,在协议栈中就不知道如何入手了,楼主可以指点一下吗?谢谢 qq372160080

luzhizhong:

回复 guang zhang:

你也是用的485芯片吗?最好先排除485的问题,绕过485测试一下2530芯片串口输入引脚的波形是否正常。

guang zhang:

回复 luzhizhong:

刚开始是3485的问题,后来改好了,不用协议栈单独写发送接收程序都可以,协议栈不知道往哪里写程序,实现不了。。

luzhizhong:

回复 guang zhang:

像HalUARTWrite,HalUARTRead是协议栈基本的函数,直接用就可以了。如果这个也不知道的话恐怕别人也不知道怎么帮助你。

赞(0)
未经允许不得转载:TI中文支持网 » cc2530中UART转RS485,RS485通讯方向的控制问题
分享到: 更多 (0)