如果使用DMA接收,在PC上通过串口发送100K的数据,一个数据都不会丢失,但是使用中断方式,就会造成接收数据少那么几个, 注:在PC上使用串口工具, 发送字节数为280个, 时间间隔为1 ms, 有没有那位高人可以帮我看一下.
static void UART_Interrupt( void *Param )
{
OS_ERR err;
unsigned int cr;
struct UART_DEVICE *uart = (struct UART_DEVICE *)Param;
unsigned int sr = uart->uart->SR;
cr = uart->uart->CR1;
if ( (cr && 0x20) && (sr & 0x20) ){
//RXNE 读数据寄存器非空
UART_Recv_Byte( uart, cr, sr );
sr = uart->uart->SR;
}
if ( (cr & 0x80) && (sr & 0x80) ){
//TXE:发送数据寄存器空
uart->uart->DR = uart->Send.buffer[uart->Send.offset];
uart->Send.offset++;
if ( uart->Send.offset >= uart->Send.size ){
//发送缓冲区空中断使能
uart->uart->CR1 &= (~0x80);
BSP_OS_SemPost( &uart->Send_Sem );
}
uart->uart->SR &= (~0x80);
sr = uart->uart->SR;
}
if ( (cr && 0x20) && (sr & 0x20) ){
//RXNE 读数据寄存器非空
UART_Recv_Byte( uart, cr, sr );
sr = uart->uart->SR;
}
if ( (cr & 0x10) && (sr & 0x10) ){
//IDEL 监测到总线空闲
OSQPost( &uart->Recv_Queue, (void *)uart->current_buffer, 1, OS_OPT_POST_NO_SCHED | OS_OPT_POST_ALL | OS_OPT_POST_FIFO, &err );
if ( uart->current_buffer == NULL ){
uart->current_buffer = &uart->Recv[0];
}else if ( uart->current_buffer == &uart->Recv[0] ){
uart->current_buffer = &uart->Recv[1];
}else if ( uart->current_buffer == &uart->Recv[1] ){
uart->current_buffer = &uart->Recv[2];
}else if ( uart->current_buffer == &uart->Recv[2] ){
uart->current_buffer = &uart->Recv[3];
}else{
uart->current_buffer = &uart->Recv[0];
}
uart->current_buffer->offset = 0;
uart->current_buffer->Recv_Size = 0;
uart->uart->CR1 &= (~0x10);
uart->uart->SR &= (~0x10);
sr = uart->uart->SR;
}
if ( (cr && 0x20) && (sr & 0x20) ){
//RXNE 读数据寄存器非空
UART_Recv_Byte( uart, cr, sr );
}
}
static void Uart_SendTask( void *p_arg )
{
struct UART_DEVICE *uart = (struct UART_DEVICE *)p_arg;
while (DEF_TRUE) { /* Task body, always written as an infinite loop. */
const PLIST_ENTRY Entry = &uart->Send_Entry;
PLIST_ENTRY pListEntry = Entry->Flink;
if ( pListEntry == Entry ){
BSP_OS_SemWait( &uart->Lock_Sem, 0 );
uart->ReadyStatus = 1;
BSP_OS_SemPost( &uart->Lock_Sem );
BSP_OS_SemWait( &uart->Ready_Sem, 0 );
continue;
}
while( pListEntry != Entry ){
struct UART_SEND_NODE *Node = CONTAINING_RECORD( pListEntry, struct UART_SEND_NODE, Link );
uart->Send.offset = 0;
uart->Send.size = Node->Size;
uart->Send.buffer = Node->Buffer;
//发送缓冲区空中断使能
uart->uart->CR1 |= 0x80;
BSP_OS_SemWait( &uart->Send_Sem, 0 );
BSP_OS_SemWait( &uart->Lock_Sem, 0 );
RemoveEntryList( &Node->Link );
BSP_OS_SemPost( &uart->Lock_Sem );
pListEntry = pListEntry->Flink;
if ( NULL == Node->Complete ){
BSP_OS_SemPost( &Node->SemComplete );
}else{
Node->Complete( Node->arg );
Node->Release( Node );
}
}
}
}
static void Uart_RecvTask( void *p_arg )
{
OS_ERR err;
OS_MSG_SIZE i;
OS_MSG_SIZE Size;
struct UART_DEVICE *uart = (struct UART_DEVICE *)p_arg;
while (DEF_TRUE) { /* Task body, always written as an infinite loop. */
struct UART_RECV* Recv = (struct UART_RECV *)OSQPend( &uart->Recv_Queue, 0, OS_OPT_PEND_BLOCKING, &Size, (CPU_TS *)0, &err );
if ( err != OS_ERR_NONE ){
continue;
}
for ( i = 0; i < Size; i++ ){
m_Size += Recv->Recv_Size;
UART_Send( uart, Recv->buffer, Recv->Recv_Size, UART_Complete, NULL );
Recv++;
}
}
} |