STM32F103 UART4 DMA接收

发布者:王大雷最新更新时间:2019-07-22 来源: eefocus关键字:STM32F103  UART4  DMA接收 手机看文章 扫描二维码
随时随地手机看文章

//网上找了老半天也找不到UART4-DMA的程序,自己调试成功了,特地分享一下

uint8_t UART4_Rx_buffer[512],UART4_Rx_num;

void UART4_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;             

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

DMA_InitTypeDef DMA_InitStructure; //定义DMA初始化结构体DMA_InitStructure 

    

// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //选择NVIC优先级分组0  

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

 

//串口4所使用管脚输出输入定义

//定义UART4 Tx (PC.10)脚为复用推挽输出

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;         //IO口的第2脚

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度

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

GPIO_Init(GPIOC, &GPIO_InitStructure);            //初始化串口1输出IO口

//定义 UART4 Rx (PC.11)为悬空输入 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;           //IO口的第3脚

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//IO口悬空输入

GPIO_Init(GPIOC, &GPIO_InitStructure);               //初始化串口1输入IO口

 

//串口4参数初始化定义部分,串口1参数为9600 , 8 ,1 ,N  接收中断方式  

USART_InitStructure.USART_BaudRate = 9600;                  //设定传输速率

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_Init(UART4, &USART_InitStructure);      //初始化串口4

USART_ITConfig(UART4, USART_IT_IDLE,ENABLE);  //使能串口4接收中断

USART_Cmd(UART4, ENABLE);                     //使能串口4

USART_ClearFlag(UART4, USART_FLAG_TC);        // 清标志(后增加)

 

DMA_DeInit(DMA2_Channel3); //重置DMA 2通道配置

DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004C04; //外设地址  

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)UART4_Rx_buffer; //内存地址  

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为数据目的地 

DMA_InitStructure.DMA_BufferSize = 512; //DMA缓存大小:BufferSize 

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不递增  

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;   //内存地址寄存器递增

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度为8位 

DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; //内存数据宽度为8位 

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在正常缓存模式 

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //设置DMA通道优先级为高 

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止DMA通道设置为内存至内存传输 

DMA_Init(DMA2_Channel3, &DMA_InitStructure); //初始化

  

  DMA_ITConfig(DMA2_Channel3, DMA_IT_TC, ENABLE);

DMA_ITConfig(DMA2_Channel3, DMA_IT_TE, ENABLE);

 

USART_DMACmd(UART4, USART_DMAReq_Rx, ENABLE);

DMA_Cmd(DMA2_Channel3, ENABLE);

//使能串口4中断

NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

 

NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn; 

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; 

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 

NVIC_Init(&NVIC_InitStructure);

 }

void UART4_IRQHandler(void)

{

uint16_t i;

uint16_t Data_Len;

if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET)    //如果为中断

{  

DMA_Cmd(DMA2_Channel3, DISABLE);

Data_Len=512-DMA_GetCurrDataCounter(DMA2_Channel3);

USART_PutStr(USART1,UART4_Rx_buffer,Data_Len);

UART4_Rx_num=0;

DMA_ClearFlag(DMA2_FLAG_GL3 | DMA2_FLAG_TC3 | DMA2_FLAG_TE3 | DMA2_FLAG_HT3); //清标志

DMA2_Channel3->CNDTR = 512;                //重装填

DMA_Cmd(DMA2_Channel3, ENABLE);            //处理完,重开DMA

//读SR后读DR清除IDLE

i = UART4->SR;

i = UART4->DR;

if(i) i=0;

if(Data_Len) Data_Len=0;   

}

if(USART_GetITStatus(UART4, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET){    //出错

USART_ClearITPendingBit(UART4, USART_IT_PE | USART_IT_FE | USART_IT_NE);

}

USART_ClearITPendingBit(UART4, USART_IT_TC);

USART_ClearITPendingBit(UART4, USART_IT_IDLE);

}

void DMA2_Channel3_IRQHandler(void)

{

	USART_PutStr(USART1," DMA23:rn",9);

DMA_ClearITPendingBit(DMA2_IT_TC3);

DMA_ClearITPendingBit(DMA2_IT_TE3);

DMA_Cmd(DMA2_Channel3, DISABLE);         //关闭DMA,防止处理其间有数据

DMA2_Channel3->CNDTR = 512;              //重装填

DMA_Cmd(DMA2_Channel3, ENABLE);          //处理完,重开DMA

}


关键字:STM32F103  UART4  DMA接收 引用地址:STM32F103 UART4 DMA接收

上一篇:STM32 Uart 实现printf函数
下一篇:STM32CubeMX 4 解锁UART模块

推荐阅读最新更新时间:2024-11-07 21:51

STM32F103+RT-Thread从零开始(二)——RTT系统中点亮LED
上次的的推文简单说了下如何使用Keil创建STM32F103的工程,并且完成了LED点亮,及让LED等闪烁的功能,那是诸多同学学习单片机的起手式。本篇推文是继续上一篇推文的内容,依旧是点亮LED,不同的是,这次点亮LED等,是在RT-Thread操作系统中进行的。 创建工程 创建一个Keil工程,芯片依旧选择STM32F103C8T6,然后在Manage Run-Time Environment对话框中选择需要用的的软件组件,与上文不同的是,我们需要把RTT一起勾上。如下图: 上图中,红线框中即为RTT操作系统的组件,分别为设备驱动,系统内核以及shell。蓝线框中为Keil的RTX操作系统。我们现在要用的是RT
[单片机]
STM32F103VCT6 高级定时器的PWM输出
要求得到下列 波形 ,死区时间1us,CH1和CH1之间的相位差事3us,频率50HZ。 1,To get TIM1 counter clock at 72MHz,the prescaler is computer as follows: Prescaler = (TIM1CLK / TIM1 counter clock) - 1 To objective is to genterate PWM signal at 50KHz: -TIM1_Priod = (SystemCoreClock / 50000) - 1 To get TIM1 output clock at 50KHz , the pe
[单片机]
<font color='red'>STM32F103</font>VCT6 高级定时器的PWM输出
STM32F103标准库开发----CAN总线通信实验----初始化/波特率
一、CAN总线通信初始化配置 1. CAN总线通信初始化配置流程 CAN总线GPIO和时钟配置 CAN总线接收中断优先级配置 CAN总线初始化配置 2. CAN总线GPIO和时钟配置 CAN引脚配置 CAN时钟配置: PA11和PA12引脚,CAN GPIO初始化,具体代码如下: /*CAN GPIO 和时钟配置 */ void CAN_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /*GPIOA端口时钟使能*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
[单片机]
<font color='red'>STM32F103</font>标准库开发----CAN总线通信实验----初始化/波特率
基于stm32f103ze+mpu9250通过官方DMP库串口输出角度
单片机源程序如下: #include stm32f10x.h #include stdio.h #include UART1.h #include systick.h // mpu9250 include files #include sys.h #include mpu9250.h #include mpuiic.h #include inv_mpu.h #include inv_mpu_dmp_motion_driver.h float Q0,Q1,Q2,Q3; // 欧拉角 u32 status2=0; void printf_init() //printf初始化 { GPIO_I
[单片机]
使用STM32F103做CAN的收发通信
一、can通信 CAN 是Controller Area Network 的缩写(以下称为CAN),是ISO国际标准化的串行通信协议。 CAN协议是通过以下5种类型的帧进行的: l 数据帧 l 摇控帧 l 错误帧 l 过载帧 l 帧间隔 另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有11 个位的标识符(ID),扩展格式有29 个位的ID。 大部分系统使用的都是数据帧 ,我这里使用的也是数据帧。 数据帧一般由7个段构成,即: (1) 帧起始。表示数据帧开始的段。 (2) 仲裁段。表示该帧优先级的段。 (3) 控制段。表示数据的字节数及保留位的段。 (4) 数据段。数据的内容,一帧可发送0~8个字节的数据。 (5)
[单片机]
STM32F103RCT6控制LED
不管什么单片机,想要控制LED灯,只能是通过控制单片机芯片的I/O引脚电平的高低来实现。 同样在ST单片机也一样,在ST单片机上,I/O引脚可以被软件设置成各种不同的功能,如输入或输出,所以被称为 GPIO (General-purpose I/O)。 而GPIO引脚又被分为GPIOA、GPIOB„„GPIOG不同的组,每组端口分为 0~15,共16个不同的引脚不等, 对于不同型号的芯片,端口的组和引脚的数量不尽相同,具体请参考相应ST单片机芯片型号的datasheet。 根据ST单片机的GPIO特点,控制LED灯的步骤如下: 1.在众多 GPIO端口引脚中选定需要控制的特定引脚 2.根据外设配置GPIO需要的特定功能 3.
[单片机]
关于FreeRTOS移植到STM32F103上的步骤以及注意事项
因为最近比较有时间,而且发现自己对于STM上可以跑的操作系统相对陌生。所以选择几个操作系统进行移植和玩几个DEMO理解一下。虽然理解的不是很深入,但是如果项目需要的话,只是移植,进行多任务的操作。应付一下还是绰绰有余的。之前移植了uCosII.后续有需要会总结一下。这里先对FreeRTOS相关的问题进行总结。因为个人能力有限。有什么不对的地方请大家批评,写这个主要是为了记录一下自己的移植过程。 1、第一步肯定是先到官网去下载关于FreeRTOS的源码 下面的网址是官方最新源码的下载地址: https://sourceforge.net/projects/freertos/files/latest/download?source=
[单片机]
关于FreeRTOS移植到<font color='red'>STM32F103</font>上的步骤以及注意事项
STM32F103C8T6使用SPI接口驱动WS2812b灯条
之前一篇 文章 写了使用IO控制WS2812b操作原理,但是由于IO的输出比较慢,所以现在改用了硬件SPI控制WS2812b灯条 把SPI的mosi线接到ws2812b的数据线,SPI的速率可达十几Mbit/s,如此高的传输速率,我们可以使用一个(uint8_t)类型的数据代表一个码1或者码0; 也就是说,本来控制一个灯珠的数据由3个Byte(24位)变成了24Byte,每个bit转换成一个Byte; 具体看时钟如何配置的。 SPI配置: 在上一篇文章可以看到控制一个码的周期在1.25us±300ns之间,现在把时钟配成9Mbit/s,这个的话每个码的周期大概就在889ns,和LED的周期略有误差; 从规格书上可以看到码1和码0
[单片机]
<font color='red'>STM32F103</font>C8T6使用SPI接口驱动WS2812b灯条
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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