-
串口工作在DMA模式下有时接收异常
2016-11-25 16:56:051 前言客户反馈在使用STM32F205的串口工作在DMA模式时,有时能够接收数据,有时完全没有数据,但如果换成中断模式来接收又能100%正常收到数据。2 复现现象2.1 问题背景与客户沟通,客户使用的是STM32F2标准库V1.1.0...1 前言
客户反馈在使用STM32F205的串口工作在DMA模式时,有时能够接收数据,有时完全没有数据,但如果换成中断模式来接收又能100%正常收到数据。
2 复现现象
2.1 问题背景
与客户沟通,客户使用的是STM32F2标准库V1.1.0,串口波特率为1.408Mbps,不经过串口RS232,直接连接主CPU和从MCU(STM32F205)的串口发送和接收引脚,如下图所示:
图1 2.2 尝试重现问题
由于客户使用的是主从架构,实验采用两块STM3220G-EVAL评估板来重现现象。一块用来不间断发送串口数据,另一块采用串口DMA进行接收,直接通过杜邦线连接串口PIN脚并共地,不使用评估板上的RS232收发器。接收端使用STM32F2xx_StdPeriph_Examples\ USART\USART_TwoBoards的示例代码。代码片段如下:
int main(void) { ... USART_Config(); ... while (1) { /* Clear Buffers */ Fill_Buffer(RxBuffer, TXBUFFERSIZE); Fill_Buffer(CmdBuffer, 2); DMA_DeInit(USARTx_RX_DMA_STREAM); DMA_InitStructure.DMA_Channel = USARTx_RX_DMA_CHANNEL; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /************* USART will receive the the transaction data ****************/ /* Transaction data (length defined by CmdBuffer[1] variable) */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RxBuffer; DMA_InitStructure.DMA_BufferSize =10;// (uint16_t)CmdBuffer[1]; DMA_InitStructure.DMA_Mode =DMA_Mode_Normal;//DMA_Mode_Circular; DMA_Init(USARTx_RX_DMA_STREAM, &DMA_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable DMA Stream Transfer Complete interrupt */ DMA_ITConfig(USARTx_RX_DMA_STREAM, DMA_IT_TE|DMA_IT_DME|DMA_IT_FE, ENABLE); /* Enable the DMA Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, ENABLE); /* Enable the USART Rx DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Rx , ENABLE); // USART_Cmd(USARTx, ENABLE); // while(SET ==USART_GetFlagStatus(USARTx,USART_FLAG_ORE)) // { // Tmp =USART_ReceiveData(USARTx); // } while ((DMA_GetFlagStatus(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_TCIF) == RESET) { } /* Clear all DMA Streams flags */ DMA_ClearFlag(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_HTIF | USARTx_RX_DMA_FLAG_TCIF); /* Disable the DMA Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, DISABLE); /* Disable the USART Rx DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Rx, DISABLE); //handle the RxBuffer data... //... } }
USART_Config()函数如下:
static void USART_Config(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Peripheral Clock Enable -------------------------------------------------*/ /* Enable GPIO clock */ RCC_AHB1PeriphClockCmd(USARTx_TX_GPIO_CLK | USARTx_RX_GPIO_CLK, ENABLE); /* Enable USART clock */ USARTx_CLK_INIT(USARTx_CLK, ENABLE); /* Enable the DMA clock */ RCC_AHB1PeriphClockCmd(USARTx_DMAx_CLK, ENABLE); /* USARTx GPIO configuration -----------------------------------------------*/ /* Connect USART pins to AF7 */ GPIO_PinAFConfig(USARTx_TX_GPIO_PORT, USARTx_TX_SOURCE, USARTx_TX_AF); GPIO_PinAFConfig(USARTx_RX_GPIO_PORT, USARTx_RX_SOURCE, USARTx_RX_AF); /* Configure USART Tx and Rx as alternate function push-pull */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN; GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN; GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure); /* USARTx configuration ----------------------------------------------------*/ /* Enable the USART OverSampling by 8 */ USART_OverSampling8Cmd(USARTx, ENABLE); USART_InitStructure.USART_BaudRate = 1408000;//3750000; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; /* When using Parity the word length must be configured to 9 bits */ 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(USARTx, &USART_InitStructure); /* Configure DMA controller to manage USART TX and RX DMA request ----------*/ DMA_InitStructure.DMA_PeripheralBaseAddr = USARTx_DR_ADDRESS; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /* Here only the unchanged parameters of the DMA initialization structure are configured. During the program operation, the DMA will be configured with different parameters according to the operation phase */ /* Enable USART */ USART_Cmd(USARTx, ENABLE); }
按如上代码,有如下现象:
1. 代码不做修改,若先启动接收端MCU再启动发送端MCU,接收端MCU的串口能正常接收。
2. 代码不做修改,若先启动发送端MCU再启动接收端MCU,接收端MCU的串口100%接收异常。
3. 修改发送端代码,改为发送端MCU串口每1秒间隔发送一次,则无论启动顺序如何,接收端MCU的串口都能正常。3 程序分析
由上述代码可知,程序是先在USART_Config()函数函数内初始化串口并使能,然后再在接下来的main函数的while循环内初始化DMA并使能。这个是标准库内附带的示例代码,咋一看没什么问题,但仔细一想,针对用户的使用场景,这里就会产生一个问题:由于用户的主CPU有可能在从MCU启动之前就已经有可能启动,那么在这种情况下,在初始化完串口并使能后,到DMA使能之前这段时间内,若主CPU向从MCU发送串口数据,从MCU是否能正确接收?
从上述测试代码的结果2可以得出,若在串口初始化并使能后到DMA使能之前有数据来,MCU是不能接收的,经进一步调试,发现此时数据寄存器USART_DR存在一个数据,且在状态寄存器USART_SR中ORE值1,由此可知,串口的接收寄存器中已经接收到一个数据,但是后面的数据又来了,由于数据寄存器中的数据没有及时转移走(此时DMA还没有开启),从而导致后面的数据无法存入,所以产生了上溢错误(ORE),而一旦产生上溢错误后,就无法再触发DAM请求,及时之后再启动DMA也不行,无法触发DMA请求就无法将数据寄存器内的数据及时转移走,如此陷入死锁,这就是串口无法正常接收的原因。这时反观一下代码的结果3,这又将做如何解释?
仔细查看测试结果3,发现这个发送端每1秒间隔发送一次,那么就会存在这个一个概率,这个发送的时间点是否刚好在接收端MCU的串口初始化并使能和DMA使能之间还是之后,这个时间窗口非常关键,如果刚好在时间窗,那么串口接收就不正常,如果在这个时间窗之后,串口接收就能正常。由于测试代码采用的是1秒间隔,对于MCU来说这个是非常大的时间长度,还是很小概率能碰中这个时间窗的,因此,测试结果看起来是都能正常,实际严格来说,还是存在刚好碰中的可能。如果间隔时间缩短,那个碰中的几率就增大。由此看来,这也就能解释测试结果3了,也能解释客户提到的有时正常有时不正常的现象了。
4 问题处理
处理有两种方法,第一种方法是在使能DMA后,及时将数据寄存器DR中的数据清除掉,如下代码所示:
//... /* Enable the DMA Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, ENABLE); /* Enable the USART Rx DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Rx , ENABLE); while(SET ==USART_GetFlagStatus(USARTx,USART_FLAG_ORE)) { Tmp =USART_ReceiveData(USARTx); } //...
这里是使用读DR的方法来清除的,从参考手册中也提到使用这种方法来清除ORE标志:
图2
第一种方法类似于一种纠错措施,下面介绍另一种推荐的方法,如下代码所示://... /* Enable the DMA Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, ENABLE); /* Enable the USART Rx DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Rx , ENABLE); USART_Cmd(USARTx, ENABLE); //...
如上所示,可以先使能DMA再使能串口,这样就彻底不存在那个时间窗了,不管数据何时过来能能被DAM及时转走。这个是推荐的解决方法。
5 结论
标准库中的示例代码一般来说只供参考,对于大部分情况来说都是能正常工作的,但偶尔也会出现不适用的情况,此时更需要我们针对问题进行思考分析,进一步找到原因才能解决问题。对于串口使用DMA来接收的情况,这里建议一定要先使能DMA,最后使能串口,这样就能避免类似问题出现了。
本文转自:http://www.stmcu.org/module/forum/thread-606799-1-1.html
-
让DMA66 硬盘工作在DMA33 模式 (转)
2007-12-04 10:37:47让DMA66 硬盘工作在DMA33 模式 (转)[@more@] 我的计算机的主板为旗舰638B型主板,采用威盛公司的VT82C693和VT82C596A 芯片组。当BIOS中对硬盘类型有关的设置都选择Auto后,会在启动...让DMA66 硬盘工作在DMA33 模式 (转)[@more@]我的计算机的主板为旗舰638B型主板,采用威盛公司的VT82C693和VT82C596A 芯片组。当BIOS中对硬盘类型有关的设置都选择Auto后,会在启动画面中显示硬盘和光驱真正支持的最高传输模式,甚至可以显示本身并不支持的UDMA 4模式。XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
对于支持DMA33 传输模式的硬盘,都可以在进入windows 98后设置成DMA 模式。具体步骤为:右击“我的电脑”,选择“属性”,选择“设备管理”,分别展开“CDROM ”和“磁盘驱动器”前面的+号,分别双击代表光驱和硬盘的子项目,然后选择“设置”,选中 DMA选项。选中时会出现关于硬件不支持的警告,属正常提示,尽可以放心地重新启动。另外,若硬盘支持的是DMA66 ,则无法选中DMA 选项;即便强行选中也不会有效,反而使计算机每次启动时都出现很长时间的自动纠正等待。
假如想要在仅支持DMA33 的主板上使用 DMA66硬盘DMA 传输特性,人们普遍认为必须配一块PCI 硬盘加速卡,或者用各硬盘厂商专门提供的DMA 转换程序,把硬盘的DMA66 转换为DMA33。然而经过本人反复试验,终于发现还有一个非常简单的方法。
把主板中关于DMA66 硬盘的UDMA选项从默认的AUTO改成DISABLE ,屏蔽掉主板对该硬盘的UDMA支持,进入windows 98后,便可以用上面介绍的方法,利用Windows 98自带的UDMA驱动程序,让硬盘工作在DMA33 模式下。经过此方法处理后,本人的第二硬盘IBM15.2G硬盘很正常地工作在DMA33 模式下,经过Winbench99测试比较,硬盘传输率从原来的4.8M/s一下提高到11.2M/s,cpu占用率从96% 骤降至5.3%,几乎和我的第一硬盘,DMA33 火球六代6.4G的传输率12.8M/s、CPU占用率6.3%一致。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-988166/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10752043/viewspace-988166/
-
stm32f407实现定时器3(Timer3)触发ADC双通道同时采样(ADC_DualMode_RegSimult)并在DMA中断读取每次转换...
2019-02-05 20:46:56项目简介:stm32f407实现定时器3(Timer3)触发ADC双通道同时采样并在DMA中断读取每次转换的结果 项目需求: 对两路信号进行ADC同时采样。由于一路信号将作为参考信号解调另一路信号,所以要确保两路信号的每次...项目简介:stm32f407实现定时器3(Timer3)触发ADC双通道同时采样并在DMA中断读取每次转换的结果
项目需求:
对两路信号进行ADC同时采样。由于一路信号将作为参考信号解调另一路信号,所以要确保两路信号的每次采样是同时进行的。所以,需要将ADC设置成“多重ADC模式”中的“规则同时模式”下的“双重ADC模式”(ADC_DualMode_RegSimult)。由于待采样的信号频率范围不确定,但是又要求每次采样之间的时间间隔较为精确,故需要ADC采样率可调但是又不能简单的使用delay()函数,所以要求ADC的每次转换由定时器触发(ADC_ExternalTrigConvEdge_Rising)。
其中,需要注意的点有:
- 多重ADC模式下想要多路ADC同步(同时)转换,只能通过DMA功能来同时获取两路ADC的转换结果到目标地址(自己定义的用于保存转换结果的数组),即便不需要DMA做大量的数据搬运工作。
- 要想定时器触发ADC的转换,Timer必须配置成PWM模式。
- 要想在DMA转换结束后及时调用转换结果,需要开启DMA传输完成的中断,然后再中断中及时对数据进行处理。
下面,本文将一步一步记录,我是如何完成项目需求的程序功能的。
首先,我找来了原子stm32f407探索者开发板提供的定时器例程作为模板,准备往其中添加内容完成最终的功能。
实验8 定时器中断实验
然而,原子的ADC教学中并没有关于ADC双通道同步采样的例程,故在某一篇博友的博文(链接遗失,感谢博友好人)中受到启发,去到st官网下载了官方的双通道adc规则同步采样的例程。下载地址链接为[下载地址][下载页面],如果下载链接失效,那么可以自己前往官网搜索stm32f407,找到名为“STM32F4 DSP and standard peripherals library”的资源下载。例程的目录如下,在本文的最后也会提供该例程的下载。
en.stm32f4_dsp_stdperiph_lib
--STM32F4xx_DSP_StdPeriph_Lib_V1.8.0
----Project
------STM32F4xx_StdPeriph_Examples
--------ADC
----------ADC_DualModeRegulSimu
根据例程中excel画出的图示,我们可以很清楚的看到每次两个通道同时采样完成后,结果通过DMA获取。该例程中还是使用软件触发ADC启动转换,先不管这些,我们先把这个例程和原子的定时器Timer的例程整合到一起。
规则同步ADC采样时序示意图,来自ST官方demo 整合好的文件名为:
myTest-20190203-dualADCok
在文章的最后将会附上下载链接。
大概来看一下这个代码做了什么事:就是在Timer3的中断里,通过调用ADC_SoftwareStartConv(ADC1);函数触发了双通道ADC的规则同步转换,然后从DMA的目标数组中读取结果,通过串口输出。关键代码如下:
就是简单的将两个例程整合,并没有做太多别的事情。
//定义存储转换结果的数组 __IO uint16_t aADCDualConvertedValue[2]; // ADC初始化部分 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; …… ADC_Init(ADC1, &ADC_InitStructure); ADC_Init(ADC2, &ADC_InitStructure); ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); //获取ADC采样的值部分 ADC_SoftwareStartConv(ADC1); adcVal01= aADCDualConvertedValue[0]; adcVal02= aADCDualConvertedValue[1]; sprintf(msgstr,"adc ch5=%d ch6=%d\r\n",adcVal01,adcVal02); printf(msgstr); //DMA初始化部分 DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&aADCDualConvertedValue; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); //DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE); /* DMA2_Stream0 enable */ DMA_Cmd(DMA2_Stream0, ENABLE);
运行结果如下:
目前,ADC的转换还是在定时器的中断中,通过调用函数,这种产生软件触发的方式进行的。
下一步,需要将ADC的转换改为由定时器触发。那么,在改动的过程中会遇到哪些问题呢?关键代码如下:
//ADC初始化部分 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_T3_CC1; //定时器初始化部分 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); /* TIM1 channel1 configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 500; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_CtrlPWMOutputs(TIM3, ENABLE); TIM_Cmd(TIM3,ENABLE); NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure);
改好后的文件名为:
myTest-20190203-dualADCandTimerTrigOk
在文末会提供下载。主要修改的地方是:
- ADC初始化部分对ADC的触发方式做了修改
- 定时器初始化部分,将Timer配置成的PWM的模式
- 配置定时器相关中断
运行结果如下:
这里,取消了定时器3溢出时的中断函数。可见,我们可以在主函数while(1)循环中,不断的读取转换结果保存数组的值,打印出来,然后发现每次读取的结果确实在随着输入信号的变化而改变。因此我们知道了,Timer触发ADC采样配置成功了。但是还并不知道在什么时候完成了一次转换。图示表明,在打印速率大于转换速率的时候,我们将每一次的采样结果打印了多遍。
//TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //注释掉Timer3中断
但是,怎么才能在每次转化好了后,及时的把采样的结果获取到呢?
其实,只需要再加上DMA传输完成后的中断函数,在DMA的中断中及时处理每次DMA传输的采样结果就行了。关键代码如下:
//DMA初始化部分 DMA_Init(DMA2_Stream0, &DMA_InitStructure); DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TC); DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); /* DMA2_Stream0 enable */ DMA_Cmd(DMA2_Stream0, ENABLE); //增加DMA中断处理函数 void DMA2_Stream0_IRQHandler(void) { if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) { DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); printf("DMA interrupt:\r\n"); adcVal01= aADCDualConvertedValue[0]; adcVal02= aADCDualConvertedValue[1]; sprintf(msgstr,"adc ch5=%d ch6=%d\r\n",adcVal01,adcVal02); printf(msgstr); printf("\r\n"); } }
最终实现了完整功能的程序命名如下:
myTest-20190203-dualADCandTimerTrigAndDMAinterrOk
运行结果如下:
最后附上本文所述代码的下载链接地址:
下载地址二:(点此链接之前请先给本文点个“赞”吧)来源于Github
本文代码可直接在原子STM32F407ZGT6的战舰开发板上运行。
感谢各位的阅读,如果您觉得有用或觉得哪里有错误,希望您能够留言表示支持。
-
stm32 usart在DMA模式下只能发送一次
2016-09-12 10:47:43问题描述:使用STM32 cube生成usart2 DMA direct mode(不使用FIFO,normal模式,STM32... 单步调试发现DMA方式下的发送在发送第一次之后,husart->State 标志变为 HAL_USART_STATE_BUSY就再也不变了。比较直接的解决思问题描述:使用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发送是完全正常了。
-
Stm32 ADC在DMA中切换不同的采集源
2019-10-11 22:05:11应用背景: 一个双通道DO输出芯片...把反馈引脚接到单片机的ADC,然后在程序中进行切换。代码如下: void Adc2_init(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStruct... -
让DMA66 硬盘工作在DMA33 模式
2001-01-19 08:23:00我的计算机的主板为旗舰638B型主板,采用威盛公司的VT82C693和VT82C596A 芯片组...对于支持DMA33 传输模式的硬盘,都可以在进入Windows 98后设置成DMA 模式。具体步骤为:右击“我的电脑”,选择“属性”,选择“设备管 -
[导入]让DMA66 硬盘工作在DMA33 模式
2001-01-19 16:23:00文章来源:http://blog.csdn.net/xiaozuo/archive/2001/01/19/5151.aspx 转载于:https://www.cnblogs.com/zhaoxiaoyang2/archive/2001/01/19/816635.html -
DMA
2019-09-23 10:43:26什么是DMA DMA,Direct Memory Access,直接内存访问,是一种不经过CPU而直接从内存存取数据的数据交换...在DMA模式下,CPU只需要向DMA控制器下达指令,传输数据由DMA来完成,数据传送完再把信息反馈给CPU,这... -
dma
2013-05-09 23:12:01DMA的英文拼写是“Direct ...而在DMA模式下,CPU只须向DMA控制器下达指令,让DMA控制器来处理数据的传送,数据传送完毕再把信息反馈给CPU,这样就很大程度上减轻了CPU资源占有率。DMA模式与PIO模式的区别就在于,DM -
SG DMA与普通DMA(block DMA)的区别
2018-01-10 14:10:34在DMA传输数据的过程中,要求源物理地址和目标物理地址必须是连续的。但是在某些计算机体系中,如IA架构,连续的存储器地址在物理上不一定是连续的,所以DMA传输要分成多次完成。如果在传输完一块物理上连续的数据后... -
DMA传送
2020-09-15 15:01:58目录DMA的由来两种由CPU控制的传送方式程序传送方式无条件传送方式查询(有条件)传送方式中断传送方式CPU控制传送方式总结DMA原理DMA的传送过程预处理数据传送后处理...在DMA出现之前,CPU与外设之间的数据传送方式 -
DMA之理解
2018-09-12 12:32:37在DMA出现之前,CPU与外设之间的数据传送方式有程序传送方式、中断传送方式。CPU是通过系统总线与其他部件连接并进行数据传输。 1.1程序传送方式 程序传送方式是指直接在程序控制下进行数据的输入/输出操作。... -
DMA摘记
2017-10-11 10:43:00而在DMA模式下,CPU只须向DMA控制器下达指令,让DMA控制器来处理数据的传送,数据传送完毕再把信息反馈给CPU,这样就很大程度上减轻了CPU资源占有率。DMA模式与PIO模式的区别就在于,DMA模式不过分依赖CPU,可以大大... -
关于DMA
2018-05-17 17:49:00用串口在dma中发东西的时候,,, 要判断DMA里是不是由东西,是不是在占用 当多个外设再用DMA的时候,,,要查看DMA有没有占用 一包数没发完,不要再传另一包 转载于:... -
DMA知识
2017-11-20 15:37:21DMA(Direct Memory Access,...在DMA模式下,CPU只须向DMA控制器下达指令,让DMA控制器来处理数据的传送,数据传送完毕再把信息反馈给CPU,这样就很大程度上减轻了CPU资源占有率,可以大大节省系统资源。DMA方式是一
-
(js)leetcode 1295. 统计位数为偶数的数字
-
FACEBOOK 时间序列预测算法 PROPHET 的研究
-
【考研初试】安徽建筑大学501建筑设计考研真题库资料
-
安徽大学617古代汉语和现代汉语考研历年真题库资料
-
svg_pnf_Selector-源码
-
elasticsearch简单API的使用(CRUD)
-
网上行销原则.txt
-
金士顿U盘微博营销活动策划方案.ppt
-
ssm超市订单管理系统
-
ELF视频教程
-
MySQL 管理利器 mysql-utilities
-
MySQL 数据库权限管理(用户高级管理和精确访问控制)
-
Day08-笔记
-
智能停车场云平台(附vue+SpringBoot前后端项目源码)
-
占据主动!刘强东微博营销之道.pdf
-
13款手机浏览器分析(Android).pptx
-
利用社交媒体创造销售奇迹的十大经典案例.jpg
-
抖音任务点赞平台源码.zip
-
公共信用信息分类与编码规范(试行).pdf
-
ssm在线视频教育网站