Я пытаюсь перенести проект из HAL в LL.Я использую USART1 + DMA2 (RS485).Прием в порядке, но передача отсутствует.
Например, буфер передачи начинается с {1, 2, 3, 4}.
- Когда я устанавливаю длину данных DMA равной 1, ничего не происходитотправлено
- Когда я устанавливаю длину данных в 2, отправляется {0xFF}
- Когда я устанавливаю длину данных в 3, отправляется {0x01, 0xFF}
- Когда я устанавливаюдлина данных до 4, отправляется {0x01, 0x02, 0xFF}
«Отправлено» означает то, что я вижу в мониторе портов на моем ПК.Таким образом, данные не повреждены, просто неполны.
Я пытался включить / отключить прерывания, очистить флаги.Также я попытался получить те же регистры DMA и UART в LL, что и в HAL.Пока безуспешно.
...
typedef uint8_t uiRX_t;
typedef uint8_t uiTX_t;
#define TX_BUFF_LEN 320
#define RX_BUFF_LEN 1
typedef struct {
uint16_t tx_len;
uiTX_t tx_buff[ TX_BUFF_LEN ];
uiRX_t rx_buff[ RX_BUFF_LEN ];
} DataStorage;
...
volatile DataStorage data = { 0 };
...
int main()
{
...
while ( 1 ) {
while ( LL_DMA_IsEnabledStream( USART_DMA, USART_DMA_STREAM_TX ) ) { }
LL_DMA_SetDataLength( USART_DMA, USART_DMA_STREAM_TX, data.tx_len );
LL_GPIO_SetOutputPin( USART_PORT, USART_PIN_DE );
LL_DMA_EnableStream( USART_DMA, USART_DMA_STREAM_TX );
LL_mDelay( SYSTICKS_FREQ );
}
}
...
void init_sys( void ) {
...
LL_APB2_GRP1_EnableClock( LL_APB2_GRP1_PERIPH_SYSCFG );
LL_APB1_GRP1_EnableClock( LL_APB1_GRP1_PERIPH_PWR );
LL_PWR_SetRegulVoltageScaling( LL_PWR_REGU_VOLTAGE_SCALE1 );
NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_3 );
LL_UTILS_PLLInitTypeDef pll = {
.PLLM = LL_RCC_PLLM_DIV_16,
.PLLN = 336,
.PLLP = LL_RCC_PLLP_DIV_2
};
LL_UTILS_ClkInitTypeDef clk = {
.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1,
.APB1CLKDivider = LL_RCC_APB1_DIV_4,
.APB2CLKDivider = LL_RCC_APB2_DIV_2
};
if( SUCCESS != LL_PLL_ConfigSystemClock_HSI( &pll, &clk ) ) {
Error_Handler();
}
LL_SYSTICK_SetClkSource( LL_SYSTICK_CLKSOURCE_HCLK );
LL_InitTick( SystemCoreClock, SYSTICKS_FREQ );
LL_SYSTICK_EnableIT();
}
...
void init_nvic( const IRQn_Type irq, const uint32_t priority0, const uint32_t priority1 ) {
NVIC_SetPriority( irq, NVIC_EncodePriority( NVIC_GetPriorityGrouping(), priority0, priority1 ) );
NVIC_EnableIRQ( irq );
}
...
void init_dma() {
LL_AHB1_GRP1_EnableClock( USART_DMA_PERIPH );
init_nvic( USART_DMA_TX_IRQn, 1, 0 );
LL_DMA_SetChannelSelection( USART_DMA, USART_DMA_STREAM_TX, USART_DMA_CHANNEL_TX );
LL_DMA_ConfigTransfer( USART_DMA, USART_DMA_STREAM_TX,
LL_DMA_DIRECTION_MEMORY_TO_PERIPH |
LL_DMA_MODE_NORMAL |
LL_DMA_PERIPH_NOINCREMENT |
LL_DMA_MEMORY_INCREMENT |
LL_DMA_PDATAALIGN_BYTE |
LL_DMA_MDATAALIGN_BYTE |
LL_DMA_PRIORITY_HIGH );
LL_DMA_DisableFifoMode( USART_DMA, USART_DMA_STREAM_TX );
LL_DMA_ConfigAddresses( USART_DMA, USART_DMA_STREAM_TX,
( ( uint32_t ) data.tx_buff ),
LL_USART_DMA_GetRegAddr( USART_N ),
LL_DMA_GetDataTransferDirection( USART_DMA, USART_DMA_STREAM_TX ) );
LL_DMA_EnableIT_TC( USART_DMA, USART_DMA_STREAM_TX );
LL_DMA_EnableIT_TE( USART_DMA, USART_DMA_STREAM_TX );
}
...
void DMA_TransmitComplete_Callback( void )
{
LL_GPIO_ResetOutputPin( USART_PORT, USART_PIN_DE );
LL_DMA_DisableStream( USART_DMA, USART_DMA_STREAM_TX );
}
void DMA_TransferError_Callback( void )
{
LL_DMA_DisableStream( USART_DMA, USART_DMA_STREAM_TX );
}
Возможно, было бы лучше предоставить полные файлы, так как они короткие, но ТАК не рекомендует.Полный проект можно найти здесь