我发现串口发送时,最多128被字节。。。HAL_UART_DMA_RX_MAX 128;#define HAL_UART_DMA_TX_MAX HAL_UART_DMA_RX_MAX
我现在想在一次发送大于128个字节改怎么操作?
shaokai Lin:
Hi wengo
HAL_UART_DMA_RX_MAX是指DMA的接收缓冲。
只要你注册了DMA的事件回调函数,DMA有数据时就会通知你(可能是1个或者多个数据),这时你就可以去读取。
——一有数据就读走,不管多少个,不必等到所有数据都收齐了再去读。
而DMA能存的字节数自然由这个缓冲的大小决定,只要你能及时地读取数据,128字节是足够你使用的。
wengo wu:
回复 shaokai Lin:
怎么注册DMA事件回调啊?我知道有一个串口接收回调函数。。但是这个是接收后的。
我要发送到串口呢?
for(uint8 i=0;i<50;i++) { HalUARTWrite(0,"Hello",5); }我这么写之后,PC端串口接收不能显示50个Hello。。在1.4版本调用NPI_WriteTransport("Hello",5);这个也一样。
shaokai Lin:
回复 wengo wu:
在初始化串口DMA传输时,就需要传入回调函数的指针:
NPI_InitTransport(UART_DmaEvtCB);//初始化串口DMA传输、注册回调函数
发送串口数据也很方便:
NPI_WriteTransport("Hi wengo\n",sizeof("Hi wengo\n")-1);
//串口DMA传输事件回调函数static void UART_DmaEvtCB( uint8 port,uint8 event){
uint8 numbyte; if(event & HAL_UART_RX_TIMEOUT)//有数据等待接收 { //todo在此接收数据
} if(event & HAL_UART_TX_EMPTY)//发送完成 { //todo }}
da qin zheng sheng:
回复 wengo wu:
等待查询发送标志!否则缓冲区数据会自动被清除。
wengo wu:
回复 shaokai Lin:
不好意思,麻烦你了。。。我试了下,还是有问题啊,if(event & HAL_UART_TX_EMPTY)//发送完成。。这个确实是发送完成时进入的。。不能满足我的需求。
不知你试验了没,我有一堆数据要发送,我现在就简单点发50组Hello。
for(uint16 cnt=0;cnt<50;cnt++) { NPI_WriteTransport("Hello",sizeof("Hello")-1);
// delay(); }
1 但是实际上,PC端接收到
Hello…HelloBLE CentralTexas Instruments0x883314D6BA3D时,才进入if(event & HAL_UART_TX_EMPTY)。。。而此时,Hello并没有输出50组。程序已经运行到后面 打印Texas完成才进入回调函数。。
2 而如果我在delay打开后,就能完整打印50组Hello。。但是在打印期间加入延时,可能不是很好的办法。。
3 如果
for(uint16 cnt=0;cnt<50;cnt++){NPI_WriteTransport("Hello",sizeof("Hello")-1);
}
delay();
把延时函数放到for外面。。延时时间完成,也不能进入回调函数。。。说明如果我一次发多个字节,是不能调用到回调函数里面的事件的!!连发送完成事件也没触发。
4 if(event & HAL_UART_TX_EMPTY)//发送完成{ sendOKFlag = 1;}
我在里面加一个标志
{ NPI_WriteTransport("Hello",sizeof("Hello")-1); while(sendOKFlag==0); }为什么加while不能进入回调函数,一直挺在while里面。。一去掉while 就能进入发送完成的回调函数里面了??
wengo wu:
回复 shaokai Lin:
HI shaokai
谢谢你。。我明白了,肯定是数据阻塞了。。。看来我必须使用延时了,使用延时能完成发送数据的。。多谢!!!
shaokai Lin:
回复 wengo wu:
Hi wengo
如果你说的延时是指如下的做法,那么我不赞同这么做。
for(uint16 cnt=0;cnt<50;cnt++){NPI_WriteTransport("Hello",sizeof("Hello")-1);
delay();}
因为这么样会Hold住CPU,不能执行其他任务。
我的建议是:将你要发送的大数据分批发送,在前面一批数据发送完成后 才继续发送下一批数据。
比方说,你可以在回调函数的发送完成处理中置为一个任务事件 osal_set_event(xxtaskid,xxeventid);
然后你到这个任务事件的处理中去继续发送下一批数据。
不过我自己没有做过(因为我没有大数据要猛发…),我也只是提供一个建议,可不可行得你自己去试了。
wengo wu:
回复 da qin zheng sheng:
HI 大秦正声:
等待查询发送标志!是那个?
for(uint16 cnt=0;cnt<70;cnt++) { NPI_WriteTransport("Hello",sizeof("Hello")-1); while((U0CSR&0x02) != 0x02);// delay(); }
U0CSR 的bit2位是Transmit byte status.好像没起作用。。
shaokai Lin:
回复 wengo wu:
Hi wengo
NPI_WriteTransport("Hello",sizeof("Hello")-1);while(sendOKFlag==0);}为什么加while不能进入回调函数,一直挺在while里面。。一去掉while 就能进入发送完成的回调函数里面了??
可能你对器件的DMA传输还不是很了解,为何加while不能进入到回调函数呢?先看看回调函数在哪里被调用:
1.OSAL.C文件中,void osal_run_system(void)有这么一个函数 Hal_ProcessPoll();
2.点进去,可以找到 HalUARTPoll();
3.再点进去可以找到 HalUARTPollDMA();
4.再点进去可以找到
if ((evt != 0) && (dmaCfg.uartCB != NULL))//调用回调函数并发送事件通知 { dmaCfg.uartCB(HAL_UART_DMA-1, evt); }
这里调用的dmaCfg.uartCB正是你注册的回调函数。
也就是说,DMA串口传输的回调函数是放在主循环里面轮询的,你用while(sendOKFlag == 0);Hold住CPU,代码得不到执行,当然不会执行回调函数啦。
OK,我能帮你的就这么多了,深入的还是请教TI的专家吧。