五、STM32F407VET6串口2改为DMA模式

       1、第四章建立好的串口2程序

        2、编译环境MDK5(KEIL5)   

        3、一个STM32F407VET6硬件

        4、一个下载器j-link 或 st-link等

        5.代码编辑器 Notepad++   (可以不要 用记事本也能编译  都是习惯的问题)

        6.USB转TTL设备  用于连接电脑串口助手

壹、复制串口2程序

1.1 复制串口2程序并进行重命名

贰、修改BSP_DEBUG.c与BSP_DEBUG.h代码

2.1 打开BSP_DEBUG.c修改为

#include "BSP_DEBUG.h"

#include <string.h>  

#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 

    int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 

    x = x; 

//重定义fputc函数 
int fputc(int ch, FILE *f)
{     
    while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   
    USART2->DR = (u8) ch;      
    return ch;
}
#endif

uint8_t   USART2_TX_BUF[USART2_MAX_TX_LEN];         //发送缓冲,最大USART2_MAX_TX_LEN-1字节
//uint8_t   USART2_RX_BUF[USART2_MAX_RX_LEN];         //接收缓冲,最大USART2_MAX_RX_LEN-1字节    

_USART_FLAG USART2_FLAG ;


#define RCC_AHBxPeriph_DMAy                 RCC_AHB1Periph_DMA1
 
#define USART2_TX_DMAx_Streamy_IRQHandler   DMA1_Stream6_IRQHandler
#define USART2_TX_DMAx_Streamy_IRQn         DMA1_Stream6_IRQn
#define USART2_TX_DMAx_Streamy              DMA1_Stream6
#define USART2_TX_DMA_IT_TCIFx              DMA_IT_TCIF6
#define USART2_TX_DMA_Channelx              DMA_Channel_4


void BSP_DEBUG_Send_ascii(uint8_t* p,uint16_t length)
{
        uint16_t i;
    printf("\r\n");

    for(i =0;i<length;i++)
    {
        printf(" %02X ",p[i]);
    }
    printf("\r\n");        
}
void DMA_USART2_Init(void)
{
    DMA_InitTypeDef DMA_USART2_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_AHB1PeriphClockCmd(RCC_AHBxPeriph_DMAy, ENABLE);                                          //启动DMA时钟

    //发送 DMA通道配置
    DMA_DeInit(USART2_TX_DMAx_Streamy);                                                           //DMA数据流
    DMA_USART2_InitStructure.DMA_Channel            = USART2_TX_DMA_Channelx;                     //DMA通道
    DMA_USART2_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);                    //外设地址
    DMA_USART2_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)USART2_TX_BUF;                    //内存地址
    DMA_USART2_InitStructure.DMA_DIR                = DMA_DIR_MemoryToPeripheral;                  //dma传输方向
    DMA_USART2_InitStructure.DMA_BufferSize         = USART2_MAX_TX_LEN;                          //设置DMA在传输时缓冲区的长度
    DMA_USART2_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;                  //设置DMA的外设递增模式,一个外设
    DMA_USART2_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;                          //设置DMA的内存递增模式
    DMA_USART2_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;                //外设数据字长
    DMA_USART2_InitStructure.DMA_MemoryDataSize     = DMA_PeripheralDataSize_Byte;                //内存数据字长
    DMA_USART2_InitStructure.DMA_Mode               = DMA_Mode_Normal;                            //设置DMA的传输模式
    DMA_USART2_InitStructure.DMA_Priority           = DMA_Priority_High;                          //设置DMA的优先级别
    DMA_USART2_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;                       //指定如果FIFO模式或直接模式将用于指定的流 : 不使能FIFO模式     
    DMA_USART2_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_HalfFull;                 //指定了FIFO阈值水平       
    DMA_USART2_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;                     //指定的Burst转移配置内存传输        
    DMA_USART2_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;                  //指定的Burst转移配置外围转移       
    DMA_Init(USART2_TX_DMAx_Streamy, &DMA_USART2_InitStructure);                                  //配置DMA的通道    

  DMA_ClearITPendingBit(USART2_TX_DMAx_Streamy,USART2_TX_DMA_IT_TCIFx);                         //清除标志位  
  DMA_Cmd(USART2_TX_DMAx_Streamy, DISABLE);                                                     //关闭DMA
    DMA_ITConfig(USART2_TX_DMAx_Streamy,DMA_IT_TC,ENABLE);                                        //使能发送完成中断  
    
    NVIC_InitStructure.NVIC_IRQChannel                   = USART2_TX_DMAx_Streamy_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 6;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE);                                                  //采用DMA方式发送
}
void BSP_DEBUG_Init(uint32_t bound )
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;
    
    while(USART2_FLAG.DMA_Tx_flag == 1);//防止DMA发送中设置,打断发送
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
 
  //串口2引脚复用映射    
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_USART2); //GPIOA2复用为USART2
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource6,GPIO_AF_USART2); //GPIOA3复用为USART2  

    //USART2    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; //GPIOA2与GPIOA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;    //速度100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
    GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化PA2,PA3 
    
    //初始化设置
    USART_InitStructure.USART_BaudRate                   = bound;                         //串口波特率
    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(USART2, &USART_InitStructure);                                             //初始化串口
    
//    //NVIC配置
//    NVIC_InitStructure.NVIC_IRQChannel                   = USART2_IRQn;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 5;        
//    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;             
//    NVIC_Init(&NVIC_InitStructure);     
//  
//    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);                                        //开启串口空闲IDEL中断
    USART_Cmd(USART2, ENABLE);                                                            //使能串口 
    
  DMA_USART2_Init();                                                                    //串口 DMA 配置

//    printf("USART2 OK...\r\n");
}

//DMA 发送应用源码
void DMA_USART2_Tx_Data(uint16_t size)  
{         
        USART2_FLAG.DMA_Tx_flag = 1;
    DMA_SetCurrDataCounter(USART2_TX_DMAx_Streamy,size);                         //设置传输数据长度 
    DMA_Cmd(USART2_TX_DMAx_Streamy,ENABLE);                                      //打开DMA,开始发送  

void USART2_TX_DMAx_Streamy_IRQHandler(void)  
{                                                               
    if(DMA_GetITStatus(USART2_TX_DMAx_Streamy,USART2_TX_DMA_IT_TCIFx) != RESET)   
    {  
        DMA_ClearITPendingBit(USART2_TX_DMAx_Streamy,USART2_TX_DMA_IT_TCIFx);    //清除标志位    
        DMA_Cmd(USART2_TX_DMAx_Streamy,DISABLE);                                 //关闭DMA  
                USART2_FLAG.DMA_Tx_flag = 0;                                             //发送完成
        }       

void BSP_Send_Array (uint8_t *array,uint16_t num)
{
    while(USART2_FLAG.DMA_Tx_flag==1);
    memcpy(USART2_TX_BUF,array,num);
    DMA_USART2_Tx_Data(num);
}     

2.2 打开BSP_DEBUG.h修改为


#ifndef __BSP_DEBUG_H
#define __BSP_DEBUG_H
#include "stm32f4xx.h"
#include "stdio.h"    


#define  USART2_MAX_TX_LEN                   200 //最大发送缓存字节数,刨去\0 最大-1
//#define  USART2_MAX_RX_LEN                   200 //最大接收缓存字节数,刨去\0 最大-1
extern   uint8_t   USART2_TX_BUF[USART2_MAX_TX_LEN];//发送缓冲区
//extern   uint8_t   USART2_RX_BUF[USART2_MAX_RX_LEN];//接收缓冲区                                  

typedef struct
{
    uint8_t     DMA_Tx_flag;                    //DMA忙碌标志,1    
    uint8_t     DMA_Rx_flag;                    //DMA接收完成标志,0
        uint16_t    Tx_LEN;
        uint16_t    Rx_LEN;    
}_USART_FLAG;


extern    _USART_FLAG USART2_FLAG ;
//extern    void USART2_DEBUG_callback(uint8_t* p,uint16_t length);

 
extern    void     BSP_DEBUG_init(uint32_t bound);
extern    void     BSP_Send_Array (uint8_t *array,uint16_t num);
extern     void    BSP_DEBUG_Send_ascii(uint8_t* p,uint16_t length);   


#endif 

伍、编译下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值