STM32的串口采用DMA方式发送数据测试

发布者:GoldenEclipse最新更新时间:2020-10-09 来源: eefocus关键字:STM32  串口  DMA方式  发送数据 手机看文章 扫描二维码
随时随地手机看文章

环境:


主机:WIN7


开发环境:MDK4.23


MCU:STM32F103CBT6



源代码:


配置:



//---------------------串口功能配置---------------------

//打开串口对应的外设时钟  

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);   

//启动DMA时钟

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

//DMA发送中断设置

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//DMA1通道4配置

DMA_DeInit(DMA1_Channel4);

//外设地址

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);

//内存地址

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Uart_Send_Buffer;

//dma传输方向单向

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

//设置DMA在传输时缓冲区的长度

DMA_InitStructure.DMA_BufferSize = 100;

//设置DMA的外设递增模式,一个外设

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

//设置DMA的内存递增模式

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

//外设数据字长

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

//内存数据字长

DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;

//设置DMA的传输模式

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

//设置DMA的优先级别

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

//设置DMA的2个memory中的变量互相访问

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel4,&DMA_InitStructure);

DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);

 

//使能通道4

//DMA_Cmd(DMA1_Channel4, ENABLE);

 

  

//初始化参数  

//USART_InitStructure.USART_BaudRate = DEFAULT_BAUD;  

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_InitStructure.USART_BaudRate = DEFAULT_BAUD; 

//初始化串口 

USART_Init(USART1,&USART_InitStructure);  

//TXE发送中断,TC传输完成中断,RXNE接收中断,PE奇偶错误中断,可以是多个   

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);  

 

//配置UART1中断  

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;               //通道设置为串口1中断  

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;       //中断占先等级0  

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;              //中断响应优先级0  

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //打开中断  

NVIC_Init(&NVIC_InitStructure);                                 //初始化  

 

//采用DMA方式发送

USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);

//启动串口  

USART_Cmd(USART1, ENABLE);   

 

//设置IO口时钟      

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);    

//串口1的管脚初始化    

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                       //管脚9  

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                //选择GPIO响应速度  

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                 //复用推挽输出  

GPIO_Init(GPIOA, &GPIO_InitStructure);                          //TX初始化  

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                      //管脚10  

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                //选择GPIO响应速度  

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;           //浮空输入  

GPIO_Init(GPIOA, &GPIO_InitStructure);                          //RX初始化                                                      

 

//设置IO口时钟      

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);   

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                       //管脚9  

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                //选择GPIO响应速度  

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                 //复用推挽输出  


中断函数:


//串口1DMA方式发送中断

void DMA1_Channel4_IRQHandler(void)

{

//清除标志位

  DMA_ClearFlag(DMA1_FLAG_TC4);

//DMA_ClearITPendingBit(DMA1_FLAG_TC4);

  //DMA1->IFCR |= DMA1_FLAG_TC4;

//关闭DMA

DMA_Cmd(DMA1_Channel4,DISABLE);

  //DMA1_Channel4->CCR &= ~(1<<0);

 

//允许再次发送

Flag_Uart_Send = 0;

}


发送测试:


//串口DMA发送测试

Uart_Send_Buffer[0] = 1;

Uart_Send_Buffer[1] = 2;

Uart_Send_Buffer[2] = 3;

Uart_Send_Buffer[3] = 4;

Uart_Send_Buffer[4] = 5;

i = 1;

while (1)

{

//检查串口是否可以发送

while (Flag_Uart_Send);

Flag_Uart_Send = 1;

//设置传输数据长度

DMA_SetCurrDataCounter(DMA1_Channel4,i);

//打开DMA

DMA_Cmd(DMA1_Channel4,ENABLE);

i++;

if (i > 5)

{

i = 1;

}

}


关键字:STM32  串口  DMA方式  发送数据 引用地址:STM32的串口采用DMA方式发送数据测试

上一篇:STM32的串口采用DMA方式接收数据测试
下一篇:STM32通过DMA采集多通道AD

推荐阅读最新更新时间:2024-11-10 20:48

STM8学习笔记----普通IO口模拟串口功能
串口在产品应用中很常见,但是单片机的默认带的串口往往比较少,有时候就会出现串口不够用,所以就想着能不能用普通IO口模拟串口来实现串口的功能。 要模拟串口首先要清楚串口数据传输过程中的原理。 常用的串口格式为 1位起始位,8位数据位,无校验位,1位结束位。起始位为低电平,结束位为高电平。数据0为低电平,数据1为高电平。 所以最简单的串口传输一个字节总共有10个电平变化,每个电平的宽度由波特率决定的。 具体的串口数据分析,可以参考这篇文章:STM8学习笔记---通过示波器分析串口数据。 下面看一个通过波特率如何计算每个位的电平宽度。 发送一个字节,以stm8中9600bit/s的波特率计算的过程为例(1秒钟传输
[单片机]
STM8学习笔记----普通IO口模拟<font color='red'>串口</font>功能
STM32 spi与FPGA的通信
最近在研究SPI总线,至于协议和硬件描述就不多说了 四线包括时钟、片选、接收、发送 初始化SP SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; //16bit宽度 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure
[单片机]
在ubuntu下利用eclipse搭建stm32开发环境和st-link调试
一、下载eclipse: 我们选择的工具为Eclipse IDE for C/C++ Developers,官网下载地址在 https://www.eclipse.org/downloads/packages/release/helios/sr2/eclipse-ide-cc-developers 若网址打不开或下载速度慢,可选用百度云链接: https://pan.baidu.com/s/10bMkwr1hyL0FDf-NXaruAA 解压安装包并复制到自己安装的安装目录。 二、下载gcc-arm-none-eabi: 在终端输入 sudo apt-get install gcc-arm-none-eabi
[单片机]
在ubuntu下利用eclipse搭建<font color='red'>stm32</font>开发环境和st-link调试
STM32从入门到精通—I2C 简介
I2C端口,即内部集成电路接口,I2C总线接口用作微控制器和I2C串行总线之间的接口,提供多主模式功能,可以控制所有I2C总线特定的序列、协议、仲裁和时序。它支持标准和快速模式。 I2C可用于多种用途,包括CRC生成和验证、SMBus(系统管理总线)以及PMBus(电源管理总线)。 I2C主要特性 并行总线/I2C协议转换器 多主模式功能:同一接口既可用作主模式也可用作从模式 I2C主模式特性: 1. 时钟生成 2. 起始位和停止位生成 I2C从模式特性: 1. 可编程I2C地址检测 2. 双寻址模式,可对2个从地址应答 3. 停止位检测 7位/10位寻址以及广播呼叫的生成和检测 支持不同的通信速度: 1
[单片机]
STM32-使用定时器做延时函数时遇到的坑
做延时函数,可以使用简单的循环等待,如下面这样的: void Delay(uint32_t nCount) { for(; nCount != 0; nCount--); } 但是有个问题,就是这个nCount值怎么取? 我们可以通过多次试验,来确定调用时使用的循环次数。 但是还要考虑下,如果硬件有变化,例如外接晶振变化,或类似的主芯片替换等情况下,这个值有可能会变化。另外,编译的优化选项变化,也可能导致循环次数的变化。也就是说,这样写的延时函数,对外部的依赖项比较多,稍不注意,可能最终的延时时间不准确。 更好的延时方式是使用定时器,这样能更准确的定时,并且移植性也更好一些。 但是使用定时器做延时函数时,也是有一些需要注意
[单片机]
从一无所知的开始 学习stm32
首先说下博主不是什么大牛,还是一名在校的大二学生,主要是想学习STM32,想通过学习STM32,然后通过博客来记些笔记,来提高自己的能力。 好了,来进入主题。哦,就是这个feel! 首先就是学习STM32,就是需要有自己的一块开发板,我用的就是实验室学长留下的一个野火板。自己感觉还是不错的。 首先我们需学习怎么建立一个STM32的工程。 首先在建立一个模板,以方便自己以后使用。我是在桌面上,建立一个文件夹,取名模板。然后在模板里面建立几个文件夹如下图所示: 然后就是找到stm32的库,然后开始往自己的模板里写入一些启动文件和官方文件。我用的就是3.5版本的,3.0版本与3.5版本还是有区别的。 下面就开始往每个文件里添加
[单片机]
从一无所知的开始 学习<font color='red'>stm32</font>
STM32之BKP原理
1. BKP可以用来保存数据 BKP中包括了42个16位的寄存器,共可保存84字节的内容,它们由VBAT的供电来维挂。 2. BKP内保存的数据可以被毁灭(如果有人希望恶意得到这些数据的话,令其丢失比保护数据更重要)。STM32提供了一种称之为TAMPER的机制来完成。中文译为“侵入检测”,这需要占用一个外部引脚(PC13)。 3. 如果不用侵入检测功能,那么这个外部引脚可以用作RTC校准功能,这个稍后再研究。 4. 当有系统复位/电源复位/待机模式下被唤醒这三种情况时,BKP中的值不会丢失或被复位。 先回来研究一下STM32的复位机制。以下是数据手册的相关部分。 6.1 复位 ST
[单片机]
STM32之五外部中断(下)
通过对外部中断理论的些许理解,这次我们利用两个按键key1和key2来控制led1和led2的亮灭,按key1进入key1的中断,控制对应的led亮灭,按key2进入key2的中断,控制相应的led的亮灭 同样,涉及到中断,我们要建立两个文件,exti.c及exti.h,首先来看看exti.c 用到中断,自然我们要用到stm32f10x_it.c函数,将中断响应函数放在里面,打开这个文件你会发现里面只是给出了部分中断函数,找来找去也没有我们需要的中断函数体,这时需要我们自己添加函数体,看下我添加的函数体: 但是这个函数名可不是随便起的,具体每个中断函数体的函数名怎么书写,我们可以打开startup_stm32f10x_hd.
[单片机]
<font color='red'>STM32</font>之五外部中断(下)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved