Apтём (07.04.2017 23:09, просмотров: 160) ответил Ксения на Но меня интересует передача. Буфер тоже кольцевой, в него время от времени подбрасываются еще порции. Какую тактику вы бы посоветовали в этом случае?
Я наверное сделал бы также как и при передаче с использованием прерывания UDRE, только с ДМА передавались бы не байты, а блоки из буфера передачи. Типа так:
volatile uint8_t TxBuffer[500];
volatile uint16_t TxNext, TxFirst;
void SendBuffer(uint8_t * data, uint16_t data_length)
{
uint16_t tx_next=TxNext;
// копируем данные в буфер
for (uint16_t i=0; i<data_length; i++) {
TxBuffer[tx_next]=*data++;
if (tx_next>=sizeof(TxBuffer))
tx_next=0;
}
CRITICAL_SECTION();
TxNext=tx_next;
if (tx_dma::TransferInterruptDisabled()) {
// запуск передачи по ДМА и разрешение прерываний от канала ДМА
StartDMATx();
}
}
ISR(DMA_CH0_vect)
{
uint16_t tx_size=tx_dma::GetTrfCnt();
TxFirst+=tx_size;
if (TxFirst==sizeof(TxBuffer))
TxFirst-=sizeof(TxBuffer);
if (TxNext!=TxFirst) {
// запуск новой передачи по ДМА
}
else {
// запрет прерываний от ДМА
}
}
Думаю, ничего лучше в данном случае и не придумаешь.