如图所示,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是协议栈基本的函数,直接用就可以了。如果这个也不知道的话恐怕别人也不知道怎么帮助你。
TI中文支持网





