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

发布者:Jinghua6666最新更新时间:2016-06-03 来源: 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方式发送数据测试

上一篇:ARM裸机串口UART
下一篇:stm32 中DMA的stream和channel关系

推荐阅读最新更新时间:2024-03-16 14:56

STM32+W5500+MQTT+Android实现远程数据采集及控制
0 前言 最近在学习MQTT,发现MQTT还是挺好用的,于是花了点时间做了一个简单的应用示例,希望能给需要做这方面的人一些参考。 相关背景知识: http://www.embed-net.com/thread-224-1-1.html 具体功能为: 1,STM32F405为主控芯片,它通过传感器采集环境数据,比如温度,湿度,光照度,大气压强等; 2,主控芯片通过W5500模块将测量的数据通过MQTT协议方式发布到MQTT服务器(服务器域名和IP见固件程序); 3,主控订阅LED灯控制的消息,当接收到对应的控制指令后点亮或者熄灭对应的LED灯; 4,安卓手机端订阅传感器数据的消息,当接收到消息后将传感器数据在界面显示; 5,安卓手机
[单片机]
STM32+W5500+MQTT+Android实现远程数据采集及控制
基于多串口通信的柴油发电机组远程监控平台
    柴油发电机组在无市电供应及需要不间断 供电 的地方,如电信系统、 电力系统 、广播电视系统的机站、机房,银行、医院等单位的供电系统等得到了广泛应用。在电信系统内,通常一个县级局要管理多个供电机房,这些机房有的位于市区,有的位于偏僻的高山,有的有人值守,有的无人值守,但都需要不间断供电,一般每个机房有一至数台柴油发电机组,作为市电供电的备用 电源 ,或是几台机组互为主备供电。对这些柴油发电机组实现计算机自动监控和统一管理就显得很重要,这样有助于减少值班人员的工作强度,提高工作效率,提高管理水平。在县级局内设集中监控中心,监控主机通过公用电话网实现对各个下级机站柴油发电机组的远程实时自动监控和管理,系统构建方便,实现简单,使用可
[嵌入式]
HI3531串口测试程序(arm)
#include stdio.h unsigned int UART0_ADDR = 0x20080000; unsigned int retu=0; int i=0; void delay_x(unsigned short cycles) { unsigned short t; t = cycles; while ( --t != 0 ); } int main() { ///////////初始化部分//////////////////////////////////////////////////// retu = *(unsigned int *)(UART0_ADDR + 0X30);//uart_c
[单片机]
STM32的GPIO有几种输出模式及其说明
GPIO的基本结构 第一:开漏输出模式(N-MOS打开,高电平时,IO端口电平取决于外部的上拉电阻;低电平时,IO端口为底) 在图的上半部,施密特触发器处于开启状态,这意味着CPU可以在“输入数据寄存器”的另一端,随时监控I/O端口的状态;通过这个特性,还实现了虚拟的I/O端口双向通信:只要CPU输出逻辑“1”,由于编号3的N-MOS管处于关闭状态,I/O端口的电平将完全由外部电路决定,因此,CPU可以在“输入数据寄存器”读到外部电路的信号,而不是它自己输出的逻辑“1”。 当CPU在左边的编号1端通过位设置/清除寄存器,或输出数据寄存器写入数据后,该数据位将通过编号2的输出控制电
[单片机]
<font color='red'>STM32</font>的GPIO有几种输出模式及其说明
第45节:主机的串口收发综合程序框架
开场白: 在大部分的项目中,串口都需要 一收一应答 的握手协议,主机先发一串数据,从机收到数据后进行校验判断,如果校验正确则返回正确应答指令,如果校验错误则返回错误应答指令,主机收到应答指令后,如果发现是正确应答指令则继续发送其它的新数据,如果发现是错误应答指令,或者超时没有接收到任何应答指令,则继续重发,如果连续重发三次都是错误应答或者无应答,主机就进行报错处理。 上一节已经讲了从机,这节就讲主机的收发端程序实例。要教会大家四个知识点: 第一个:为了保证串口中断接收的数据不丢失,在初始化时必须设置IP= 0x10,相当于把串口中断设置为最高优先级,这个时候,串口中断可以打断任何其他的中断服务函数,实现中断嵌套。 第二个:
[单片机]
玩转STM32(10)CPU的脉搏
前面学习了怎么样下载程序到开发板, 并且可以运行起来,看到LED灯轮回地亮灭。你也许很好奇为什么LED会轮流地亮灭,像拥有生命一样,具有周期性地工作。要解决这个问题,我们得学习CPU的脉搏,那么什么是CPU的脉搏呢?其实CPU就是一堆泥沙和一些金属组成的,本身是不具备这种生命的特性,那么它周期性地工作的秘密又是什么呢?其实CPU之所以有这种特性,是因为它靠一个振荡电路来实现,这个振荡电路就是CPU的心脏,如果没有它是不可能产生任何的跳动。 在这个振荡电路里,你也许听过石英晶振这个名称,为什么要使用它呢?物理学家在研究物质的属性时,发现石英有一个特性,当把石英放在一个电场里,石英会变长,当电场去掉后,又可以恢复原来的长度。在这个
[单片机]
玩转<font color='red'>STM32</font>(10)CPU的脉搏
关于STM32的USART_GetFlagStatus和USART_GetITStatus解析(异步通信)
前言 STM32固件库中提供了串口收发的标志位函数,包括USART_GetFlagStatus(…,…);和USART_GetITStatus(…,…);,两者容易混淆,重点区别就在于:前者返回值是中断标志位状态(读SR寄存器),后者返回值是中断发生与否的判断(读CR寄存器),以下主要对这两个函数进行分析。 一、USART_GETFlagStatus(…,…) /** * @brief Checks whether the specified USART flag is set or not. * @param USARTx: Select the USART or the UART peripheral. *
[单片机]
关于<font color='red'>STM32</font>的USART_GetFlagStatus和USART_GetITStatus解析(异步通信)
关于STM32存储的堆栈地址
由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。-程序结束后有系统释放 4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放 5、程序代码区—存放函数体的二进制代码。 STM32的地址
[单片机]
关于<font color='red'>STM32</font>存储的堆栈地址
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved