STM32F407 USART +DMA共思路DMA通道,进行数据转发
STM32CubeMx——串口使用DMA收发数据

STM32CubeMx——串⼝使⽤DMA收发数据⽤到的是DMA发送数据,DMA接收,在中断回调⾥发送出去。
⼀.代码⽣成1.按以前的⽅法设置好时钟和调试⽅式,这⾥就不多说了。
2.设置串⼝1。
3.在DMA Setting⾥点击Add添加USART1_TX,Mode有两种模式,⼀种是普通模式,使⽤⼀次发送语句就发⼀次,另⼀种是循环模式,使⽤⼀次发送会⼀直发送。
这⾥发送我选择普通模式,接收选择循环模式。
4.在中断设置⾥打开串⼝1的中断。
5.时钟和⽂件路径等设置好,然后点⽣成代码。
⼆.代码编写1.先定义发送和接收的数组。
/* USER CODE BEGIN 0 */uint8_t aRxBuffer[1];uint8_t aTxBuffer[]="ok";/* USER CODE END 0 */2.打开串⼝DMA的发送使能,while循环可以放⼀些LED的闪烁。
/* USER CODE BEGIN 2 */HAL_UART_Receive_DMA(&huart1,aRxBuffer,1);HAL_UART_Transmit_DMA(&huart1,aTxBuffer,sizeof(aTxBuffer));/* USER CODE END 2 */3.最后加上⼀个串⼝接收函数的回调函数,把接收到的数据再发出去。
/* USER CODE BEGIN 4 */void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle){HAL_UART_Transmit(&huart1,aRxBuffer,1,0);}/* USER CODE END 4 */现象:上电之后,电脑的串⼝会收到“OK”,然后从电脑发送给芯⽚任意字符,芯⽚再发回来。
总结:使⽤DMA做发送处理,接收数据后⽤串⼝发出去。
为什么接收到数据后不⽤HAL_UART_Transmit_DMA发送出去呢?使⽤这个发现丢包情况,因为这⾥只是测试DMA接收数据情况,接收到之后⼀般是作运算处理的,所以⽤⼀般串⼝发送验证接收的数据正确。
stm32f407数据手册中文

stm32f407数据手册中文STM32F4是由ST(意法半导体)开发的一种高性能微控制器。
其采用了90纳米的NVM工艺和ART(自适应实时存储器加速器,Adaptive Real-Time MemoryAccelerator T,,)o简介:ST(意法半导体)推出了以基于ARM® Cortex™-M4为内核的STM32F4系列高性能微控制器,其采用了90纳米的NVM工艺和ART(自适应实时存储器加速器,Adaptive Real-Time MemoryAccelerator™)oART技术使得程序零等待执行,提升了程序执行的效率,将Cortext-M4的性能发挥到了极致,使得STM32 F4 系列可达到210DMIPS@168MHz o自适应实时加速器能够完全释放Cortex-M4内核的性能;当CPU 工作于所有允许的频率仁168MHz)时,在闪存中运行的程序,可以达到相当于零等待周期的性能。
STM32F4系列微控制器集成了单周期DSP指令和FPU(floating point unit,浮点单元),提升了计算能力,可以进行一些复杂的计算和控制。
STM32 F4系列引脚和软件兼容于当前的STM32 F2系列产品。
优点兼容于STM32F2系列产品,便于ST的用户扩展或升级产品,而保持硬件的兼容能力。
集成了新的DSP和FPU指令,168MHz的高速性能使得数字信号控制器应用和快速的产品开发达到了新的水平。
提升控制算法的执行速度和代码效率。
先进技术和工艺・存储器加速器:自适应实时加速器(ART Accelerator™ )・多重AHB总线矩阵和多通道DMA:支持程序执行和数据传输并行处理,数据传输速率非常快・90nm工艺咼性能・210DMIPS@168MHz・由于采用了ST的ART加速器,程序从FLASH运行相当于0等待更多的存储器・多达1MB FLASH (将来ST计划推出2MB FLASH的STM32F4) ・192Kb SRAM:128KB在总线矩阵上,64KB在专为CPU使用的数据总线上高级外设与STM32F2兼容・USB OTG 高速480Mbit/s・IEEE1588 ,以太网MAC 10/100・PWM高速定时器:168MHz最大频率・加密/哈希硬件处理器:32位随机数发生器(RNG)・带有日历功能的32位RTC:<1 pA的实时时钟,1秒精度更多的提升・低电压:1.8V到3.6V VDD ,在某些封装上,可降低至1.7V ・全双工I2S・ 12 位ADC:0.41us 转换/2.4Msps(7.2Msps 在交替模式)・高速USART ,可达10.5Mbits/s・高速SPI,可达37.5Mbits/s・Camera接口,可达54M字节/s。
stm32DMA采集一个AD数据并通过DMA向串口发送

stm32DMA采集一个AD数据并通过DMA向串口发送#include#include\#include\#include\#include\#include\e某ternuint32_tSendBuff;floatADC_Received;uint32_tADC_Received1;uin t8_tADC_Received2[11];//printf函数重新定向,方便在程序中使用intfputc(intch,FILE 某f){USART_SendData(USART1,(unignedchar)ch);while(!(USART1->SR&USART_FLAG_T某E));return(ch);}voiduart_putchar(uint8_tch){USART_SendData(USART1,ch);while(USART_GetFlagStatu(USART1,USART_FLAG_T某E)==RESET);} intmain(){ADC1_Config();DMA_Config();USART1_Config();while(1 ){//ADC_Received=(float)ADC_GetConverionValue(ADC1)某3.3/4069;//ADC_Received1=ADC_Received某1000000000;ADC_Received=(float)SendBuff某3.3/4069;ADC_Received1=ADC_Received某1000000000;ADC_Received2[0]=(ADC_Received1/1000000000+0某30);//uart_putchar(0某2e);ADC_Received2[1]=(ADC_Received100000000/100000000+0某30);ADC_Received2[2]=(ADC_Received1000000000000000/10000000+0某30);ADC_Received2[3]=(ADC_Received1000000000000000000000/1000000 +0某30);ADC_Received2[4]=(ADC_Received100000000000000000000000000/10 0000+0某30);ADC_Received2[5]=(ADC_Received100000000000000000000000000000 0/10000+0某30);ADC_Received2[6]=(ADC_Received100000000000000000000000000000 0000/1000+0某30);ADC_Received2[7]=(ADC_Received100000000000000000000000000000 000000/100+0某30);ADC_Received2[8]=(ADC_Received100000000000000000000000000000 0000000/10+0某30);ADC_Received2[9]=(ADC_Received1+0某30);ADC_Received2[10]=0某0d;USART_DMACmd(USART1,USART_DMAReq_T 某,ENABLE);//delay_m(1000);//USART_DMACmd(USART1,USART_DMAReq_T某,DISABLE);//delay_m(1000);//ADC_Received=(float)SendBuff/4069某3.3;//ADC_Received=(u16)ADC1->DR;//ADC_Received=(float)ADC_Received/4069某3.3;//printf(\//while(!ADC_GetFlagStatu(ADC1,ADC_FLAG_EOC));//uart_putchar('\\r');//uart_putchar('\\n');//uart_putchar(0某0d);//uart_putchar(0某0a);//printf(\//printf(\//printf(\}}#include\voidADC1_Config(void){ADC_InitTypeDefADC_InitStructure;RCC_APB2PeriphClockCmd(RCC_ APB2Periph_ADC1,ENABLE);ADC1_Gpio_Config();ADC_DeInit(ADC1);//复位ADC1,将外设ADC1的全部寄存器重设为缺省值//ADC1配置ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC1工作在独立模式ADC_InitStructure.ADC_ScanConvMode=ENABLE;//使能扫描ADC_InitStructure.ADC_ContinuouConvMode=ENABLE;;//ADC转换工作在连续模式ADC_InitStructure.ADC_E某ternalTrigConv=ADC_E某ternalTrigConv_None;//由软件控制转换ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//转换数据右对齐ADC_InitStructure.ADC_NbrOfChannel=1;//转换通道为通道1ADC_Init(ADC1,&ADC_InitStructure);//初始化ADC//ADC1选择信道0,顺续等级1,采样时间239.5个周期ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime _28Cycle5);//打开ADC1ADC_Cmd(ADC1,ENABLE);//重置ADC1校准寄存器ADC_ReetCalibration(ADC1);//等待ADC1校准重置完成while(ADC_GetReetCalibrationStatu(ADC1));//开始ADC1校准ADC_StartCalibration(ADC1);//等待ADC1校准完成while(ADC_GetCalibrationStatu(ADC1));//使能ADC1软件开始转换ADC_SoftwareStartConvCmd(ADC1,ENABLE);//配置ADC时钟=PCLK21/612MHzRCC_ADCCLKConfig(RCC_PCLK2_Div6);//使能ADC1模块DMAADC_DMACmd(ADC1,ENABLE);}taticvoidADC1_Gpio_Config(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RC C_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Mode=GPIO_Mod e_AIN;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_Init(GPIOA,&GP IO_InitStructure);}#include\/某其他函数里USART_DMACmd(USART1,USART_DMAReq_T某,ENABLE);uint32_tSendBuff;e某ternfloatADC_Received;e某ternuint8_tADC_Received2[11];//描述:DMA串口的初始化配置voidDMA_Config(void){//初始化结构体DMA_InitTypeDefDMA_InitStructure;//开启DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//配置DMA中断NVIC_Config();//设置DMA源:地址DMA_InitStructure.DMA_PeripheralBaeAddr=(u32)&ADC1->DR;//某内存地址(要传输的变量的指针)DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//指定DMA通道的DMA缓存的大小,单位为数据单位。
stm32usart在DMA模式下只能发送一次

stm32usart在DMA模式下只能发送一次
问题描述:使用STM32 cube生成usart2 DMA direct mode(不使用FIFO,normal模式,STM32f407)配置代码,usart2可以使用阻塞方式发送,使用DMA发送则只能发送第一次,复位后还只能发送一次。
单步调试发现DMA方式下的发送在发送第一次之后,husart->State 标志变为HAL_USART_STATE_BUSY就再也不变了。
比较直接的解决思路就是在DMA发送中断中给这个标志修改为HAL_USART_STATE_READY,修改之后还是不好用(我认为是可以通过修改多个相关寄存器解决的,但是个人倾向于不深入了解其寄存器,而是用封装度更高的HAL系列函数)。
读stm32f4xx_hal_usart.c(V1.5.0)文件的前面关于如何使用HAL 函数的部分并与配置代码比较并没有发现问题,但是看stm32f1xx_hal_usart.c(V1.0.0)在同样的位置多了如下文字:(+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
(used for last byte sending completion detection in DMA non circular mode)
翻看STM32F4系列早于1.5.0的文件都没有这句,可能是官方的疏忽或者是个人理解不到位,总之增加了USART2中断之后(cube生成的),usart DMA发送是完全正常了。
stm32dma工作原理

stm32dma工作原理STM32DMA是一种用于外设数据传输的直接存储器访问控制器。
其主要作用是增强STM32系统的数据传输速度和效率,也大大减轻了CPU的负担。
下面就来详细介绍一下STM32DMA的工作原理。
首先,STM32DMA的数据传输过程分为两个阶段:配置阶段和传输阶段。
1. 配置阶段在配置阶段,开发人员需要设置DMA的操作方式和使用的资源。
这包括源地址、目的地址、数据长度和传输方式等。
还需要设置DMA通道、DMA控制器和中断等。
①设置通道每个DMA通道都能够控制一个或多个外设,该通道负责管理该外设的数据传输。
通过设置通道的方式,就能确定当前DMA通道所控制的外设的类型。
②设置DMA控制器DMA控制器是负责控制所有DMA通道的硬件设备。
DMA控制器通过寄存器控制DMA的状态和传输,例如激活DMA传输、中断或者停止传输等。
③设置中断DMA传输完成后可以通过中断的方式来通知CPU,可以设置传输完成中断或错误中断,便于进行处理。
2. 传输阶段一旦配置完成,DMA就可以应用于数据传输。
传输阶段分为两部分:DMA启动和DMA传输。
①DMA启动在DMA启动时,DMA控制器通过设置寄存器来激活传输。
当启动DMA后,系统就开始了DMA数据传输阶段的操作。
此外,系统可以通过设置多个DMA通道来控制多个数据传输,从而提高数据传输的效率。
②DMA传输传输阶段是真正的数据传输,分为两个步骤。
DMA从存储器复制数据,然后将数据传输到外设。
在这一过程中,数据的流向可以是单向或双向的,因此需要根据具体的应用场景进行配置。
总结:在STM32DMA的工作原理中,配置阶段负责设置DMA的操作方式和使用的资源,如DMA 通道、DMA控制器和中断等,也是实现外设数据传输的关键。
而传输阶段则是数据实际传输的过程,包括DMA启动和DMA传输两步。
通过合理配置DMA传输的参数和DMA通道,可以使数据传输更加快速、高效。
同时由于这种方式不需要CPU参与数据传输,因此大大减轻了CPU的负担,提高了系统的运行效率。
STM32f407 一个串口收传给另一个串口再发送出去串口收发设置

/* Includes ------------------------------------------------------------------*/#include "stm32f4xx_conf.h"#include <stdio.h>void Delay(__IO uint32_t nCount);//***********************************************//函数功能:延时ms//入口参数:延时长度//出口参数:无//备注://************************************************void Delay_ms(u16 ms){u32 j;for(;ms>0;ms--)for(j=0;j<9700;j++);}//***********************************************//函数功能:IO配置//入口参数:无//出口参数:无//备注://************************************************void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/* GPIOD Periph clock enable */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);/* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure PA0 pin as input floating *///GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//GPIO_Init(GPIOA, &GPIO_InitStructure);}//***********************************************//函数功能:UART配置//入口参数:无//出口参数:无//备注://************************************************void USART_Configuration(void){USART_InitTypeDef USART_InitStructure;USART_ART_BaudRate =9600; //波特率USART_ART_WordLength = USART_WordLength_8b; //8 位数据USART_ART_StopBits = USART_StopBits_1; //停止位USART_ART_Parity = USART_Parity_No;// 校验方式:无USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 发送/接收使能/* Enable GPIO clock */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);/* Enable UART clock */RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);/* Connect PXx to USARTx_Tx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);/* Connect PXx to USARTx_Rx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);GPIO_StructInit(&GPIO_InitStructure);/* Configure USART Tx as alternate function */GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure USART Rx as alternate function */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_Init(GPIOC, &GPIO_InitStructure);/* USART configuration */USART_Init(USART3,&USART_InitStructure);USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);USART_ITConfig(USART3,USART_IT_TXE,ENABLE);/* Enable USART */USART_Cmd(USART3, ENABLE);/* Enable UART clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); /* Connect PXx to USARTx_Tx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); /* Connect PXx to USARTx_Rx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6); GPIO_StructInit(&GPIO_InitStructure);/* Configure USART Tx as alternate function */GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure USART Rx as alternate function */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_Init(GPIOC, &GPIO_InitStructure);/* USART configuration */USART_Init(USART6,&USART_InitStructure);USART_ITConfig(USART6,USART_IT_RXNE,ENABLE);//USART_ITConfig(USART6,USART_IT_TXE,ENABLE);/* Enable USART */USART_Cmd(USART6, ENABLE);}void NVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//嵌套优先级分组为1 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //嵌套通道为USART3_IRQn NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; //嵌套通道为USART6_IRQn NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0; //抢占优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能NVIC_Init(&NVIC_InitStructure);}/*** @brief Main program* @param None* @retval None*** @brief Delay Function.* @param nCount:specifies the Delay time length.* @retval None*/void Delay(__IO uint32_t nCount){while(nCount--){}}/**int fputc(int ch, FILE *f){/* Place your implementation of fputc here *//* e.g. write a character to the USART */USART_SendData(USART6, (uint8_t) ch);/* Loop until the end of transmission */while (USART_GetFlagStatus(USART6, USART_FLAG_TC) == RESET){}return ch;}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t* file, uint32_t line){/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* Infinite loop */while (1){}}#endif/*** @}*//*** @}*//*中断*/uint8_t Uart3_Buffer[255];uint8_t temp;uint8_t Flag=0;int RxCounter=0;int i=0;void USART3_IRQHandler(void){if(USART_GetITStatus(USART3,USART_IT_RXNE)!= RESET) //中断产生{USART_ClearITPendingBit(USART3,USART_IT_RXNE); //清除中断标志if(RxCounter==0){temp=USART_ReceiveData(USART3);if(temp==FRAMEHEAD)/*FRAMEHEAD*/Uart3_Buffer[RxCounter++]=temp;}else{Uart3_Buffer[RxCounter++]=USART_ReceiveData(USART3);if(RxCounter==FRAMELEN)/*FRAMELEN*/{Flag=1;RxCounter=0;}if(USART_GetFlagStatus(USART3,USART_FLAG_ORE) == SET){USART_ClearFlag(USART3,USART_FLAG_ORE);USART_ReceiveData(USART3);}}}if(USART_GetITStatus(USART3,USART_IT_TXE)!= RESET){USART_ClearITPendingBit(USART3,USART_IT_TXE);if(Flag){for(i=0;i<FRAMELEN;i++){USART_SendData(USART3,Uart3_Buffer[i]); //发送数据while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); {} }Flag=0;}}}uint8_t Flag6=0;int RxCounter6=0;uint8_t temp6;uint8_t Uart6_Buffer[255];void USART6_IRQHandler(void){if(USART_GetITStatus(USART6,USART_IT_RXNE)!= RESET){USART_ClearITPendingBit(USART6,USART_IT_RXNE);if(RxCounter6==0){temp6=USART_ReceiveData(USART6);if(temp6==FRAMEHEAD)/*FRAMEHEAD*/Uart6_Buffer[RxCounter6++]=temp6;}else{Uart6_Buffer[RxCounter6++]=USART_ReceiveData(USART6);if(RxCounter6==FRAMELEN)/*FRAMELEN*/{Flag6=1;RxCounter6=0;}if(USART_GetFlagStatus(USART6,USART_FLAG_ORE) == SET){USART_ClearFlag(USART6,USART_FLAG_ORE);USART_ReceiveData(USART6);}}}}{int i=0;int j=0;GPIO_Configuration();USART_Configuration();NVIC_Config();while (1){}}。
完整word版,STM32f407 一个串口收传给另一个串口再发送出去串口收发设置

/* Includes ------------------------------------------------------------------*/#include "stm32f4xx_conf.h"#include <stdio.h>void Delay(__IO uint32_t nCount);//***********************************************//函数功能:延时ms//入口参数:延时长度//出口参数:无//备注://************************************************void Delay_ms(u16 ms){u32 j;for(;ms>0;ms--)for(j=0;j<9700;j++);}//***********************************************//函数功能:IO配置//入口参数:无//出口参数:无//备注://************************************************void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/* GPIOD Periph clock enable */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);/* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure PA0 pin as input floating *///GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//GPIO_Init(GPIOA, &GPIO_InitStructure);}//***********************************************//函数功能:UART配置//入口参数:无//出口参数:无//备注://************************************************void USART_Configuration(void){USART_InitTypeDef USART_InitStructure;USART_ART_BaudRate =9600; //波特率USART_ART_WordLength = USART_WordLength_8b; //8 位数据USART_ART_StopBits = USART_StopBits_1; //停止位USART_ART_Parity = USART_Parity_No;// 校验方式:无USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 发送/接收使能/* Enable GPIO clock */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);/* Enable UART clock */RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);/* Connect PXx to USARTx_Tx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);/* Connect PXx to USARTx_Rx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);GPIO_StructInit(&GPIO_InitStructure);/* Configure USART Tx as alternate function */GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure USART Rx as alternate function */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_Init(GPIOC, &GPIO_InitStructure);/* USART configuration */USART_Init(USART3,&USART_InitStructure);USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);USART_ITConfig(USART3,USART_IT_TXE,ENABLE);/* Enable USART */USART_Cmd(USART3, ENABLE);/* Enable UART clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); /* Connect PXx to USARTx_Tx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); /* Connect PXx to USARTx_Rx*/GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6); GPIO_StructInit(&GPIO_InitStructure);/* Configure USART Tx as alternate function */GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure USART Rx as alternate function */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_Init(GPIOC, &GPIO_InitStructure);/* USART configuration */USART_Init(USART6,&USART_InitStructure);USART_ITConfig(USART6,USART_IT_RXNE,ENABLE);//USART_ITConfig(USART6,USART_IT_TXE,ENABLE);/* Enable USART */USART_Cmd(USART6, ENABLE);}void NVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//嵌套优先级分组为1 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //嵌套通道为USART3_IRQn NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; //嵌套通道为USART6_IRQn NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0; //抢占优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能NVIC_Init(&NVIC_InitStructure);}/*** @brief Main program* @param None* @retval None*** @brief Delay Function.* @param nCount:specifies the Delay time length.* @retval None*/void Delay(__IO uint32_t nCount){while(nCount--){}}/**int fputc(int ch, FILE *f){/* Place your implementation of fputc here *//* e.g. write a character to the USART */USART_SendData(USART6, (uint8_t) ch);/* Loop until the end of transmission */while (USART_GetFlagStatus(USART6, USART_FLAG_TC) == RESET){}return ch;}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t* file, uint32_t line){/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* Infinite loop */while (1){}}#endif/*** @}*//*** @}*//*中断*/uint8_t Uart3_Buffer[255];uint8_t temp;uint8_t Flag=0;int RxCounter=0;int i=0;void USART3_IRQHandler(void){if(USART_GetITStatus(USART3,USART_IT_RXNE)!= RESET) //中断产生{USART_ClearITPendingBit(USART3,USART_IT_RXNE); //清除中断标志if(RxCounter==0){temp=USART_ReceiveData(USART3);if(temp==FRAMEHEAD)/*FRAMEHEAD*/Uart3_Buffer[RxCounter++]=temp;}else{Uart3_Buffer[RxCounter++]=USART_ReceiveData(USART3);if(RxCounter==FRAMELEN)/*FRAMELEN*/{Flag=1;RxCounter=0;}if(USART_GetFlagStatus(USART3,USART_FLAG_ORE) == SET){USART_ClearFlag(USART3,USART_FLAG_ORE);USART_ReceiveData(USART3);}}}if(USART_GetITStatus(USART3,USART_IT_TXE)!= RESET){USART_ClearITPendingBit(USART3,USART_IT_TXE);if(Flag){for(i=0;i<FRAMELEN;i++){USART_SendData(USART3,Uart3_Buffer[i]); //发送数据while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); {} }Flag=0;}}}uint8_t Flag6=0;int RxCounter6=0;uint8_t temp6;uint8_t Uart6_Buffer[255];void USART6_IRQHandler(void){if(USART_GetITStatus(USART6,USART_IT_RXNE)!= RESET){USART_ClearITPendingBit(USART6,USART_IT_RXNE);if(RxCounter6==0){temp6=USART_ReceiveData(USART6);if(temp6==FRAMEHEAD)/*FRAMEHEAD*/Uart6_Buffer[RxCounter6++]=temp6;}else{Uart6_Buffer[RxCounter6++]=USART_ReceiveData(USART6);if(RxCounter6==FRAMELEN)/*FRAMELEN*/{Flag6=1;RxCounter6=0;}if(USART_GetFlagStatus(USART6,USART_FLAG_ORE) == SET){USART_ClearFlag(USART6,USART_FLAG_ORE);USART_ReceiveData(USART6);}}}}{int i=0;int j=0;GPIO_Configuration();USART_Configuration();NVIC_Config();while (1){}}。
STM32实现USART DMA接收未知长度的数据和发送

前言:开始学USART DMA的时候看到帖子《STM32 UART DMA实现未知数据长度接收》,觉得方法妙极了。
此下出自此帖子——(整体的思路是这样的,一开始设置好DMA接收,可以把缓冲区长度设置为帧最大长度,我们可以把RX连接到定时器的管脚输入端,并且一开始设置输入并且使能引脚下降沿中断,当帧的第一个字节发送时,因为起始位为低电平,空闲时UART为高电平,满足条件,进入中断,禁止中断,并且在中断中开启定时器,该定时器工作在复位模式,上升沿复位,并且设置好定时器输出比较值为超时时间,比如20ms,这样,在传输后面字节时,肯定会有高低电平出现,即便是传输的是0x00,0xFF,虽然UART 数据区不变,但是都为1,或都为0,但是因为起始位为低电平,停止位是高电平,所以肯定会有上升沿,定时器会一直复位,输出定时器的计数器一直到达不了输出比较值,当一帧传输结束后,定时在最后一个字节复位后,由于没有数据继续到达,无法复位,则计数器就能计到输出比较值,这时发出中断,在定时器中断中可以计算出接收数据的长度,并且通知外部数据已经接收完毕。
)今天我在工作中调通了另一种USART DMA接收未知数据长度的接收,使用的是USRAT空闲总线中断接收,这种方法也在网站上比较多见,以前没试过,今天才知道如此的爽,另外我使用DMA发送USART数据替代了以前的查询法发送,发现更加爽了。
其速度快了很多,尤其是在大量数据传输与发送的时候其优势更加明显。
我举个例子:1、后台数据->USART1-> USART2->其它设备,其它设备数据->USART2-> USART1->后台,这两个数据过程也可能同时进行。
2、由于硬件的限制,USART1和USART2的传输波特率不一样,比如USART1使用GPRS通信,USART2使用短距离无线通信;或者USART1使用以太网通信,USART2使用485总线通信。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream2, &DMA_InitStruct);
DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR));
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)uart_rx_tx_buf;
DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR));
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)uart_rx_tx_buf;
/**********************DMA interrupt************************/
DMA_ITConfig(DMA2_Stream7,DMA_IT_TC,ENABLE);
DMA_ITConfig(DMA2_Stream2,DMA_IT_TC,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream7_IRQn;
/**
******************************************************************************
* @file IO_Toggle/main.c
* @author MCD Application Team
* @version V1.0.0
USART_ART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_ART_Mode=USART_Mode_Rx |USART_Mode_Tx;
USART_ART_Parity=USART_Parity_No;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
/**
* @brief Main program
* @param None
* @retval None
*/
void uart_1_dma_init(void);
void uart_2_dma_init(void);
void Set485Mode(unsigned char flag);
void Set_1_rate(unsigned char rate_num);
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.DMA_BufferSize = 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream7, &DMA_InitStruct);
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
/* DMA2 Stream0 channel0 configuration **************************************/
* @date 19-September-2011
* @brief Main program body
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
__IO unsigned char uartБайду номын сангаасrx_tx_buf[2];
USART_InitTypeDef USART_InitStruct;
DMA_InitTypeDef DMA_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDefNVIC_InitStructure;
#define RX_MODE 1
unsigned long boundrate[7]={600,2400,4800,9600,19200,38400,57600};
/* Private variables ---------------------------------------------------------*/
{
/* Enable uart1, DMA2 and GPIO clocks ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOB, ENABLE); //B6-TX, B7-RX;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_USART1);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6 |GPIO_Pin_7;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
void Set_2_rate(unsigned char rate_num);
void _485PinConfig(void);
int main(void)
{
uart_1_dma_init();