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接收

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic468712.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

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

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

基于STM32F103ZET6主控平台实现定时器TIM3的驱动

_Clock_Init(9);   //系统时钟设置 delay_init(72);     //延时初始化 uart_init(72,115200); //串口初始化为115200 LED_Init(); BEEP_Init(); TIM3_Init(4999,7199); while(1) { if(Wl_stat==0)//代表进入WHILE循环 { printf("Input While(1)-->rn"); Wl_stat=1; } LED1=!LED1; delay_ms(200); }} 第四步:编译通过后,烧录进STM32F103ZET6开发板,实现
发表于 2019-08-22

STM32f103ZET6定时器TIM3使用通道1输出PWM程序

总结:TIM3_CH1输出口为PA6(重映射为PB4),PB5位DS0接口。1.使用重映射之后,原始IO口不再有输出;本例子中,若使用部分重映射,则 PA6映射到PB4中,所以仅仅PB4有波形输出;飞线连接PB4与PB5即可观察PWM呼吸灯效果。2.使用IO口前务必初始化,本例子中开始仅仅初始化了PB5口,而没有初始化PA6导致一直验证失败;正点原子给出程序中是由通道2直接映射到PB5因此只需要初始化PB5口即可,不存在上述问题。3.除了正常输出输入信号之外,输出PWM以及其他功能均属于IO口的复用功能。#include "stm32f10x.h"#include "led.h"
发表于 2019-08-22

stm32f0设置tim2单脉冲模式-tim1内部触发

/***************************************************************************************************************以下TIM1和TIM2的设置实现TIM1输出40hz,占空比7%即高电平输出180us,TIM2输出单脉冲,周期360us,占空比50%,TIM2的触发是TIM1的OC1REF信号。TIM2设置单脉冲需设置的参数:  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;    TIM_SelectOnePulseMode(TIM2,TIM_OPMode_Single);//单脉冲  TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);//定时器1内部触发 
发表于 2019-08-22
stm32f0设置tim2单脉冲模式-tim1内部触发

STM32F103 使用TIM3产生四路PWM

为PC6、PC7、PC8、PC9*******************************************************************************/#include"stm32f10x.h"void RCC_Cfg(void);void GPIO_Cfg(void);void TIM_Cfg(void);void NVIC_Cfg(void);void delay_ms(u32 i);void PWM_Cfg(float dutyfactor1,float dutyfactor2,float dutyfactor3,float dutyfactor4); int
发表于 2019-08-22
STM32F103 使用TIM3产生四路PWM

STM32F10 OLED液晶显示(IIC)

2019年7月27日做小车的第六天。今天我实现了一个新的功能 OLED显示汉字。刚开始学习这个显示汉字的时候也是一头污水,代码啊大部分看不懂,看OLED讲解的那个视频反复看了好几遍。还是没什么思路。但是那自己慢慢的开始修改自带的源代码,尝试的去做,从显示点、线、字符、字符串一步步的开始进行,随着这个一步步的学会,显示汉字那,哈哈,原理也是差不多。大致思路也就是调用.c中的函数,设置里面的变量,去调出自己想要的字符,汉字的代码(这些代码都是在一个数组里)先说说重要的,怎么显示出汉字:比如我们想让OLED显示屏显示一个字符串:“CODE”,主函数是这么两条语句:OLED_ShowString(63,48,“CODE:”,16
发表于 2019-08-22
STM32F10 OLED液晶显示(IIC)

STM32F103_SD卡FatFs文件系统移植

;       status = RES_OK;            break;至此diskio.c移植完成三、ffconfig.h需要修改的参数如下:  //准许使用文件字符串函数: f_gets(), f_putc(), f_puts() and/  f_printf()#define    _USE_STRFUNC    1    //支持格式化函数f_mkfs()#define    _USE_MKFS   
发表于 2019-08-22
STM32F103_SD卡FatFs文件系统移植

小广播

何立民专栏

单片机及嵌入式宝典

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

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