前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >STM32F407-USART3+DMA空闲中断收发

STM32F407-USART3+DMA空闲中断收发

作者头像
用户11186929
发布2024-07-01 12:31:47
570
发布2024-07-01 12:31:47
举报
文章被收录于专栏:技术干货技术干货

usart3.c

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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);                    
    }
 
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档