- 有段代码功能是串口接受字符之间传输超时1000us判断;
- 串口波特率是57600(1.74*e4 ns 传一位),配置为8个数据位,无奇偶校验;
- cpu时钟频率为f=58.98MHz, SCI_B串口时钟未分频直接使用系统时钟。
我的理解为每个字符(10位(起始位+数据位+停止位),需要1.74*e4 10=1.74e5 ns <10^6 ns)中断一次,每获取到一个新字符然后在初始化记时函数ISB_ReceiveCommandTimeout(3)函数中初始化时间将计数变量Mruningtimeout置零。接受过程中如果对应的接受缓冲区的值为0x00(实际是不会为0x00,我理解为串口传输很慢,cpu工作频率很快),将计数变量Mruningtimeout自加一。
问题: 但却将判断值mRequiredTimeout设置为3,这个是为什么?
if ( mNumberOfCharsInRxBuffer < SCI_RxBufferNumberOfCharsGet(SCI_B) ) // New Chars received
{
mNumberOfCharsInRxBuffer = SCI_RxBufferNumberOfCharsGet(SCI_B); // Number of chars updated
ISB_ReceiveCommandTimeoutInitialise(TIMEOUT_FOR_BAUD_RATE); // Reset the inter-char timer
}
if ( mNumberOfCharsInRxBuffer != 0u ) // Chars In the RX buffer
{
// First we look for the CTRL_A character within the characters received
for ( loop = 0u; loop < (mNumberOfCharsInRxBuffer - 1u); loop++ )
{
if ( CTRL_A == *pCtrlA ) //lint !e921 Cast to uint8_t in CTRL_A is OK
{
break;
}
else
{
pCtrlA++;
}
}
// Then the message is checked.
ISBcommandStatus = ISB_ReceivedCommandCheck(pCtrlA, mBusAddress);
// The response to the ISB status is based on the status table in the
// LWD / MWD / ISB Communications Opcodes document (GeMS 100553165, page 5).
// Note that not all conditions require a response to be sent back to the master.
switch (ISBcommandStatus)
{
// The packet is OK, so process the received opcode and then reset
// the receive buffer and inter-character timer.
case (ISB_PACKET_OK) :
ProcessOpcodeAndTransmitResponse(pCtrlA);
ReceiveBufferInitialise();
ISB_ReceiveCommandTimeoutInitialise(TIMEOUT_FOR_BAUD_RATE); // **_TIMEOUT_FOR_BAUD_RATE为3_**
break;
// The reception buffer is cleared for the following cases.
// Note that the slave does not reply to the master under these conditions.
case ISB_NO_CTRL_A :
case ISB_INVALID_ADDRESS :
case ISB_COMMAND_WAIT_OPCODE_TIMEOUT :
case ISB_CHECKSUM_FAIL :
ReceiveBufferInitialise();
break;
EIsbRxStatus_t ISB_ReceivedCommandCheck(const uint8_t * const pBuffer,
const uint8_t ExpectedAddress)
{
EIsbRxStatus_t status = ISB_PACKET_OK;
uint16_t expected_length = 6u;
mValidOpcode = 0xffu; // set opcode to 0xff before we use it
mDataLength = 0u; // set length of data found to zero
if (CTRL_A != pBuffer[0u]) //lint !e921 Cast to uint8_t in macro.
{
status = ISB_NO_CTRL_A;
}
else if (0x00u == pBuffer[1u])
{
status = ISBTimeoutCheck(ISB_WAITING_FOR_ADDRESS);
}
else if (ExpectedAddress != pBuffer[1u])
{
status = ISB_INVALID_ADDRESS;
}
else if ( (0x00u == pBuffer[2u]) && (0x00u == pBuffer[3u]) )
{
status = ISBTimeoutCheck(ISB_WAITING_FOR_MORE_COMMAND);
}
}
// ----------------------------------------------------------------------------
/**
* ISB_ReceiveCommandTimeoutIncrement increments the running timeout for the
* received message.
*
*/
// ----------------------------------------------------------------------------
void ISB_ReceiveCommandTimeoutIncrement(void)
{
mRunningTimeout++;
}
我的解答思路和尝试过的方法
我想应该是时钟频率和波特率有差距产生的,下一个中断来以前,CPU在飞速的执行程序,预期时间IMEOUT_FOR_BAUD_RATE设为3,是不是可以理解为接受下个字符的时候我cpu给了3次机会,程序循环3次后,即计数变量mRunningTimeout自加3次之后,接受区的数据还为0x00(没更新)就属于超时了
我想要解决的问题
这个3是如何计算得出的,请大家指点迷津。