我使用标准外设库编写了一个驱动程序,从 USART6_RX 获取数据并将其通过 DMA 保存在 STM32F407ZGT6 芯片上的内存中。 USART 无需 DMA 即可工作,但使用 DMA 则不会发生任何事情。
注1:USART1和USART6有不同的配置,这是系统特性。 注2:RCC和GPIO设置被删除。
//length of data
#define TX_L 6
#define RX_L 30
//CH2 ENABLES GPIOE
#define CH2_RE GPIO_Pin_4
#define CH2_DE GPIO_Pin_5
//IN USART6 GPIOC
#define UART_RECIVO USART6
#define UART_PIN_RECIVO GPIO_Pin_7
//OUT USART1 GPIOB
#define UART_SENDO USART1
#define UART_PIN_SENDO GPIO_Pin_6
//speed
#define UART_SPEED 9600
volatile uint8_t tx_buffer[TX_L];
volatile uint8_t rx_buffer[RX_L];
void Delay(__IO uint32_t nCount) {
while(nCount--);
}
void tx_clear(void) {
for(size_t i = 0; i < TX_L; i++) {
tx_buffer[i] = i + 1;
}
}
void rx_clear(void) {
for(size_t i = 0; i < RX_L; i++) {
rx_buffer[i] = 0;
}
}
void UART_send(uint8_t s) {
while (USART_GetFlagStatus(UART_SENDO, USART_SR_TXE) == RESET);
USART_SendData(UART_SENDO, s);
}
void UART_send_tx_buffer(size_t len) {
for(size_t i = 0; i < len; i++) {
UART_send(tx_buffer[i]);
}
}
uint8_t UART_get(void) {
while (USART_GetFlagStatus(UART_RECIVO, USART_SR_RXNE) == RESET);
return (USART_ReceiveData(UART_RECIVO));
}
void DMA_Config(void) {
RCC_APB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_Cmd(DMA2_Stream1, DISABLE);
while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE);
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_Channel = DMA_Channel_5;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(UART_RECIVO->DR));//USART6_BASE + 0x04;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&rx_buffer[0]);//(uint32_t)DMA_Start_Pos;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = (uint16_t)TX_L;//(uint16_t)sizeof(rx_buffer);//DMA_Buffer_Size;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream1, ENABLE);
}
void UART_Tx_Config(uint32_t speed) {
USART_InitTypeDef USART_InitStructure;
USART_Cmd(UART_SENDO, DISABLE);
USART_StructInit(&USART_InitStructure);
USART_OverSampling8Cmd(UART_SENDO, ENABLE);
USART_InitStructure.USART_BaudRate = speed;
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_Odd;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(UART_SENDO, &USART_InitStructure);
USART_Cmd(UART_SENDO, ENABLE);
}
void UART_Rx_Config(uint32_t speed) {
USART_InitTypeDef USART_InitStructure;
USART_Cmd(UART_RECIVO, DISABLE);
USART_StructInit(&USART_InitStructure);
USART_OverSampling8Cmd(UART_RECIVO, ENABLE);
USART_InitStructure.USART_BaudRate = speed;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_Odd;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx;
USART_Init(UART_RECIVO, &USART_InitStructure);
USART_DMACmd(UART_RECIVO, USART_DMAReq_Rx, ENABLE);
USART_Cmd(UART_RECIVO, ENABLE);
}
void UART_Config(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
UART_Tx_Config(UART_SPEED);
UART_Rx_Config(UART_SPEED);
USART_ReceiveData(UART_RECIVO);
USART_ReceiveData(UART_RECIVO);
USART_ReceiveData(UART_RECIVO);
}
int main(void) {
PLL_Config();
DMA_Config();
tx_clear();
UART_Config();
rx_clear();
GPIO_Config();
enableDEchannel(1, ENABLE);
enableDEchannel(2, DISABLE);
enableREchannel(1, ENABLE);
enableREchannel(2, ENABLE);
while(1) {
for(size_t i = 0; i < TX_L; i++) {
UART_send(tx_buffer[i]);
//rx_buffer[i] = UART_get();
}
Delay(0xFFFFFF);
}
}
我找到了答案...
RCC_APB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);//wrong
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);//right