dma

基于stm32mini开发板的简易函数发生器和简易示波器

五迷三道 提交于 2020-02-27 11:00:48
基于stm32 mini开发板的简易函数发生器和简易示波器 前言:这是我学习完stm32基础知识后做的第一个比较综合的项目,由于本人学习时间不长,在程序设计方面能力不强,故展示的代码或者方法可能有误,还请各位大佬海涵,我也很高兴大家能在评论区提出建议和意见,谢谢。 一、项目整体思路和实现的功能 这个项目是基于正点原子stm32 mini开发板设计的,使用芯片为STM32F103RCT6,相关配置步骤和基础知识,可以在正点原子论坛找到。 (一)、简易示波器思路和功能 利用stm32强大的ADC功能,在一定时间内采集IO口电压,将采集到的一定数值保存在数组中,经过数据处理后,显示在LCD上。 能实现正电压下,0~3.3v电压的显示,以及最高10KHZ的频率显示(10K以上显示将不清晰)。能通过两个按键实现对ADC采样周期的转换,分为us级和ms级。 (二)、简易函数发生器思路和功能 利用stm32强大的DAC和DMA功能,以定时器2触发DAC转换,以DMA传送需要转换的数值,以达到目标波形的输出。 能实现正弦波,三角波,方波,锯齿波,甚至模拟噪声波等多种波形的输出,可以调节输出波形的幅值和频率。 二、程序设计和部分原理解释 (一)、外围按键设计 这部分主要涉及改变ADC采样周期,由于整个程序有延时,必须采用中断的方式读取键值并改变采样周期标志位,这样才能达到按一次改变一次的效果

利用DMA双缓冲或半完成中断实现串口不定长数据的接收

最后都变了- 提交于 2020-02-26 18:44:30
在《 HAL版本DMA循环模式串口数据收发 》中介绍了利用DMA循环模式进行串口数据的收发,STM32F4xx的DMA还提供了双缓冲的功能,采用双缓冲模式,可以在一个DMA完成接收后,对其缓冲区内数据进行处理的过程中,将此时接收到的数据放入第二个DMA缓冲区。双缓冲模式尤其对高速数据接收有着明显的优势,本文以上述循环接收方案为基础,提供实现双缓冲接收数据的实现方式。 首先,从寄存器的角度讲,要实现双缓冲,需要将CR寄存器的DBM位置1,将该位置1后,硬件会强制使用循环模式,当一个缓冲满后,会自动交换缓冲区的地址。但我们采用HAL库版本的程序时,不太需要关注这些,但是值得注意的是,HAL库的stm32f4xx_hal_uart.c中并没有提供实现双缓冲的接口,因此需要我们对HAL库的程序进行一些改写: HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { /*省略库中起始部分的程序*/ /* Set the DMA abort callback */ huart->hdmarx->XferAbortCallback = NULL; /* Enable the DMA stream */ //HAL_DMA_Start_IT(huart-

STM32同步定时器并触发ADC_DMA多路采样

爱⌒轻易说出口 提交于 2020-02-26 14:54:30
STM32同步定时器并触发ADC_DMA多路采样 ctime:2019-05-05 16:53:06 +0800|1557046386 标签(空格分隔): 技术 硬件 需求是这样的: 做电机驱动,需要采集电压和电流的时候,由于H桥驱动管以16K的频率再开关,如果随意进行ADC采样的话,会采到MOS关断时候的电压值和电流值,对整个电压和电流的估计造成影响。最好的情况就是在PWM为高电平,也就是MOS导通的时候,采集相应的电压和电流。 那么实现方式就是用定时器来触发ADC进行采样,而这个定时器又必须与发出PWM波的定时器计数是同步的,假设驱动电机的定时器为TIM2,那么用TIM4作为从定时器,TIM4另外发出一路PWM波来触发ADC采样。 假设此时驱动电机的占空比为50%,那么TIM4发出的PWM波占空比应该是25%(在高电平的中间采样),同时由于ADC是上升沿触发,因此需要将TIM4的PWM波极性反一下,直接设置为PWM_MODE_2即可。 思路就是这样,接下来开始配置: ADC配置: void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig; /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of

Linux内存使用调整

☆樱花仙子☆ 提交于 2020-02-26 01:28:24
前段时间在做播放器的时候,遇到个问题,花了很长时间,做个记录,希望对有需要的人有所帮助: 播放器的播视频的时候,无论是手动切换视频还是到视频播放完成,自动切换视频,一定次数后均出现黑屏现象,偶尔有声音,问题出现后,不可恢复,Kernel输出如下Log: DMA free:71672kB min:616kB low:768kB high:924kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolateds lowmem_reserve[]: 0 1244 1593 1593 Normal free:1249804kB min:4212kB low:5264kB high:6316kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB o lowmem_reserve[]: 0 0 2794 2794 HighMem free:223000kB min:348kB low:640kB high:936kB active_anon:39248kB inactive_anon:140kB active_file:61020kB inactive

windbg命令详解

青春壹個敷衍的年華 提交于 2020-02-24 09:52:20
DLL 该扩展仅在内核模式下使用,即使它是在 Ext.dll 中的。 Windows NT 4.0 Ext.dll Windows 2000 Ext.dll Windows XP和之后 Ext.dll 注释 如果不提供参数,调试器会列出所有进程,以及时间和优先级统计。这和使用 !process @#Process 0 作为 CommandString 值一样。 To terminate execution at any point, press CTRL+BREAK (in WinDbg) or CTRL+C (in KD). 附加信息 关于进程的一般信息,查看 线程和进程 。进程操作和获取进程信息,查看 控制进程和线程 。 !for_each_thread !for_each_thread 扩展对目标机中每个线程执行一次指定的调试器命令。 语法 !for_each_thread [ " CommandString " ] !for_each_thread -? 参数 CommandString 指定要为每个线程执行的调试器命令。如果 CommandString 包括多条命令,则需要用分号( ; )分隔他们,并且将 CommandString 包含在引号(")中。如果 CommandString 被包含在引号中,则 CommandString 中的命令不能包含引号。在

总线主控DMA

给你一囗甜甜゛ 提交于 2020-02-17 18:30:38
DMA都是主控总线的,这里的总线主控DMA是指设备本身具备DMA功能,而无需使用系统DMA控制器。 总线主控DMA的设备,有两种基本的DMA方式 基于包的DMA传输 使用公共缓冲区的传输 基于包的DMA传输一般是这样的过程: IRP到达Dispacher Dispacher分配一个通道 AllocateAdapterChannel ,这个例程会在一个合适的时候调用它的一个回调函数 回调函数内部会根据IRP的MDL得到内核虚拟地址,接着 MapTransfer ,调用会得到物理地址,这个物理地址是指总线相关的物理地址 得到物理地址后,一般是写入硬件寄存器,并且通知启动DMA传输 真正的DMA传输就开始了 这种方式的DMA是可以直接把硬件的数据DMA到应用层的,效率相当高。另外DDK文档说明了一些Cache的控制,以及映射寄存器(x86是软件模拟的)的一些关系。需要仔细推敲和理解 使用公共缓冲区的传输是比较简单的: 在StartDevice时, AllocateCommonBuffer 得到一个公共缓冲区,这个缓冲区是物理连续的,有时候是会失败的。如果失败,那么StartDevice应该返回STATUS_INSUFFICIENT_RESOURCES. 和基于包的一样,IRP到达Dispacher,Dispacher直接使用缓冲区域地址编程硬件就可以启动DMA了

STM32F4x系列的DMA配置

不想你离开。 提交于 2020-02-15 20:47:28
以SPI2 为例,将存储器中的数据,通过DMA方式搬运到外设,DMA配置步骤: 1、选择DMA1还是DMA2:通过图1可查看到SPI2是在DMA1表里,所以选择DMA1。   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE); 2、选择数据流:该配置应该放在所有信息配置完在使能。   DMA_Cmd(DMAX_StreamY, ENABLE);   其中X = 1、2,Y=0、1…7,有两个DMA,分别是DMA1和DMA2,每个DMA控制器有又有8个数据流。   问题1:一个外设怎么知道选哪个数据流呢?   答:先查看参考手册,找到DMA1/2请求映射表,如下图1、2 图1 图2   比如现在用到外设SPI2_TX(存储器的数据搬运到外设,所以得找发送) ,选择数据流4。   DMA_Cmd(DMA1_Stream4, ENABLE); 3、通道选择,有8个通道,不是随便选择的,得查看图1和图2,SPI2外设所对应的通道0。   DMA_InitStructure.DMA_Channel = DMA_Channel_0; 4、设置外设基地址。   DMA_InitStructure.DMA_PeripheralBaseAddr = 0Xxxxx;    问题2:怎么知道当前选用外设的基地址?看人家例子都是写好了的,到时换其他外设

RT600 I2S外设介绍及应用

穿精又带淫゛_ 提交于 2020-02-14 14:48:50
恩智浦的i.MX RT600是跨界处理器产品,同样也是i.MX RTxxx系列的开山之作。不同于i.MX RT1xxx系列单片机,i.MX RT600 采用了双核架构,将新一代Cortex-M33内核与高性能Cadence Tensilica HiFi 4 音频DSP内核相结合,适用于32位沉浸式音频播放和视频用户界面应用。i.MX RT600旨在通过安全、功率优化的嵌入式处理器充分挖掘语音辅助终端节点的潜力,因此针对音频数据的采集、传输和处理,i.MX RT600都有丰富的硬件资源进行支持。其中,针对RT600的I2S外设,本文详细地进行了介绍,并基于i.MX RT600 EVK开发板,在RT600的DSP端(HiFi4)实现了一个音频数字回环的demo。 一、I2S介绍 1.1 I2S 接口 I2S总线为数字音频流的传输提供了标准的通信接口,由飞利浦制定。I2S总线规范定义了一种3线串行总线,分别是: 1、串行时钟SCK(也称位时钟BCLK),这是SDA线上数据的位时钟。对应SDA的每一个数据位,SCLK都有产生一个脉冲。 2、帧时钟WS(也称LRCK,或FSYNC),以大多数单一立体声格式的PDM数据来说,WS用于切换左右声道的数据;在DSP或TDM模式下用作帧定界符。此外,I2S的采样频率是由WS频率决定的。 3、串行数据(SDA),就是用二进制表示的音频数据流

I2S 总线学习:2-I2S驱动WM8978

不问归期 提交于 2020-02-14 11:04:23
背景 为了了解I2S总线所对应的硬件设计,下文转载了 《STM32:I2S驱动WM8978》 。 以加深对I2S总线的了解。 正文 最近项目中使用STM32F4驱动音频IC:WM8978。 由于STM32的I2S接口只有一个数据引脚,因此在设计引脚的时候,就需要确定是录音还是放音。 WM8978为DAC+ADC芯片,本身并不具备编解码的功能。 1)WM8978可通过I2S接口接收PCM数据,转为模拟信号输出,此为DAC过程,即放音; 2)WM8978可接收模拟信号转为数字信号,通过I2S接口传输给MCU,此为ADC过程,即录音。 3)WM8978还使用I2C接口配置其工作参数,比如音量,EQ,3D环绕等。WM8978本身可直连1W/8欧的小喇叭。(在下文中没有使用) 1.GPIO配置 我使用的是I2S3,对着硬件工程师给的原理图,再使用STM32CubeMX对照各个管脚看看是否有此映射。不得不说,新版的STM32CubeMX使用起来有些不顺。我只喜欢使用STM32CubeMX查看资源,却不喜欢这个软件的代码,架构有些不合我意。 我使用的还是传统的库,版本为V1.4.0。 GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |

STM32 hal库串口DMA模式收发定长数据

♀尐吖头ヾ 提交于 2020-02-12 00:19:32
//DMA接收定义为循环模式,只能接受定长数据 //串口DMA中断调用的回调函数和串口接收中断是同一个 uint8_t rxch [ 5 ] ; uint8_t trch [ ] = "transmit dma:\r\n" ; int main ( void ) { HAL_UART_Transmit_DMA ( & huart1 , trch , 15 ) ; HAL_UART_Receive_DMA ( & huart1 , rxch , 5 ) ; while ( 1 ) { } } //DMA接收完成回调函数和这是同一个 void HAL_UART_RxCpltCallback ( UART_HandleTypeDef * huart ) { if ( huart -> Instance == USART1 ) { printf ( "%s\r\n" , rxch ) ; HAL_UART_Transmit_DMA ( & huart1 , rxch , 5 ) ; } } //DMA传输完成回调函数和这是同一个 void HAL_UART_TxCpltCallback ( UART_HandleTypeDef * huart ) { uint8_t tx_str [ ] = "Data Transfer completed\r\n" ; HAL_UART_Transmit