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

串口一次发大量数据时怎么操作?

我发现串口发送时,最多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的专家吧。

赞(0)
未经允许不得转载:TI中文支持网 » 串口一次发大量数据时怎么操作?
分享到: 更多 (0)