Не хочется создавать большой кольцевой буфер для PRINTF. Поступил по - другому. С задержкой.
Посчитав что PRINTF работает через int fputc(int ch, FILE *f), в ней и написал:
Код
int fputc(int ch, FILE *f) //Внутри функции реализована задержка заполнения
{ //буфера для уменьшения размера буфера.
static unsigned int StreamWaitCnt = 0; //
StreamWaitCnt++; //Счетчик числа передаваемых байт
if (StreamWaitCnt > PC_TxBufSize-5) //Если счеттчик достиг размера буфера
{ //
StreamWaitCnt = 0; //Обнулить счетчик
HAL_Delay(30); //Задержка пока буфер улетит в порт
} //
return (PC_Putchar(ch)); //
} //
Т.е. когда буфер заполняется, происходит задержка для ожидания завершения передачи буфера в порт. Передача осуществляется через прерывание:
Код
int PC_Putchar(int ch) //Передача. Функция помещает Ch в кольцевой буфер.
{ //Указатель головы кольцевого буфера перемещается на
int tmphead = (PC_TxHead + 1) & PC_TX_BUFFER_MASK; //одну позицию, символ помещается в кольцевой буфер.
PC_TxBuf[tmphead] = (char)ch; //Если передача первая после опустошения
PC_TxHead = tmphead; //буфера(переданы все символы), взводится флаг L86_Complete,
if (PC_Complete==0) //Передаваемый символ помещается в передающий регистр порта
{ //(L86_UsartTx();) и инициируется первая передача
PC_Complete = 1; //в цепочке - разрешением прерывания.
PC_UsartTx(); //Флаг начала цепочки передач
PC_En_Tranfer_Interrupt; //Положить первый символ в DR
} //
return (ch); //
} //
Само прерывание:
Код
void USART2_IRQHandler(void)
{
if (USART2->ISR & USART_ISR_TC) //Bit 6 TC: Transmission complete
{ //
PC_UsartTx(); //
} //
if (USART2->ISR & USART_ISR_RXNE) //Bit 5 RXNE: Read data register not empty
{ //
PC_UsartRx(); //Функция кладет байт из приёмного регистра в кольцевой буфер
} //
HAL_UART_IRQHandler(&huart2);
}
Код
void PC_UsartTx(void) //
{ //
if (PC_TxHead != PC_TxTail) //Check if all data is transmitted
{ //
PC_TxTail = (PC_TxTail + 1) & PC_TX_BUFFER_MASK;//Перемещение указателя по кольцевому буферу
USART2->TDR = (int)PC_TxBuf[PC_TxTail]; //Start transmition
} //
else //
{ //
PC_Complete=0; //Цепочка передачи окончена
PC_Dis_Tranfer_Interrupt; //Запретить прерывание на передачу Bit 6 TCIE:
} //
} //
Самой задержки (30мс) по идее должно хватать. Т.е. при скорости 115200 за 1 секунду улетает 10килобайт. Примерно. Значит за милисекунду - 10 байт. Итого - 300байт при буфере в 256.
Такой подход по идее должен разрешать иметь любой малый (в разумных пределах) буфер для передачи. На практике же это не работает - часть выводимой информации теряется. И только когда я делаю #define PC_TxBufSize 8192, передача осуществляется без потерь.
Где же я не прав, может кто подскажет?
Сообщение отредактировал Димон Безпарольный - Feb 16 2018, 03:31