STM32F407 USART +DMA共思路DMA通道,进行数据转发
发布时间:2024-11-21
发布时间:2024-11-21
/**
****************************************************************************** * @file IO_Toggle/main.c
* @author MCD Application Team
* @version V1.0.0
* @date 19-September-2011
* @brief Main program body
****************************************************************************** * @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
****************************************************************************** */
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
//串口1连接电脑的USB-TTL小板子,串口2连接MAX485
/* Private typedef -----------------------------------------------------------*/
#define TX_MODE 0
#define RX_MODE 1
unsigned long boundrate[7]={600,2400,4800,9600,19200,38400,57600};
/* Private variables ---------------------------------------------------------*/
__IO unsigned char uart_rx_tx_buf[2];
USART_InitTypeDef USART_InitStruct;
DMA_InitTypeDef DMA_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
void uart_1_dma_init(void);
void uart_2_dma_init(void);
void Set485Mode(unsigned char flag);
void Set_1_rate(unsigned char rate_num);
void Set_2_rate(unsigned char rate_num);
void _485PinConfig(void);
int main(void)
{
uart_1_dma_init();
uart_2_dma_init();
Set485Mode(TX_MODE);
while(1);
}
void uart_1_dma_init(void)
{
/* Enable uart1, DMA2 and GPIO clocks ****************************************/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOB, ENABLE); //B6-TX, B7-RX;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
/***********************uart1 initial****************************************/ USART_http://ART_BaudRate=9600;
USART_http://ART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_http://ART_Mode=USART_Mode_Rx |USART_Mode_Tx;
USART_http://ART_Parity=USART_Parity_No;
USART_http://ART_StopBits=USART_StopBits_1;
USART_http://ART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct);
/***************GPIO**************************************************/ GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_USART1);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6 |GPIO_Pin_7;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
/* DMA2 Stream0 channel0 configuration **************************************/ DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR));
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)uart_rx_tx_buf;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream2, &DMA_InitStruct);
DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR));
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)uart_rx_tx_buf;
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.DMA_BufferSize = 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream7, &DMA_InitStruct);
/**********************DMA interrupt************************/
DMA_ITConfig(DMA2_Stream7,DMA_IT_TC,ENABLE);
DMA_ITConfig(DMA2_Stream2,DMA_IT_TC,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01;
NVIC_Init(&NVIC_InitStructure);
/**********************start*********************************/
DMA_Cmd(DMA2_Stream7, DISABLE); //不使能DMA对于USART1的发送功能 DMA_Cmd(DMA2_Stream2, ENABLE); //使能DMA对于USART1的接收功能 USART_DMACmd(USART1,USART_DMAReq_Rx |USART_DMAReq_Tx,ENABLE); USART_Cmd(USART1,ENABLE);
}
void uart_2_dma_init(void)
{
/* Enable uart1, DMA2 and GPIO clocks ****************************************/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_GPIOA, ENABLE); // A2-TX,A3-RX
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
/***********************uart1 initial****************************************/ USART_http://ART_BaudRate=9600;
USART_http://ART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_http://ART_Mode=USART_Mode_Rx |USART_Mode_Tx;
USART_http://ART_Parity=USART_Parity_No;
USART_http://ART_StopBits=USART_StopBits_1;
USART_http://ART_WordLength=USART_WordLength_8b;
USART_Init(USART2,&USART_InitStruct);
/***************GPIO**************************************************/ GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2 |GPIO_Pin_3;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);
/* DMA2 Stream0 channel0 configuration **************************************/ DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART2->DR));
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)uart_rx_tx_buf;
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.DMA_BufferSize = 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream6, &DMA_InitStruct);
DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART2->DR));
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)uart_rx_tx_buf;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream5, &DMA_InitStruct);
/**********************DMA interrupt************************/
DMA_ITConfig(DMA1_Stream5,DMA_IT_TC,ENABLE);
DMA_ITConfig(DMA1_Stream6,DMA_IT_TC,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=DMA1_Stream5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=DMA1_Stream6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01;
NVIC_Init(&NVIC_InitStructure);
/**********************start*********************************/
DMA_Cmd(DMA1_Stream5, ENABLE); //使能USART2的串口接收DMA
DMA_Cmd(DMA1_Stream6, DISABLE); //不使能USART2的串口发送DMA
USART_DMACmd(USART2,USART_DMAReq_Rx |USART_DMAReq_Tx,ENABLE); USART_Cmd(USART2,ENABLE);
}
void DMA2_Stream2_IRQHandler(void) //串口1接收到了数据。即:电脑发数据了 {
if(DMA_GetITStatus(DMA2_Stream2,DMA_IT_TCIF2)==SET)
{
DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2);
if(uart_rx_tx_buf[0]=='C')
{
Set_1_rate(uart_rx_tx_buf[1]);
}
DMA_Cmd(DMA1_Stream6, ENABLE); //使能USART2的串口发送DMA
}
}
void DMA2_Stream7_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_Stream7,DMA_IT_TCIF7)==SET) //串口1发送完数据
{
DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7);
DMA_Cmd(DMA2_Stream7, DISABLE); //不使能DMA对于USART1的发送功能
}
}
void DMA1_Stream5_IRQHandler(void) //串口2接收数据完成,即:8051向串口2发送数据
{
if(DMA_GetITStatus(DMA1_Stream5,DMA_IT_TCIF5)==SET)
{
DMA_ClearFlag(DMA1_Stream5,DMA_FLAG_TCIF5);
DMA_Cmd(DMA2_Stream7, ENABLE); //使能DMA对于USART1的发送功能
}
}
void DMA1_Stream6_IRQHandler(void) //串口2发送数据完成,即:发送到8051 {
if(DMA_GetITStatus(DMA1_Stream6,DMA_IT_TCIF6)==SET)
{
DMA_ClearFlag(DMA1_Stream6,DMA_FLAG_TCIF6);
if(uart_rx_tx_buf[0]=='C')
{
Set_2_rate(uart_rx_tx_buf[1]);
}
else if(uart_rx_tx_buf[0]=='R' &&uart_rx_tx_buf[1]=='D')
{
Set485Mode(RX_MODE);
}
DMA_Cmd(DMA1_Stream6, DISABLE); //关闭USART2的串口发送DMA
}
}
void Set_1_rate(unsigned char rate_num)
{
USART_http://ART_BaudRate=boundrate[rate_num];
USART_http://ART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_http://ART_Mode=USART_Mode_Rx |USART_Mode_Tx;
USART_http://ART_Parity=USART_Parity_No;
USART_http://ART_StopBits=USART_StopBits_1;
USART_http://ART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct);
}
void Set_2_rate(unsigned char rate_num)
{
USART_http://ART_BaudRate=boundrate[rate_num];
USART_http://ART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_http://ART_Mode=USART_Mode_Rx |USART_Mode_Tx;
USART_http://ART_Parity=USART_Parity_No;
USART_http://ART_StopBits=USART_StopBits_1;
USART_http://ART_WordLength=USART_WordLength_8b;
USART_Init(USART2,&USART_InitStruct);
}
void Set485Mode(unsigned char flag)
{
if(flag==RX_MODE)
GPIO_ResetBits(GPIOC,GPIO_Pin_1);
else if(flag==TX_MODE)
GPIO_SetBits(GPIOC,GPIO_Pin_1);
}
void _485PinConfig(void) //PC1作为485控制引脚
{
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStruct);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
while (1)
{}
}
#endif
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/