STM32F3使用USART串口DMA发送数据,使用蓝牙发送

Author: Wind

OS:   WIN7

IDE:    KEIL uvision V5.10.0.2

MCU: STM32 F303 VC T6

一、硬件设计

1.MCU使用USART2,USART2_TX——PA2, USART2_RX——PA3

2.DMA:查看ST官方网站的STM32F3参考手册(官网下载),使用DMA1  Channel7


3.MCU与蓝牙模块连接:


二、程序代码

1.USART配置:查看ST官方固件库手册(官网下载),按顺序进行配置,以下复制原文:

//23.2 USART Firmware driver API description

The following section lists the various functions of the USART library.

23.2.1 How to use this driver 

1. Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE) function for USART1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) function for USART2, USART3, UART4 and UART5. 

2. According to the USART mode, enable the GPIO clocks using RCC_AHBPeriphClockCmd() function. (The I/O can be TX, RX, CTS, or and SCLK). 3. Peripheral's alternate function:  Connect the pin to the desired peripherals' Alternate Function (AF) using GPIO_PinAFConfig() function.

 Configure the desired pin in alternate function by: GPIO_InitStruct->GPIO_Mode=

GPIO_Mode_AF.

 Select the type, pull-up/pull-down and output speed via GPIO_PuPd,

GPIO_OType and GPIO_Speed members.

 Call GPIO_Init() function.

4. Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware flow control and

Mode(Receiver/Transmitter) using the SPI_Init() function.

5. For synchronous mode, enable the clock and program the polarity, phase and last bit

using the USART_ClockInit() function.

6. Enable the NVIC and the corresponding interrupt using the function

USART_ITConfig() if you need to use interrupt mode.

7. When using the DMA mode:

 Configure the DMA using DMA_Init() function.

 Active the needed channel Request using USART_DMACmd() function.

8. Enable the USART using the USART_Cmd() function.

9. Enable the DMA using the DMA_Cmd() function, when using DMA mode.

2.DMA配置

//9.2 DMA Firmware driver API description

     The following section lists the various functions of the DMA library.

     9.2.1 How to use this driver

1. Enable The DMA controller clock using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE) function for DMA1 or using   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE) function for DMA2.

2. Enable and configure the peripheral to be connected to the DMA channel (except for internal SRAM / FLASH memories: no initialization is necessary).

3. For a given Channel, program the Source and Destination addresses, the transfer Direction, the Buffer Size, the Peripheral and Memory Incrementation mode and Data Size, the Circular or Normal mode, the channel transfer Priority and the Memory- to- Memory transfer mode (if needed) using the DMA_Init() function.

4. Enable the NVIC and the corresponding interrupt(s) using the function DMA_ITConfig() if you need to use DMA interrupts.

5. Enable the DMA channel using the DMA_Cmd() function.

6. Activate the needed channel Request using PPP_DMACmd() function for any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...) The function allowing this operation is provided in each PPP peripheral driver (ie. SPI_DMACmd for SPI peripheral).

7. Optionally, you can configure the number of data to be transferred when the channel is disabled (ie. after each Transfer Complete event or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter(). And you can get the number of remaining data to be transferred using the function DMA_GetCurrDataCounter() at run time (when the DMA channel is enabled and running).

8. To control DMA events you can use one of the following two methods:

a. Check on DMA channel flags using the function DMA_GetFlagStatus().

b. Use DMA interrupts through the function DMA_ITConfig() at initialization phase and DMA_GetITStatus() function into interrupt routines in communication phase. After checking on a flag you should clear it using DMA_ClearFlag() function. And after checking on an interrupt event you should clear it using DMA_ClearITPendingBit() function.

3.开始发送,使能各功能模块

源代码:
</pre><pre name="code" class="cpp">
<pre name="code" class="cpp">/**************************************************/
// Header:
// File Name: 	main.h
// Author:	Wind	
// Date:	2015.01.25
/**************************************************/

#ifndef MAIN_H
#define MAIN_H

#include "stm32f30x.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_dma.h"
#include "Config.h"

#endif
/*****************************************/

/**************************************************/
// Header:
// File Name: main.c
// Author:	Wind	
// Date:	2015.01.25
/**************************************************/

#include "main.h"

#define BT_TX_BUFFER_LENGTH 26 //发送26个字母

static uint8_t BT_TX_Buffer[BT_TX_BUFFER_LENGTH];

/**************************************************/

int main()
{
	uint8_t i=0,data='A';
	
	BTUSARTConfig(115200);//波特率115200
	BTDMAConfig((uint32_t) BT_TX_Buffer,BT_TX_BUFFER_LENGTH);
	
	//准备好待发送的数据
	for (i=0;i<BT_TX_BUFFER_LENGTH;i++,data++)
	{
		BT_TX_Buffer[i] = data;
	}
	
	//开始发送
	StartDataTransfer();
	
	while(1);  //持续发送,同时CPU可以做其他事情

}

/**********************************************************/
/**************************************************/
// Header:
// File Name:	 Config.h
// Author:	Wind	
// Date:	2015.01.25
/**************************************************/

#ifndef CONFIG_H
#define CONFIG_H

#include "stm32f30x.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_dma.h"

// Bluetooth port settings
#define BT_USART_IO_PORT GPIOA
#define BT_TX_PIN GPIO_Pin_2
#define BT_RX_PIN GPIO_Pin_3
#define BT_TX_SOURCE GPIO_PinSource2
#define BT_RX_SOURCE GPIO_PinSource3
#define BT_USART_GPIO_CLK RCC_AHBPeriph_GPIOA
#define BT_USART_CLK RCC_APB1Periph_USART2
#define BT_TX_AF GPIO_AF_USART2
#define BT_RX_AF GPIO_AF_USART2
#define GPIO_AF_USART2 GPIO_AF_7 
#define BT_USART_PORT USART2
#define BT_USART_TDR_ADDRESS ((uint32_t)USART2 + 0x28) 
#define BT_USART_RDR_ADDRESS ((uint32_t)USART2 + 0x24) 
#define BT_USART_DMA_PORT DMA1
#define BT_USART_DMA_CLK RCC_AHBPeriph_DMA1
#define BT_USART_TX_DMA_CHANNEL DMA1_Channel7
#define BT_USART_RX_DMA_CHANNEL DMA1_Channel6
#define BT_USART_TX_DMA_FLAG_TCIF DMA1_FLAG_TC7
#define BT_USART_RX_DMA_FLAG_TCIF DMA1_FLAG_TC6

//Function declaration

void BTUSARTConfig(uint32_t baudrate);
void BTDMAConfig(uint32_t DataAddr,uint8_t dataLength);
void StartDataTransfer(void);

#endif
/****************************************************************/
/**************************************************/
// Header:
// File Name: 	Config.c
// Author:	Wind	
// Date:	2015.01.25
/**************************************************/

#include "Config.h"


/**************************************************/

//USART配置
void BTUSARTConfig(uint32_t baudrate)
{
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_AHBPeriphClockCmd(BT_USART_GPIO_CLK, ENABLE);
	RCC_APB1PeriphClockCmd(BT_USART_CLK, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = (BT_TX_PIN | BT_RX_PIN);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;              //复用模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	
	GPIO_Init(BT_USART_IO_PORT, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(BT_USART_IO_PORT, BT_TX_SOURCE, BT_TX_AF);
	GPIO_PinAFConfig(BT_USART_IO_PORT, BT_RX_SOURCE, BT_RX_AF);
	
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	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_DeInit(BT_USART_PORT);
	USART_Init(BT_USART_PORT, &USART_InitStructure);
	
	USART_Cmd(BT_USART_PORT, ENABLE);
}


//DMA配置
//para:dataAddr:Transffer data address;dataLength:Transffer data length
void BTDMAConfig(uint32_t dataAddr,uint8_t dataLength)
{
	DMA_InitTypeDef DMA_InitStructure;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	
	DMA_StructInit(&DMA_InitStructure);
	DMA_DeInit(BT_USART_TX_DMA_CHANNEL); 
	
	DMA_InitStructure.DMA_PeripheralBaseAddr = BT_USART_TDR_ADDRESS;
	DMA_InitStructure.DMA_MemoryBaseAddr = dataAddr;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;        //外设作为发送目的地
	DMA_InitStructure.DMA_BufferSize = dataLength;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;									//Ñ­»··¢ËÍģʽ
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	
	DMA_Init(BT_USART_TX_DMA_CHANNEL,&DMA_InitStructure);
	
}
	
//开始发送
void StartDataTransfer(void)
{
	//清除标志位,否则会丢失部分数据
	USART_ClearFlag(BT_USART_PORT,USART_FLAG_TC);
	DMA_ClearFlag(BT_USART_TX_DMA_FLAG_TCIF);
	
	//发送	
	USART_DMACmd(BT_USART_PORT,USART_DMAReq_Tx,ENABLE);
	DMA_Cmd(BT_USART_TX_DMA_CHANNEL,ENABLE);
	//等待发送完毕
	while (!DMA_GetFlagStatus(BT_USART_TX_DMA_FLAG_TCIF));
}
/**********************************************************/


 

 
 

 
 

 


  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F103 USART使用DMA接收发送的框图如下: ![STM32F103的USART使用DMA接收发送框图](https://i.imgur.com/rsldyhT.png) 首先,框图中的USART模块用来实现与外部设备进行串行通信。USART模块包括了发送器和接收器两个功能部分。发送器负责将数据从处理器发送到外部设备,接收器负责将外部设备发送的数据接收到处理器。 在USART模块的发送/接收方向,连接有DMA控制器。DMA(直接存储器访问)是一种独立于处理器的数据传输方式,它通过直接从外部设备读写数据,而不需要处理器的干预。DMA控制器有多个通道,用于连接不同的外设。在本框图中,DMA通道与USART模块相连。 对于USART发送,当处理器要发送数据时,首先将待发送数据写入USART模块的发送寄存器。然后,触发DMA控制器,将发送寄存器中的数据送到DMA通道,最后DMA将数据传输到USART外设,并且把发送完的数据长度传送到处理器,以便处理器知道数据是否发送完成。 对于USART的接收,当外部设备发送数据USART接收寄存器时,触发USART接收中断,通知处理器接收到了数据。然后,处理器触发DMA控制器,将接收数据的DMA通道启动,将数据从USART外设传输到DMA寄存器。接着,处理器可以通过查询DMA寄存器,获取接收到的数据。 通过使用DMA接收和发送数据,可以减轻处理器的负担,提高系统的运行效率。 ### 回答2: stm32f103是意法半导体推出的一款32位单片机系列产品,其中USART是一种通用异步收发传输器。使用DMA(直接存储器访问)来实现USART接收和发送功能,可以提高数据传输的效率。 以下是STM32F103 USART使用DMA接收发送的框图解读: 1. USART 模块:USART模块是STM32F103系列中的一种通信模块,用于数据的异步传输。它包含了需要将数据发送到外部设备或从外部设备接收数据的各种寄存器和控制逻辑。 2. DMA控制器:DMA控制器是STM32F103系列中的一个重要模块,用于在外设和内存之间进行高速数据传输,减少CPU的负担。 3. 数据内存:数据内存用于存储接收到的数据或待发送的数据。 4. NVIC:NVIC是中断控制器,用于管理各种中断源和中断优先级。 5. DMA传输请求:当USART接收或发送缓冲区准备好数据时,会产生DMA传输请求,将数据传输到或从数据内存。 6. DMA配置寄存器:DMA配置寄存器用于配置DMA通道的参数,如数据传输方向、数据长度等。 7. DMA传输完成中断:当DMA传输完成时,会产生中断请求,引起中断处理程序的执行。 8. 中断处理程序:中断处理程序负责处理DMA传输完成中断请求,可以在中断处理程序中对接收到的数据进行处理或触发其他操作。 通过使用DMA来实现USART接收和发送,可以实现数据的高效传输和处理。接收时,当USART接收缓冲器准备好数据后,它会产生DMA传输请求,将数据传输到数据内存中。当数据传输完成时,DMA会产生中断请求,触发中断处理程序对接收到的数据进行处理。发送时,将待发送的数据写入数据内存,并设置DMA传输方向和数据长度等参数。DMA会自动从数据内存中读取数据并将其传输到USART发送缓冲器进行发送。当数据传输完成时,同样会产生DMA传输完成中断请求。 总之,使用DMA来处理USART的接收和发送,可以提高数据传输效率,减轻CPU负担,从而更好地满足系统对数据通信的需求。 ### 回答3: STM32F103是一款32位的ARM Cortex-M3系列微控制器,具有多个通用同步/异步收发器(USART)接口,用于与外部设备进行数据通信。这款芯片还支持使用DMA(直接内存访问)功能来实现USART的数据传输。 在使用DMA进行数据接收和发送时,首先需要设置USART的相应寄存器(例如,配置波特率、数据位数和停止位等参数),然后设置DMA控制器的寄存器,以使其与特定的USART通道相连接。 接下来,通过配置DMA通道的源和目的地址,将USART的RDR(接收数据寄存器)作为DMA的源地址,将USART的TDR(发送数据寄存器)作为DMA的目的地址。然后,设置DMA通道的传输数量,以确定需要传输的数据的大小。 在接收数据时,一旦USART接收到数据,并将其存储在RDR寄存器中,DMA控制器就会自动将该数据从RDR寄存器传输到目的地址。这样,通过DMA传输数据可以减轻主CPU的负担,提高数据传输效率。 在发送数据时,将要发送的数据存储在TDR寄存器中,并通过DMA控制器将其传输到目的地址。这样,通过DMA发送数据可以使主CPU能够在数据传输过程中执行其他任务,提高整个系统的性能。 总结起来,使用DMA进行USART数据接收和发送时,需要配置USARTDMA控制器的寄存器,并设置源和目的地址以及传输数量。通过这种方式,可以实现高效的数据传输,减轻主CPU的负担,提高系统的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值