串口接收中断必须以极快的速度完成,否则会出现丢数据的情况

判断缓冲区足够最小值以后才唤醒任务,减少时间消耗
缓冲区里面别用%,那会产生非常耗时的除法运算
在三位触摸开关上测试1M串口通信,收发数据完整
This commit is contained in:
nnhy 2015-09-30 03:09:59 +00:00
parent 2df69092f9
commit f6b5ae1fac
2 changed files with 23 additions and 16 deletions

View File

@ -62,10 +62,10 @@ uint Controller::Dispatch(ITransport* port, ByteArray& bs, void* param, void* pa
Controller* control = (Controller*)param;
#if MSG_DEBUG
/*msg_printf("TinyNet::Dispatch[%d] ", len);
msg_printf("TinyNet::Dispatch[%d] ", len);
// 输出整条信息
Sys.ShowHex(buf, len, '-');
msg_printf("\r\n");*/
msg_printf("\r\n");
#endif
if(len > control->Port->MaxSize)
{

View File

@ -41,7 +41,7 @@ void SerialPort::Init()
Error = 0;
IsRemap = false;
MinSize = 1;
MinSize = 8;
_taskidRx = 0;
}
@ -255,7 +255,7 @@ bool SerialPort::OnWrite(const ByteArray& bs)
//Tx.Write(bs);
// 中断发送过于频繁,采用循环阻塞发送。后面考虑独立发送任务
// 中断发送过于频繁,影响了接收中断,采用循环阻塞发送。后面考虑独立发送任务
for(int i=0; i<bs.Length(); i++)
{
SendData(bs[i], 300);
@ -331,12 +331,18 @@ uint SerialPort::OnRead(ByteArray& bs)
void SerialPort::OnRxHandler()
{
// 串口接收中断必须以极快的速度完成,否则会出现丢数据的情况
// 判断缓冲区足够最小值以后才唤醒任务,减少时间消耗
// 缓冲区里面别用%,那会产生非常耗时的除法运算
//while(USART_GetITStatus(_port, USART_IT_RXNE) != RESET)
{
byte dat = (byte)USART_ReceiveData(_port);
Rx.Push(dat);
//debug_printf(" 0x%02X ", dat);
//Sys.Delay(300);
}
// 收到数据开启任务调度。延迟_byteTime可能还有字节到来
if(_taskidRx) Sys.SetTask(_taskidRx, true, _byteTime);
if(_taskidRx && Rx.Length() >= MinSize) Sys.SetTask(_taskidRx, true, _byteTime);
//if(!HasHandler()) return;
@ -373,7 +379,7 @@ void SerialPort::Register(TransportHandler handler, void* param)
if(handler)
{
// 建立一个未启用的任务,用于定时触发接收数据,收到数据时开启
if(!_taskidRx) _taskidRx = Sys.AddTask(ReceiveTask, this, -1, -1, "串口接收");
if(!_taskidRx) _taskidRx = Sys.AddTask(ReceiveTask, this, 1000000, 1000000, "串口接收");
}
else
{
@ -385,9 +391,9 @@ void SerialPort::Register(TransportHandler handler, void* param)
void SerialPort::OnHandler(ushort num, void* param)
{
SerialPort* sp = (SerialPort*)param;
assert_param2(sp, "串口参数不能为空 OnHandler");
//assert_param2(sp, "串口参数不能为空 OnHandler");
if(USART_GetITStatus(sp->_port, USART_IT_TXE) != RESET) sp->OnTxHandler();
//if(USART_GetITStatus(sp->_port, USART_IT_TXE) != RESET) sp->OnTxHandler();
// 接收中断
if(USART_GetITStatus(sp->_port, USART_IT_RXNE) != RESET) sp->OnRxHandler();
// 溢出
@ -395,7 +401,8 @@ void SerialPort::OnHandler(ushort num, void* param)
{
USART_ClearFlag(sp->_port, USART_FLAG_ORE);
// 读取并扔到错误数据
USART_ReceiveData(sp->_port);
//USART_ReceiveData(sp->_port);
debug_printf("Serial%d 溢出 \r\n", sp->_index + 1);
}
/*if(USART_GetFlagStatus(sp->_port, USART_FLAG_NE) != RESET) USART_ClearFlag(sp->_port, USART_FLAG_NE);
if(USART_GetFlagStatus(sp->_port, USART_FLAG_FE) != RESET) USART_ClearFlag(sp->_port, USART_FLAG_FE);
@ -467,9 +474,9 @@ SerialPort* SerialPort::GetMessagePort()
_printf_sp = new SerialPort(port);
#if DEBUG
#ifdef STM32F0
_printf_sp->Tx.SetCapacity(256);
//_printf_sp->Tx.SetCapacity(256);
#else
_printf_sp->Tx.SetCapacity(1024);
//_printf_sp->Tx.SetCapacity(1024);
#endif
#endif
_printf_sp->Open();