【复旦微FM33LC046N评测】+学习uart0的dma收发
[复制链接]
本帖最后由 chrisrh 于 2021-3-2 00:36 编辑
前段家里事比较多,一直没空下来时间,近日学习了一下UART0的DMA示例:
UART0 DMA发送示例
UART0 DMA接收示例
将两个例程揉合跑了一下,
UART0 初始化函数在mf_config.c中,
UART0_TX发送口为PA3;
UART0_RX接收口为PA2;
函数初始化配置如下:
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] UART0 Initialization function
* @param void
* @retval None
*/
void MF_UART0_TX_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_UART_InitTypeDef defaultInitStruct;
GPIO_InitStruct.pin = FL_GPIO_PIN_3;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = DISABLE;
GPIO_InitStruct.remapPin = DISABLE;
FL_GPIO_Init( GPIOA, &GPIO_InitStruct );
defaultInitStruct.clockSrc = FL_RCC_UART0_CLK_SOURCE_APB1CLK;
defaultInitStruct.baudRate = 115200;
defaultInitStruct.dataWidth = FL_UART_DATA_WIDTH_8B;
defaultInitStruct.stopBits = FL_UART_STOP_BIT_WIDTH_1B;
defaultInitStruct.parity = FL_UART_PARITY_EVEN;
defaultInitStruct.transferDirection = FL_UART_DIRECTION_TX;
FL_UART_Init(UART0,&defaultInitStruct );
}
/**
* @brief UART0 Initialization function
* @param void
* @retval None
*/
void MF_UART0_RX_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_UART_InitTypeDef RXdefaultInitStruct;
GPIO_InitStruct.pin = FL_GPIO_PIN_2;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = DISABLE;
GPIO_InitStruct.remapPin = DISABLE;
FL_GPIO_Init( GPIOA, &GPIO_InitStruct );
RXdefaultInitStruct.clockSrc = 0;
RXdefaultInitStruct.baudRate = 115200;
RXdefaultInitStruct.dataWidth = FL_UART_DATA_WIDTH_8B;
RXdefaultInitStruct.stopBits = FL_UART_STOP_BIT_WIDTH_1B;
RXdefaultInitStruct.parity = FL_UART_PARITY_EVEN;
RXdefaultInitStruct.transferDirection = FL_UART_DIRECTION_RX;
FL_UART_Init(UART0,&RXdefaultInitStruct );
}
DMA通道1、通道2初始化如下:
/**
* @brief DMA_Channel1 Initialization function RX
* @param void
* @retval None
*/
void MF_DMA_Channel1_Init(void)
{
/*IO CONFIG*/
FL_DMA_InitTypeDef RXdefaultInitStruct;
RXdefaultInitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION1;
RXdefaultInitStruct.direction = FL_DMA_DIR_PERIPHERAL_TO_RAM;
RXdefaultInitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
RXdefaultInitStruct.flashAddressIncMode = FL_DMA_CH7_FLASH_INC_MODE_INCREASE;
RXdefaultInitStruct.dataSize = FL_DMA_BANDWIDTH_8B;
RXdefaultInitStruct.priority = FL_DMA_PRIORITY_HIGH;
RXdefaultInitStruct.circMode = DISABLE;
FL_DMA_Init(DMA,&RXdefaultInitStruct,FL_DMA_CHANNEL_1 );
}
void MF_DMA_Channel2_Init(void)
{
/*IO CONFIG*/
FL_DMA_InitTypeDef defaultInitStruct;
defaultInitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION2;
defaultInitStruct.direction = FL_DMA_DIR_RAM_TO_PERIPHERAL;
defaultInitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
defaultInitStruct.flashAddressIncMode = FL_DMA_CH7_FLASH_INC_MODE_INCREASE;
defaultInitStruct.dataSize = FL_DMA_BANDWIDTH_8B;
defaultInitStruct.priority = FL_DMA_PRIORITY_HIGH;
defaultInitStruct.circMode = DISABLE;
FL_DMA_Init(DMA,&defaultInitStruct,FL_DMA_CHANNEL_2 );
}
在MF_Config_Init(void)中调用收发函数:
void MF_Config_Init(void)
{
/*FUNCTION CALL*/
MF_DMA_Channel1_Init();
MF_UART0_RX_Init();
/*FUNCTION CALL*/
MF_UART0_TX_Init();
MF_DMA_Channel2_Init();
}
在uart0_DMAtrx.c中为编写的测试函数,如下:
#include "main.h"
#include "user_init.h"
#include "uart0_DMAtrx.h"
uint8_t DMARxData[7];
uint8_t DMA_DATA;
void Uart0DMA_Config_TX(uint8_t *buffer,uint32_t length)
{
FL_DMA_ConfigTypeDef DMA_ConfigStruct={0};
DMA_ConfigStruct.memoryAddress = (uint32_t)buffer;
DMA_ConfigStruct.transmissionCount = length-1;
FL_DMA_StartTransmission(DMA, &DMA_ConfigStruct,FL_DMA_CHANNEL_2);
}
void Uart0DMA_Config_RX(uint8_t *buffer,uint32_t length)
{
FL_DMA_ConfigTypeDef DMA_RX_ConfigStruct={0};
DMA_RX_ConfigStruct.memoryAddress = (uint32_t)buffer;
DMA_RX_ConfigStruct.transmissionCount = length-1;
FL_DMA_StartTransmission(DMA, &DMA_RX_ConfigStruct,FL_DMA_CHANNEL_1);
}
void TestDMA_Uart0_TX(void)
{
uint8_t TestTxData[13] = "TestUart-TX\n";
volatile uint8_t tmp08;
FL_DMA_Enable(DMA);
Uart0DMA_Config_TX(TestTxData,13);
FL_UART_EnableTX(UART0);
while (!FL_DMA_IsActiveFlag_TransferComplete(DMA, FL_DMA_CHANNEL_2));
FL_DMA_ClearFlag_TransferComplete(DMA, FL_DMA_CHANNEL_2);
FL_UART_ClearFlag_TXShiftBuffEmpty(UART0);
// 等待发送完成
while (FL_UART_IsActiveFlag_TXShiftBuffEmpty(UART0) == RESET){};
FL_UART_ClearFlag_TXShiftBuffEmpty(UART0);
}
void TestDMA_Uart0_RX(void)
{
FL_DMA_Enable(DMA);
Uart0DMA_Config_RX(DMARxData,7);
FL_UART_EnableRX(UART0);
if(!FL_DMA_IsActiveFlag_TransferComplete(DMA, FL_DMA_CHANNEL_1)){DMA_DATA = 0;}
while (!FL_DMA_IsActiveFlag_TransferComplete(DMA, FL_DMA_CHANNEL_1));
if(FL_DMA_IsActiveFlag_TransferComplete(DMA, FL_DMA_CHANNEL_1)){DMA_DATA = 1;}
FL_DMA_ClearFlag_TransferComplete(DMA, FL_DMA_CHANNEL_1);
}
在主函数while(1)中编写如下:
while(1)
{
MF_Config_Init();
TestDMA_Uart0_TX( );
DelayMs(500);
if(0 == DMA_DATA){LED1_ON();LED2_OFF();LED3_TOG();LED4_TOG();}
TestDMA_Uart0_RX( );
if(1 == DMA_DATA){LED1_OFF();LED2_ON();LED3_TOG();LED4_TOG();DMA_DATA = 0;}
}
DMA发送字符串正常;
未加入中断向量,能接受到串口发来的数据,但感觉接收到的数据有点问题,在调试模式下发送数字1234567,在watch中看到的结果如下:
不知道为什么DMA收到的数总和串口发来的数据不一致,问题暂未解决,希望大家能予以帮助
源程序见附件
|