【发布时间】:2023-03-17 01:48:01
【问题描述】:
我对 for 循环复制的时间有一些问题,我不明白为什么 for 循环会花费大量时间来复制小数据大小。 我正在使用 PIC24FJ256GL406 MCU,一切都很好,但是在操作 UART 微控制器时运行缓慢,因为在复制缓冲区数据时会出现一些延迟。 让我用代码和调试日志给你解释一下。
这里我发布了UART传输的功能。该函数一般只传输第一个字符,其余字节将在中断程序服务中传输。
我的时钟频率是 32Mhz 所以外围设备将是 16 Mhz。
我不明白为什么 for 循环只复制 16 字节数据需要将近 20 毫秒。所以如果数据更多,这个时间会增加。
unsigned int UART1_WriteBuffer(const uint8_t *buffer, const unsigned int bufLen)
{
//transmit first char
U1TXREG = buffer[0];
while (!U1STAbits.TRMT);
numBytesWritten = bufLen - 1;
totalByte = 0;
//get the current time stamp
WSTimestamp currentTimeStamp = WSGetCurrTimestamp();
WMLogInfo(GEN_LOG, "current time stamp %ld", currentTimeStamp);
uint16_t i = 0;
//memset
memset(&uart1_txByteQ, 0x00, sizeof(uart1_txByteQ));
for (i = 0; i < numBytesWritten; i++)
{
uart1_txByteQ = buffer[i + 1]; //copy the data
}
_U1TXIE = 1;
//get last time stamp
WSTimestamp lastTimeStamp = WSGetCurrTimestamp();
WMLogInfo(GEN_LOG, "last time stamp %ld ", lastTimeStamp);
///print the debug
WMLogInfo(GEN_LOG, "total = %ld MS time taken fo copy the = %d byte", lastTimeStamp - currentTimeStamp, numBytesWritten);
return bufLen;
}
My Interrupt Routine service.
void __attribute__((interrupt, no_auto_psv)) _U1TXInterrupt(void)
{
if (totalByte < numBytesWritten)
{
U1TXREG = uart1_txByteQ[totalByte++];
while (!U1STAbits.TRMT);
}
else
{
_U1TXIE = 0;
_U1TXIE = 0;
}
}
Console Log.
This is function log. please note.
GEN:main loop current time stamp 6503<\r><\n>
GEN:current time stamp 6506<\r><\n>
GEN:last time stamp 6526 <\r><\n>
GEN:total = 20 MS time taken fo copy the = 16 byte<\r><\n>
GEN:command "AT+QREFUSECS=1,1<\r>" send with len [17]
【问题讨论】:
-
什么是
uart1_txByteQ?它是一个数组吗?然后像uart1_txByteQ = buffer[i + 1];这样的分配没有意义,甚至不应该建立。请尝试创建minimal reproducible example 向我们展示。 -
如果你想复制,为什么不使用
memcpy? -
@Someprogrammerdude 是 uart1_txByteQ 是一个数组。如您所见,函数中只有 buf[0] 字符正在传输,其余字符将在中断例程中传输,因此 uart1_txByteQ 是全局数组,因此我将缓冲区 [i+1] 复制到 uart1_txByteQ,因为已经传输了 1 个字符。
-
您在中断中等待传输字节
while (!U1STAbits.TRMT);并浪费时间。也许,如果可能的话,你应该在U1TXREG = xx之前做一些ready-test -
这是一个传输中断。当它发生时,加载 tx 寄存器。不要通过“Go”,不要通过毫无意义的轮询收集任何延迟。当处理程序中没有更多要发送的内容时,禁用中断。当有缓冲区要发送时,检查中断是否被禁用,如果是,则启用它并将第一个字符加载到 tx 寄存器中。
标签: c for-loop microcontroller uart