usart3.c
#include "usart3.h"
#include "uart4.h"
#define G_DMA_RX3_LEN 100
#define G_DMA_TX3_LEN 100
uint8_t g_dma_rx3_buff[G_DMA_RX3_LEN];
uint8_t g_dma_tx3_buff[G_DMA_TX3_LEN];
uint16_t g_tx3_buff_len = 0;
static void Usart3GpioInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(USART3_GPIO_CLK,ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = USART3_GPIO_PIN; //GPIOB11与GPIOB10
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_Init(USART3_GPIO_PORT,&GPIO_InitStructure); //初始化PB10,PB11
//串口3对应引脚复用映射
GPIO_PinAFConfig(USART3_GPIO_PORT,USART3_TX_SOURCE,USART3_TX_AF); //GPIOB10复用为USART3
GPIO_PinAFConfig(USART3_GPIO_PORT,USART3_RX_SOURCE,USART3_RX_AF); //GPIOB11复用为USART3
}
static void Usart3Config(void)
{
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(USART3_CLK,ENABLE); //使能USART3时钟
//USART3 初始化设置
USART_InitStructure.USART_BaudRate = USART3_BAUDRATE; //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART3, &USART_InitStructure); //初始化串口3
}
static void Usart3NvicInit(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//Usart3 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //串口3中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
}
static void Usart3DmaRxInit(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(USART3_DMA_CLK,ENABLE); //DMA1时钟使能
DMA_DeInit(USART3_RX_DMA_STREAM);
while (DMA_GetCmdStatus(USART3_RX_DMA_STREAM) != DISABLE){} //等待DMA可配置
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full ;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ; //存储器突发单次传输
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // DMA_Mode_Circular DMA_Mode_Normal
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(USART3->DR)) ;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
/* Configure RX DMA */
DMA_InitStructure.DMA_Channel = USART3_RX_DMA_CHANNEL ;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // DMA_Mode_Circular DMA_Mode_Normal
DMA_InitStructure.DMA_BufferSize = G_DMA_RX3_LEN;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;
DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)g_dma_rx3_buff;
DMA_Init(USART3_RX_DMA_STREAM,&DMA_InitStructure);
DMA_Cmd(USART3_RX_DMA_STREAM,ENABLE); //开启接收
USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);
}
static void Usart3DmaTxInit(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(USART3_DMA_CLK,ENABLE); //DMA1时钟使能
DMA_DeInit(USART3_TX_DMA_STREAM);
while (DMA_GetCmdStatus(USART3_TX_DMA_STREAM) != DISABLE){} //等待DMA可配置
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full ;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ; //存储器突发单次传输
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // DMA_Mode_Circular DMA_Mode_Normal
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(USART3->DR)) ;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
/* Configure TX DMA */
DMA_InitStructure.DMA_Channel = USART3_RX_DMA_CHANNEL ;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DMA_Mode_Circular DMA_Mode_Normal
DMA_InitStructure.DMA_BufferSize = G_DMA_TX3_LEN;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral ;
DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)g_dma_tx3_buff ;
DMA_Init(USART3_TX_DMA_STREAM,&DMA_InitStructure);
USART_DMACmd(USART3,USART_DMAReq_Tx,ENABLE);
}
void Usart3Init(void)
{
Usart3GpioInit();
Usart3Config();
Usart3NvicInit();
Usart3DmaRxInit();
Usart3DmaTxInit();
USART_ClearITPendingBit(USART3, USART_IT_IDLE); //开启串口接受中断
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); //开启空闲中断
USART_Cmd(USART3, ENABLE); //使能串口3
}
void Usart3DmaSend(uint8_t *data_buf, uint16_t lengh)
{
DMA_Cmd(USART3_TX_DMA_STREAM,DISABLE);
Waiting_Disable_DMA(USART3_TX_DMA_STREAM);
//DMA_ITConfig(USART1_TX_DMA_STREAM,DMA_IT_FE,ENABLE);
//解析接收到的数据
memset(g_dma_tx3_buff, 0,G_DMA_TX3_LEN );
memcpy(g_dma_tx3_buff,data_buf,lengh);
/* Clear DMA Transfer Complete Flags */
DMA_ClearFlag(USART3_TX_DMA_STREAM,DMA_FLAG_TCIF3);
/* Clear USART Transfer Complete Flags */
USART_ClearFlag(USART3,USART_FLAG_TC);
DMA_SetCurrDataCounter(USART3_TX_DMA_STREAM,lengh);
DMA_Cmd(USART3_TX_DMA_STREAM,ENABLE);
}
void USART3_IRQHandler(void)
{
uint16_t lengh=0;
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) //接收中断
{
USART_ClearITPendingBit(USART3, USART_IT_IDLE); //清除空闲中断标志位(无效,持续进中断)
USART_ReceiveData(USART3); //清除空闲中断标志位
DMA_Cmd(USART3_RX_DMA_STREAM,DISABLE);
lengh= G_DMA_RX3_LEN - DMA_GetCurrDataCounter(USART3_RX_DMA_STREAM); //获得传输的数据个数
DMA_SetCurrDataCounter(USART3_RX_DMA_STREAM, G_DMA_RX3_LEN);
//解析接收到的数据
memcpy(g_dma_tx3_buff,g_dma_rx3_buff,lengh);
g_tx3_buff_len = lengh;
//发送数据
Usart3DmaSend(g_dma_tx3_buff,g_tx3_buff_len);
DMA_Cmd(USART3_RX_DMA_STREAM,ENABLE);
memset(g_dma_rx3_buff, 0, G_DMA_RX3_LEN); //清空接受区
memset(g_dma_tx3_buff, 0, G_DMA_TX3_LEN); //清空接受区
g_tx3_buff_len = 0;
}
}
usart3.h
#ifndef __USART3_H
#define __USART3_H
#include "stm32f4xx.h"
#include <stdio.h>
#include <string.h>
//GPIO
#define USART3_GPIO_PIN (GPIO_Pin_10 | GPIO_Pin_11)
#define USART3_GPIO_CLK RCC_AHB1Periph_GPIOB
#define USART3_GPIO_PORT GPIOB
#define USART3_RX_AF GPIO_AF_USART3
#define USART3_RX_SOURCE GPIO_PinSource11
#define USART3_TX_AF GPIO_AF_USART3
#define USART3_TX_SOURCE GPIO_PinSource10
// USART3
#define USART3_CLK RCC_APB1Periph_USART3
#define USART3_BAUDRATE 9600
// DMA
#define USART3_DMA_CLK RCC_AHB1Periph_DMA1
#define USART3_RX_DMA_CHANNEL DMA_Channel_4
#define USART3_RX_DMA_STREAM DMA1_Stream1
#define USART3_TX_DMA_CHANNEL DMA_Channel_4
#define USART3_TX_DMA_STREAM DMA1_Stream3
void Usart3Init(void);
uint8_t Usart3IsReady(void);
void Usart3DmaSend(uint8_t *data_buf, uint16_t lengh);
void Usart_SendStr_length( USART_TypeDef * pUSARTx, uint8_t *str,uint32_t strlen );
void Usart_SendString( USART_TypeDef * pUSARTx, uint8_t *str);
#endif /* __USART3_H */
main.c
#include "stm32f4xx.h"
#include "systick.h"
#include "usart3.h"
int main()
{
uint8_t data_Buffer[8]= {01,02,03,04,05,06,07};
Usart3Init();
//printf("That OK!\n");
while(1)
{
Usart3DmaSend(data_Buffer,8);
Delay_ms(500);
Usart3IsReady();
Delay_ms(500);
}
}