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;
}
#endifuint8_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