stm32,DMA采集一个AD数据,并通过DMA向串口发送

合集下载

STM32CubeMx——串口使用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接收数据情况,接收到之后⼀般是作运算处理的,所以⽤⼀般串⼝发送验证接收的数据正确。

stm32f103 dma案例

stm32f103 dma案例

STM32F103 DMA案例背景STM32F103是意法半导体(STMicroelectronics)推出的一款32位Cortex-M3内核的单片机,具有丰富的外设和强大的性能。

其中,DMA(Direct Memory Access)是STM32F103系列的一个重要特性,它能够实现外设和内存之间的数据传输,大大减轻了CPU的负担,提高了系统的性能。

本文将通过一个具体的案例来介绍STM32F103的DMA功能以及如何使用DMA进行数据传输。

案例描述在某个智能家居系统中,需要读取多个传感器的数据,并将数据通过串口发送给上位机进行处理和显示。

传感器的数据采集频率较高,而且需要实时传输,因此需要一种高效的方式来进行数据传输。

为了减轻CPU的负担,我们决定使用STM32F103的DMA功能来实现数据的传输。

硬件准备•STM32F103开发板•传感器模块•上位机串口调试工具软件准备•Keil MDK开发环境•STM32CubeMX配置工具案例过程步骤1:配置GPIO和串口首先,使用STM32CubeMX配置工具对STM32F103进行初始化配置。

打开STM32CubeMX,选择对应的芯片型号(例如STM32F103C8T6),然后进行以下配置:1.在”Pinout & Configuration”选项卡中,配置GPIO引脚。

将传感器模块的数据引脚连接到STM32F103的GPIO引脚,使其能够读取传感器数据。

2.在”Peripherals”选项卡中,配置串口。

选择一个可用的串口(例如USART1),配置波特率和其他参数,以便与上位机进行通信。

完成配置后,点击”Project”菜单,选择”Generate Code”生成代码。

然后将生成的代码导入到Keil MDK开发环境中。

步骤2:配置DMA传输在Keil MDK中打开生成的工程,找到对应的串口初始化代码。

在初始化代码中加入以下代码,配置DMA传输:// 定义DMA传输缓冲区#define BUFFER_SIZE 100uint8_t buffer[BUFFER_SIZE];// 配置DMA传输DMA_HandleTypeDef hdma_usart1_tx;hdma_usart1_tx.Instance = DMA1_Channel4;hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;hdma_usart1_tx.Init.Mode = DMA_NORMAL;hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;HAL_DMA_Init(&hdma_usart1_tx);// 关联DMA和串口__HAL_LINKDMA(huart, hdmatx, hdma_usart1_tx);以上代码中,首先定义了一个长度为100的缓冲区,用于存储传感器数据。

STM32多通道ADC采集详解(DMA模式和非DMA模式)

STM32多通道ADC采集详解(DMA模式和非DMA模式)

STM32多通道ADC采集详解(DMA模式和非DMA模式)在非DMA模式下,ADC采集的数据是通过CPU直接读取的,采集效率相对较低,但是编程相对简单。

首先,需要初始化ADC模块的工作模式(单通道、多通道等)和采样时间。

然后,使能ADC模块,并配置所需的通道和采样时间。

接着,设置采样序列,指定要采集的通道和相应的排列顺序。

在采集数据时,首先需要设置ADC转换模式和采样时间,然后开始转换,并等待转换完成。

转换完成后,通过读取ADC_DR寄存器可以获取转换结果。

如果需要采集多个通道的数据,可以通过设置ADCSQR中的SQx位来启动下一次转换。

在DMA模式下,ADC采集的数据是通过DMA控制器传输到指定的内存区域,采集效率较高,适合数据量较大的应用场景。

与非DMA模式相比,DMA模式下的配置需要额外设置DMA控制器的工作模式(单次传输、循环传输等)和传输数据的目的地地址。

在采集数据前,需要设置DMA传输的目的地地址,并使能DMA传输。

在开启ADC转换后,DMA控制器会根据设置的目的地地址来自动传输数据,无需CPU干预。

采集完成后,CPU可以通过检查DMA传输完成标志位来判断数据是否已传输完毕。

总结:
使用非DMA模式的ADC采集相对简单而容易上手,适用于数据量较小且对实时性要求不高的应用场景。

DMA模式下的ADC采集效率更高,适用于数据量较大且对实时性要求较高的应用场景。

无论是DMA模式还是非DMA模式,都需要根据具体的应用需求来选择合适的模式。

在使用DMA模式时,还需要注意合理设置DMA传输的目的地地址和传输模式,以充分发挥DMA的优势。

STM32串口采用DMA方式收发

STM32串口采用DMA方式收发

STM32串⼝采⽤DMA⽅式收发FROM:什么是DMA —- Directional Memory Access, 直接存储器存取⽤来提供在外设和存储器之间或者存储器和存储器之间的⾼速数据传输。

⽆须CPU⼲预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作我们通过以下⼏⽅⾯学习串⼝DMA:⼀、如何理解DMA对于DMA,打个⽐⽅就很好理解:⾓⾊预设:淘宝店主 —- STM32 MCU快递员 —- 外设(如UART,SPI)发货室 —- DMA1、⾸先你是⼀个淘宝店主,如果每次发货收货都要跟快递沟通交涉会很浪费时间和精⼒。

2、然后你就⾃⼰建了⼀个发货室,发货室⾥有好多个货柜箱⼦,每个箱⼦上都写着快递名字(如果申通快递,顺丰快递等)。

3、每次发什么快递,你就找到对应的货柜箱⼦,把货物放进去即可,然后跟快递通知⼀声。

4、快递取⾛快件。

5、如果是收货,快递直接把快件放到对应的柜⼦,然后通知你⼀下。

6、你过来提取货物。

通过上⾯的⽅式,你可以不需要直接跟快递打交道,就可以轻松发货成功,DMA处理⽅式跟上⾯例⼦是⼀样的。

如果下图:⼆、STM32 DMA 配置那么DMA在STM32上是具体怎么实现的呢?我们先了解⼀下STM32关于DMA的相关配置。

1、两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道)ps:对应我们例⼦,就是有两个⼤的发货室,⼀个有7个货柜,另个有5个货柜。

2、在同⼀个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很⾼、⾼、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推)ps: 店主可以跟每个快递公司签订协议,可以在货柜前贴上加急(很⾼),很急(⾼),急(中),⼀般(低),如果同时有⼏个快递员过来取货,优先根据上⾯的优先级先取件。

3、独⽴数据源和⽬标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。

源和⽬标地址必须按数据传输宽度对齐。

stm32f103 dma案例

stm32f103 dma案例

stm32f103 dma案例STM32F103 DMA(Direct Memory Access)是一种用于高效数据传输的技术,通过在外设和内存之间设置数据传输通道,可以减轻CPU 的负担,提高系统的效率。

在这里,我们将介绍一个使用STM32F103的DMA功能的案例,具体来说是使用DMA传输数据到USART串口。

首先,我们需要在STM32F103上配置USART串口和DMA通道。

我们将USART串口配置为发送模式,并且使能DMA功能。

然后,我们设置DMA通道的传输方向为从内存到外设(USART),并设置传输的数据长度以及数据传输的起始地址。

接下来,我们需要准备要发送的数据,可以是一个字符串、一个数组或者其他形式的数据。

在本例中,我们将准备一个字符串,用于发送到USART串口。

然后,我们需要编写一个函数来启动DMA传输。

在这个函数中,我们首先需要初始化并配置DMA通道。

然后,我们将准备好的数据作为源地址传递给DMA,并设置传输的长度。

最后,我们启动DMA传输。

在主函数中,我们调用启动DMA传输的函数,并通过USART串口发送了一段文本。

在运行程序时,DMA将负责将数据从内存传输到USART串口,而不需要CPU的干预。

这样,我们可以节省CPU的处理时间,并提高系统的效率。

下面是一个使用STM32F103的DMA功能的示例代码:```c#include "stm32f10x.h"#define USART1_DMA_CHANNEL DMA1_Channel4#define USART1_DMA_STREAM DMA1_Stream4#define USART1_DR_ADDRESS ((uint32_t)0x40013804)void DMA_USART_Send(char* data, uint16_t length) {DMA_InitTypeDef dmaInitStruct;/*开启DMA和USART时钟*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);/*初始化DMA通道*/DMA_DeInit(USART1_DMA_CHANNEL);DMA_StructInit(&dmaInitStruct);dmaInitStruct.DMA_PeripheralBaseAddr = USART1_DR_ADDRESS;dmaInitStruct.DMA_MemoryBaseAddr = (uint32_t)data;dmaInitStruct.DMA_DIR = DMA_DIR_PeripheralDST;dmaInitStruct.DMA_BufferSize = length;dmaInitStruct.DMA_PeripheralInc =DMA_PeripheralInc_Disable;dmaInitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;dmaInitStruct.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte;dmaInitStruct.DMA_MemoryDataSize =DMA_MemoryDataSize_Byte;dmaInitStruct.DMA_Mode = DMA_Mode_Normal;dmaInitStruct.DMA_Priority = DMA_Priority_High; dmaInitStruct.DMA_M2M = DMA_M2M_Disable;DMA_Init(USART1_DMA_CHANNEL, &dmaInitStruct); /*配置USART串口*/USART_InitTypeDef usartInitStruct;USART_StructInit(&usartInitStruct); ART_BaudRate = 9600;USART_Init(USART1, &usartInitStruct);/*启动DMA传输*/DMA_Cmd(USART1_DMA_CHANNEL, ENABLE);USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); }int main(void) {/*初始化串口*/USART_InitTypeDef usartInitStruct;USART_StructInit(&usartInitStruct);ART_BaudRate = 9600;USART_Init(USART1, &usartInitStruct);/*启动DMA传输*/char data[] = "Hello, DMA!";DMA_USART_Send(data, sizeof(data));while(1);return 0;}```以上代码中,我们使用了STM32F103的库函数来进行配置和操作,使得编程更加方便快捷。

ADC结合DMA例子

ADC结合DMA例子

STM32 ADC结合DMA数据采样与软件滤波处理2012-03-17 23:53:05| 分类:STM32 | 标签:adc结合dma |举报|字号订阅本文原创于观海听涛,原作者版权所有,转载请注明出处。

作为一个偏向工控的芯片,ADC采样是一个十分重要的外设。

STM32集成三个12位精度18通道的内部ADC,最高速度1微秒,结合DMA可以解放CPU进行更好的处理。

ADC接口上的其它逻辑功能包括:●同步的采样和保持●交叉的采样和保持●单次采样模拟看门狗功能允许非常精准地监视一路、多路或所有选中的通道,当被监视的信号超出预置的阀值时,将产生中断。

由标准定时器(TIMx)和高级控制定时器(TIM1和TIM8)产生的事件,可以分别内部级联到ADC的开始触发和注入触发,应用程序能使AD转换与时钟同步。

12位ADC是一种逐次逼近型模拟数字数字转换器。

它有多达18个通道,可测量16个外部和2个内部信号源。

ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生。

如果被ADC转换的模拟电压低于低阀值或高于高阀值,AWD模拟看门狗状态位被设置。

关于ADC采样与DMA关系,引用网上一段解释:STM32 的优点在哪里?除去宣传环节,细细分析。

STM32 时钟不算快,72MHZ,也不能扩展大容量的RAM FLASH,同样没有DSP 那样强大的指令集。

它的优势在哪里呢?---就在快速采集数据,快速处理上。

ARM 的特点就是方便。

这个快速采集,高性能的ADC 就是一个很好的体现,12 位精度,最快1uS 的转换速度,通常具备2 个以上独立的ADC 控制器,这意味着,STM32 可以同时对多个模拟量进行快速采集,这个特性不是一般的MCU具有的。

以上高性能的ADC,配合相对比较块的指令集和一些特色的算法支持,就构成了STM32 在电机控制上的强大特性。

好了,正题,怎末做一个简单的ADC,注意是简单的,ADC 是个复杂的问题,涉及硬件设计,电源质量,参考电压,信号预处理等等问题。

STM32-ADC结合DMA数据采样与软件滤波处理

STM32-ADC结合DMA数据采样与软件滤波处理

STM32 ADC结合DMA数据采样与软件滤波处理2012-03-17 23:53:05| 分类:STM32 | 标签:adc结合dma |字号大中小订阅本文原创于观海听涛,原作者所有,请注明出处。

作为一个偏向工控的芯片,ADC采样是一个十分重要的外设。

STM32集成三个12位精度18通道的部ADC,最高速度1微秒,结合DMA可以解放CPU进行更好的处理。

ADC接口上的其它逻辑功能包括:●同步的采样和保持●交叉的采样和保持●单次采样模拟看门狗功能允许非常精准地监视一路、多路或所有选中的通道,当被监视的信号超出预置的阀值时,将产生中断。

由标准定时器(TIMx)和高级控制定时器(TIM1和TIM8)产生的事件,可以分别部级联到ADC 的开始触发和注入触发,应用程序能使AD转换与时钟同步。

12位ADC是一种逐次逼近型模拟数字数字转换器。

它有多达18个通道,可测量16个外部和2个部信号源。

ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生。

如果被ADC转换的模拟电压低于低阀值或高于高阀值,AWD模拟看门狗状态位被设置。

关于ADC采样与DMA关系,引用网上一段解释:STM32 的优点在哪里?除去宣传环节,细细分析。

STM32 时钟不算快,72MHZ,也不能扩展大容量的RAM FLASH,同样没有DSP 那样强大的指令集。

它的优势在哪里呢?---就在快速采集数据,快速处理上。

ARM 的特点就是方便。

这个快速采集,高性能的ADC 就是一个很好的体现,12 位精度,最快1uS 的转换速度,通常具备2 个以上独立的ADC 控制器,这意味着,STM32 可以同时对多个模拟量进行快速采集,这个特性不是一般的MCU具有的。

以上高性能的ADC,配合相对比较块的指令集和一些特色的算法支持,就构成了STM32 在电机控制上的强大特性。

好了,正题,怎末做一个简单的ADC,注意是简单的,ADC 是个复杂的问题,涉及硬件设计,电源质量,参考电压,信号预处理等等问题。

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现此STM32单片机为STM32F103系列的STM32的ADC有DMA功能这都毋庸置疑,也是我们用的最多的!然而,如果我们要对一个信号(比如脉搏信号)进行定时采样(也就是隔一段时间,比如说2ms),有三种方法:1、使用定时器中断每隔一定时间进行ADC转换,这样每次都必须读ADC的数据寄存器,非常浪费时间!2、把ADC设置成连续转换模式,同时对应的DMA通道开启循环模式,这样ADC就一直在进行数据采集然后通过DMA把数据搬运至内存。

但是这样做的话还得加一个定时中断,用来定时读取内存中的数据!3、使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运!这样只要设置好定时器的触发间隔,就能实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检测DMA转换完成标志,然后进行数据的读取,或者使能DMA转换完成中断,这样每次转换完成就会产生中断,我是采用第二种方法。

下面上代码:我这里使用的单通道//定时器初始化voidTIM2_ConfiguraTIon(void){TIM_TImeBaseInitTypeDefTIM_TimeBaseStructure;TIM_OCInitTypeDefTIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_TimeBaseStructure.TIM_Period=1999;//设置2ms一次TIM2比较的周期TIM_TimeBaseStructure.TIM_Prescaler=71;//系统主频72M,这里分频71,相当于1000K 的定时器2时钟TIM_TimeBaseStructure.TIM_ClockDivision=0x0;。

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现此STM32单片机为STM32F103系列的STM32的ADC有DMA功能这都毋庸置疑,也是我们用的最多的!然而,如果我们要对一个信号(比如脉搏信号)进行定时采样(也就是隔一段时间,比如说2ms),有三种方法:1、使用定时器中断每隔一定时间进行ADC转换,这样每次都必须读ADC的数据寄存器,非常浪费时间!2、把ADC设置成连续转换模式,同时对应的DMA通道开启循环模式,这样ADC就一直在进行数据采集然后通过DMA把数据搬运至内存。

但是这样做的话还得加一个定时中断,用来定时读取内存中的数据!3、使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运!这样只要设置好定时器的触发间隔,就能实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检测DMA转换完成标志,然后进行数据的读取,或者使能DMA转换完成中断,这样每次转换完成就会产生中断,我是采用第二种方法。

下面上代码:我这里使用的单通道//定时器初始化voidTIM2_ConfiguraTIon(void){TIM_TImeBaseInitTypeDefTIM_TimeBaseStructure;TIM_OCInitTypeDefTIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_TimeBaseStructure.TIM_Period=1999;//设置2ms一次TIM2比较的周期TIM_TimeBaseStructure.TIM_Prescaler=71;//系统主频72M,这里分频71,相当于1000K 的定时器2时钟TIM_TimeBaseStructure.TIM_ClockDivision=0x0;。

奋斗STM32V3版ADC例程

奋斗STM32V3版ADC例程

奋斗版 STM32 开发板例程详解———ADC 采集例程ADC 采集例程实验平台:奋斗版STM32开发板MINI、V2、V2.1、V3 实验内容:板子加电后,通过串口1显示ADC1的通道11的测量结果,该实验学习了 基于DMA专递方式的ADC采集软件的编制及控制流程。

预先需要掌握的知识1ADC介绍12位ADC是一种逐次逼近型模拟数字转换器。

它有18个通道,可测量16个外部和2个内部 信号源。

各通道的A/D转换可以单次、连续、扫描或间断模式执行。

ADC的结果可以左对齐或 右对齐方式存储在16位数据寄存器中。

模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值值。

2● ● ● ● ● ● ● ● ● ● ●ADC主要特征12-位分辨率 转换结束,注入转换结束和发生模拟看门狗事件时产生中断 单次和连续转换模式 从通道0到通道n的自动扫描模式 自校准 带内嵌数据一致的数据对齐 通道之间采样间隔可编程 规则转换和注入转换均有外部触发选项 间断模式 双重模式(带2个或以上ADC的器件) ADC转换时间: ─ STM32F103xx增强型产品:ADC时钟为56MHz时为1µs(ADC时钟为72MHz为1.17µs) ─ STM32F101xx基本型产品:ADC时钟为28MHz时为1µs(ADC时钟为36MHz为1.55µs) ─ STM32F102xxUSB型产品:ADC时钟为48MHz时为1.2µs ● ADC供电要求:2.4V到3.6V ● ADC输入范围:VREF- ≤ VIN ≤ VREF+ ● 规则通道转换期间有DMA请求产生。

3 ADC功能描述 3.1 ADC开关控制通过设置ADC_CR1寄存器的ADON位可给ADC上电。

当第一次设置ADON位时, 它将ADC 从断电状态下唤醒。

ADC上电延迟一段时间后,再次设置ADON位时开始进行转换。

STM32串口DMA方式发送数据

STM32串口DMA方式发送数据

STM32 串口DMA方式接收2011-04-02 18:13 4458人阅读评论(5) 收藏举报 STM32 是一款基于ARM Cortex-M3内核的32位MCU,主频最高可达72M。

最近因为要在车机上集成TPMS功能,便开始着手STM32的开发工作,STM32F10x系列共有5个串口(USART1~USART5),支持DMA方式通信,DMA 方式由于不需要CPU的参与,而是直接由DMA控制器完成串口数据的读写,因而可以很大程度的提高CPU的利用率。

在使用STM32串口之前需要做一系列的初始化工作:1.RCC(复位和时钟控制寄存器)初始化,启用GPIO、DMA、USART时钟。

2.NVIC(嵌套向量中断控制寄存器)初始化,完成各个硬件中断的配置。

ART初始话,配置串口,设置DMA通道等。

4.DMA初始化,完成DMA的配置。

最后是使能USART和DMA。

下面是通过DMA的方式从串口USART1接收数据,STM32工作后串口数据由DMA控制器接收存到指定buffer,读取数据直接从DMA buffer中读取即可。

发送数据采用非DMA方式,首先将待发送的数据存入到发送队列,然后在任务循环中将队列中的数据发送给USART1。

实例代码如下:[cpp]view plaincopyprint?1. //**********************************************************************************************2. // STM32F10x USART Test3. // compiler: Keil UV34. // 2011-03-28 , By friehood5. //**********************************************************************************************6. static int8u rDMABuffer[64]; // DMA buffer7. static int16u rDMARear = sizeof(rDMABuffer);8.9. static int8u USART_RevBuf[64]; // 串口接收buffer10. s tatic int8u USART_SndBuf[64]; // 串口发送buffer11. s tatic int8u Head=0,Tail=0; // 发送buffer的头尾12.13.14. // 串口任务15. v oid Task_USART(void)16. {17. int16u end;18. if (USART1->SR & (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE))19. {20. USART_ReceiveData(USART1);21. }22.23. // DMA接收24. end = DMA_GetCurrDataCounter(DMA1_Channel5);25. /*if((sizeof(rDMABuffer)-end)>0)26. dbgprt("DMA available datalen=%d/n",sizeof(rDMABuffer)-end); */27. while(rDMARear != end)28. {29. USART_receive(rDMABuffer[sizeof(rDMABuffer)-rDMARear]);30. if (!(--rDMARear))31. {32. rDMARear = sizeof(rDMABuffer);33. }34. }35.36. //发送37. if(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == SET)38. {39. int8u chr;40. // 从发送队列取出一个字符41. if(PopFront(&chr))42. {43. USART_SendData(USART1, chr);44. dbgprt("USART_SendData:0x%02x/n",chr);45. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)46. {47. }48. }49. }50. }51.52.53. // USART串口初始化54. v oid dev_USART_init(void)55. {56. USART_InitTypeDef USART_InitStructure;57. GPIO_InitTypeDef GPIO_InitStructure;58. DMA_InitTypeDef DMA_InitStructure;59.60. /* DMA1 Channel5 (triggered by USART1 Rx event) Config */ //参见 STM32 datasheet61. DMA_DeInit(DMA1_Channel5);62. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;63. DMA_InitStructure.DMA_MemoryBaseAddr = (u32)rDMABuffer;64. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;65. DMA_InitStructure.DMA_BufferSize = sizeof(rDMABuffer);66. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;67. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;68. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;69. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;70. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;71. DMA_InitStructure.DMA_Priority = DMA_Priority_Low;72. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;73. DMA_Init(DMA1_Channel5, &DMA_InitStructure);74.75. USART_ART_BaudRate = 9600;76. USART_ART_WordLength = USART_WordLength_8b;77. USART_ART_StopBits = USART_StopBits_1;78. USART_ART_Parity = USART_Parity_No;79. USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;80. USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;81.82. //配置IO: GPIOA9和GPIOA10分别作为串口TX、RX端。

STM32多路ADC+DMA+串口发送程序

STM32多路ADC+DMA+串口发送程序

主函数#include "stm32f10x.h"#include <stdio.h>#include "ADC.h"#include "DMA.h"#include "UASRT.h"u16 *dyz;//建立指针u16 sum[16];//printf重定向函数//int fputc(int ch, FILE*f){USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);return (ch);}//延时函数//void delay_ms(u16 time){u16 i=0;while(time--){i=12000; //????while(i--) ;}}//主函数//int main(void){int i,m,n;SystemInit();adc_ini();USART_int();ADC_SoftwareStartConvCmd(ADC1, ENABLE);//ADC1软启动使能dma();while(1){//求10次采集的平均值for(m=0;m<10;m++){dyz=ADC_ConvertedValue;//给指针赋值while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));//等待DAM传输完毕for(i=0;i<16;i++){sum[i]+=*dyz;dyz++;DMA_ClearFlag(DMA1_FLAG_TC1);//清楚DMA发送完成标志位}}for(n=0;n<16;n++){sum[n]/=10;//计算ADC对应通道的平均值printf("%d=%d\n",n,sum[n]);//通过串口输出delay_ms(200);}}}ADC的.h文件#ifndef __ADC_H_#define __ADC_H_void adc_ini(void){ADC_InitTypeDef ADC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启ADC1时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Pe riph_GPIOC,ENABLE);//使能GPIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开启AFIO时钟//配置模拟输入引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO _Pin_7;//选择第0脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//选择第0脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//选择第0脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式GPIO_Init(GPIOC, &GPIO_InitStructure);//配置ADCRCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADC时钟6分频ADC_DeInit(ADC1);//ADC1填入缺省值ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作在独立模式ADC_InitStructure.ADC_ScanConvMode = ENABLE;//ADC工作在多通道模式ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ADC工作在连续模式ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None;//转换由软件启动ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 16;//转换通道数为1ADC_Init(ADC1, &ADC_InitStructure);//载入设置值ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1,ADC_SampleTime_7Cycles5);//选择ADC1通道0采样顺序为1,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2,ADC_SampleTime_7Cycles5);//选择ADC1通道1采样顺序为2,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3,ADC_SampleTime_7Cycles5);//选择ADC1通道2采样顺序为3,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4,ADC_SampleTime_7Cycles5);//选择ADC1通道3采样顺序为4,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5,ADC_SampleTime_7Cycles5);//选择ADC1通道4采样顺序为5,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6,ADC_SampleTime_7Cycles5);//选择ADC1通道5采样顺序为6,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7,ADC_SampleTime_7Cycles5);//选择ADC1通道6采样顺序为7,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8,ADC_SampleTime_7Cycles5);//选择ADC1通道7采样顺序为8,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9,ADC_SampleTime_7Cycles5);//选择ADC1通道8采样顺序为9,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 10,ADC_SampleTime_7Cycles5);//选择ADC1通道9采样顺序为10,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 11,ADC_SampleTime_7Cycles5);//选择ADC1通道10采样顺序为11,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 12,ADC_SampleTime_7Cycles5);//选择ADC1通道11采样顺序为12,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 13,ADC_SampleTime_7Cycles5);//选择ADC1通道12采样顺序为13,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 14,ADC_SampleTime_7Cycles5);//选择ADC1通道13采样顺序为14,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 15,ADC_SampleTime_7Cycles5);//选择ADC1通道14采样顺序为15,采样时间7.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 16,ADC_SampleTime_7Cycles5);//选择ADC1通道15采样顺序为16,采样时间7.5周期ADC_DMACmd(ADC1, ENABLE);//使能ADC1的DMA请求ADC_Cmd(ADC1, ENABLE);//使能ADC1ADC_ResetCalibration(ADC1);//重置ADC校准值while(ADC_GetResetCalibrationStatus(ADC1));//等待重置完毕ADC_StartCalibration(ADC1);//开始ADC校准while(ADC_GetCalibrationStatus(ADC1));//等待校准完毕}#endifDMA的.H文件#ifndef __DMA_H_#define __DMA_H_u16 ADC_ConvertedValue[16];void dma(void){DMA_InitTypeDef DMA_InitStructure;//使能DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//将DMA通道一设置为缺省值DMA_DeInit(DMA1_Channel1);//定义DMA外设地址DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)( &(ADC1->DR));//定义内存基地址DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;//设置外设作为传输的源DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//指定DMA缓存大小DMA_InitStructure.DMA_BufferSize = 16;//设置外设寄存器地址不递增?DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置内存寄存器地址递增DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//设置外设数据宽度为16位DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;//设置内存数据的宽度为16位DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord;//设置DMA工作在循环模式DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//设置通道为最高优先级DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh ;//设置通道为外设到内存DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA1_Channel1, &DMA_InitStructure);//使能DMA通道1DMA_Cmd(DMA1_Channel1, ENABLE);}#endif串口.H文件#ifndef __USART_H_#define __USART_H_void USART_int(void){USART_InitTypeDef USART_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1 ,ENABLE);//使能GPIOA和USART1时钟USART_DeInit(USART1);//填入缺省值给USART1USART_ART_BaudRate = 9600;//波特率为9600USART_ART_WordLength = USART_WordLength_8b;//数据位为8位USART_ART_StopBits = USART_StopBits_1;//1位停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验USART_ART_HardwareFlowControl=USART_HardwareFlowControl_None;//无控制流USART_ART_Mode = USART_Mode_Tx | USART_Mode_Rx;//接收和发送模式USART_Init(USART1, &USART_InitStructure);//载入设置值GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_Cmd(USART1, ENABLE);//使能USART1}#endif。

STM32串口发送数据和接收数据方式总结!

STM32串口发送数据和接收数据方式总结!

STM32串⼝发送数据和接收数据⽅式总结!串⼝发送数据1、串⼝发送数据最直接的⽅式就是标准调⽤库函数。

voidUSART_SendData(USART_TypeDef* USARTx, uint16_tData) ;第⼀个参数是发送的串⼝号,第⼆个参数是要发送的数据,但是⽤过的朋友应该觉得不好⽤,⼀次只能发送单个字符,所以我们有必要根据这个函数加以扩展:voidSend_data(u8 *s){while(*s!= '0'){while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET);USART_SendData(USART1,*s);s++;}}以上程序的形参就是我们调⽤该函数时要发送的字符串,这⾥通过循环调⽤USART_SendData来⼀⼀发送我们的字符串。

while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET);这句话有必要加,它是⽤于检查串⼝是否发送完成的标志,如果不加这句话会发⽣数据丢失的情况。

这个函数只能⽤于串⼝1发送。

有些时候根据需要,要⽤到多个串⼝发送,那么就还需要改进这个程序。

如下:voidSend_data(USART_TypeDef * USARTx,u8 *s){while(*s!= '0'){while(USART_GetFlagStatus(USARTx,USART_FLAG_TC )==RESET);USART_SendData(USARTx,*s);s++;}}这样就可实现任意的串⼝发送。

但有⼀点,我在使⽤实时操作系统的时候(如UCOS,Freertos等),需考虑函数重⼊的问题。

当然也可以简单的实现把该函数复制⼀下,然后修改串⼝号也可以避免该问题。

然⽽这个函数不能像printf那样传递多个参数,所以还可以再改进,最终程序如下:voidUSART_printf( USART_TypeDef * USARTx, char* Data, ... ){constchar*s;intd;charbuf[ 16];va_list ap;va_start(ap, Data);while( * Data != 0) // 判断是否到达字符串结束符{if( * Data == 0x5c) //''{switch( *++Data ){case'r': //回车符USART_SendData(USARTx, 0x0d);Data ++;break;case'n': //换⾏符USART_SendData(USARTx, 0x0a);Data ++;break;default:Data ++;break;}}elseif( * Data == '%'){ //switch( *++Data ){case's': //字符串s = va_arg(ap, constchar*);for( ; *s; s++){USART_SendData(USARTx,*s);while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); }Data++;break;case'd'://⼗进制d = va_arg(ap, int);itoa(d, buf, 10);for(s = buf; *s; s++){USART_SendData(USARTx,*s);while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); }Data++;break;default:Data++;break;}}elseUSART_SendData(USARTx, *Data++);while( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );}}该函数就可以像printf使⽤可变参数,⽅便很多。

STM32 USART 串口 DMA 接收和发送的源码详解!

STM32 USART 串口 DMA 接收和发送的源码详解!

void DMA_Uart_Init(void) {
DMA_InitTypeDef DMA_InitStructure;
/* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 开启 DMA1 时钟
// 优先级设置
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = LUMMOD_UART_IRQn;
生的,产生的条件是这样的,当清除 IDLE 标志位后,必须有接收到第一个数据
后,才开始触发,一断接收的数据断流,没有接收到数据,即产生 IDLE 中断。
USART 和 DMA 硬件初始化配置
/*--- LumModule Usart Config ---------------------------------------*/
/* Enable GPIO clock */ RCC_APB2PeriphClockCmd(LUMMOD_UART_GPIO_CLK , ENABLE ); // 开启串口所在 IO 端口的时钟 /* Enable USART Clock */ RCC_APB1PeriphClockCmd(LUMMOD_UART_CLK, ENABLE); // 开始串口时钟
否则当 DMA 接收计数器递减到 0 的时候,又会重载这个计数值,重新循环递

stm32串口发送函数

stm32串口发送函数

stm32串口发送函数STM32是一款广泛应用于嵌入式系统开发的微控制器,其具有高性能、低功耗、易于开发等优点。

在STM32的开发中,串口通信是一种常见的通信方式,而串口发送函数则是实现串口通信的重要组成部分。

STM32串口发送函数的实现需要考虑多方面的因素,包括串口的配置、数据的发送方式、数据的格式等。

下面将从这些方面对STM32串口发送函数进行详细介绍。

1. 串口的配置在使用STM32串口发送函数之前,需要先对串口进行配置。

串口的配置包括波特率、数据位、停止位、校验位等参数的设置。

这些参数的设置需要根据具体的应用场景进行选择,以保证数据的可靠传输。

2. 数据的发送方式STM32串口发送函数支持多种数据发送方式,包括阻塞发送、非阻塞发送、DMA发送等。

阻塞发送是指在数据发送完成之前,程序会一直等待,直到数据发送完成后才会继续执行下一条指令。

非阻塞发送是指在数据发送过程中,程序可以继续执行其他指令,不会等待数据发送完成。

DMA发送是指通过DMA控制器实现数据的发送,可以大大提高数据发送的效率。

3. 数据的格式STM32串口发送函数支持多种数据格式,包括ASCII码、十六进制等。

在发送ASCII码时,需要将数据转换为ASCII码格式,然后通过串口发送出去。

在发送十六进制时,需要将数据转换为十六进制格式,然后通过串口发送出去。

下面是一个简单的STM32串口发送函数的实现示例:```void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) {/* 发送一个字节数据到USARTx */USARTx->DR = (Data & (uint16_t)0x01FF);/* 等待发送完成 */while(!(USARTx->SR & USART_FLAG_TXE));}```在这个函数中,首先将要发送的数据写入USARTx的数据寄存器DR 中,然后等待发送完成。

STM32ADC在DMA中断模式下多通道数据采集

STM32ADC在DMA中断模式下多通道数据采集

STM32ADC在DMA中断模式下多通道数据采集在DMA中断模式下进行多通道数据采集,需要进行以下步骤:1.初始化ADC模块:使用HAL库或者标准库,初始化ADC模块,设置采样时间、分辨率、触发源等参数。

同时,还需要配置ADC的多通道模式,选择需要采集的通道。

2.配置DMA:使用HAL库或者标准库,初始化DMA模块,设置DMA通道、数据传输方向、数据传输长度等参数。

3.设置中断回调函数:配置DMA传输完成后的中断回调函数,当DMA传输完成后会触发中断,在该中断中可以进行数据处理操作。

4.开始数据采集:启动ADC和DMA,开始进行数据采集。

下面是一个使用HAL库的示例代码,实现了三个通道的数据采集,每次采集10个数据点,采集完成后会触发中断进行数据处理:```c#include "stm32f4xx_hal.h"#define DATA_SIZE 10ADC_HandleTypeDef hadc1;DMA_HandleTypeDef hdma_adc1;uint16_t adc_data[DATA_SIZE * 3]; // 保存采集到的数据uint8_t current_channel = 0; // 当前采集的通道//ADCDMA中断回调函数void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) if (current_channel == 3)//数据采集完成,进行数据处理操作// 处理adc_data中已经采集到的数据// 重置current_channelcurrent_channel = 0;} else//继续采集下一个通道的数据current_channel++;HAL_ADC_Start_DMA(&hadc1, adc_data + DATA_SIZE * current_channel, DATA_SIZE);}int main(void)HAL_Init(;//初始化ADC模块__HAL_RCC_ADC1_CLK_ENABLE(;hadc1.Instance = ADC1;hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;hadc1.Init.Resolution = ADC_RESOLUTION_12B;hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;hadc1.Init.ContinuousConvMode = DISABLE;hadc1.Init.DiscontinuousConvMode = DISABLE;hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc1.Init.ExternalTrigConvEdge =ADC_EXTERNALTRIGCONVEDGE_NONE;hadc1.Init.DMAContinuousRequests = ENABLE;hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;hadc1.Init.NbrOfConversion = 3;hadc1.Init.ScanConvMode = ENABLE;HAL_ADC_Init(&hadc1);//配置ADC的通道顺序ADC_ChannelConfTypeDef sConfig;sConfig.Channel = ADC_CHANNEL_0;sConfig.Rank = 1;sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;HAL_ADC_ConfigChannel(&hadc1, &sConfig);sConfig.Channel = ADC_CHANNEL_1;sConfig.Rank = 2;HAL_ADC_ConfigChannel(&hadc1, &sConfig);sConfig.Channel = ADC_CHANNEL_2;sConfig.Rank = 3;HAL_ADC_ConfigChannel(&hadc1, &sConfig);//初始化DMA模块__HAL_RCC_DMA2_CLK_ENABLE(;hdma_adc1.Instance = DMA2_Stream0;hdma_adc1.Init.Channel = DMA_CHANNEL_0;hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc1.Init.Mode = DMA_CIRCULAR;hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;HAL_DMA_Init(&hdma_adc1);//设置DMA中断回调函数HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);__HAL_DMA_ENABLE_IT(&hdma_adc1, DMA_IT_TC);//关联ADC和DMA__HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);//开始数据采集HAL_ADC_Start_DMA(&hadc1, adc_data, DATA_SIZE);while (1)//业务逻辑代码}//DMA中断处理函数void DMA2_Stream0_IRQHandler(void)HAL_DMA_IRQHandler(&hdma_adc1);```通过以上代码,就可以实现多通道的数据采集。

STM32定时器触发AD采样+DMA传输问题

STM32定时器触发AD采样+DMA传输问题

STM32定时器触发AD采样+DMA传输问题试验环境:EWARM 4.41A + J-link + 目标板试验内容:TIM1->CC1触发ADC采样,单通道,采样结果使用DMA传输到SRAM中。

问题:下载程序提示SRAM校验错误,拔下J-link 一端的USB 口再插上,下载OK --->停止程序,再下载,提示错误,再拔下J-link USB 口,再下载,OK---> ...如此反复。

仔细看了下Debuglog,发现存放DMA传输到的目标内存数据校验错误(IAR debugger选项中的verify download 选上),如下:Verify error at address 0x2000007C, target byte: 0x3F, byte in file: 0x01分析:可能是停止程序的时候,TIM1和ADC,DMA都没有停下来,下载的时候,DMA 一直写数据到开辟的内存中,导致那部分内存数据校验错误。

以上只是个人的一些看法,不知道不否正确,有没有哪位帮分析下。

/******************************************************************************/附录1:试验程序源码:/* Includes ------------------------------------------------------------------- */#include "stm32f10x_lib.h”/* Private typedef ---------------------------------------------------------- *//* Private define ------------------------------------------------------------ */#define ADC1_DR_Address ((u32)0x4001244C)/* Private macro ----------------------------------------------------------- *//* Private variables -------------------------------------------------------- */ADC_InitTypeDef ADC_InitStructure;DMA_InitTypeDef DMA_InitStructure;TIM1_TimeBaseInitTypeDef TIM1_TimeBaseStructure;TIM1_OCInitTypeDef TIM1_OCInitStructure;TIM1_BDTRInitTypeDef TIM1_BDTRInitStructure;u16 ADC_RegularConvertedValueTab[32];ErrorStatus HSEStartUpStatus;/* Private function prototypes ---------------------------------------------- */void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);/* Private functions -------------------------------------------------------- *//******************************************************************************** Function Name : main* Description : Main program* Input : None* Output : None* Return : None*****************************************************************************int main(void)(#ifdef DEBUGdebug();#endif/* System clocks configuration --------------------------------------------- */RCC_Configuration();/* NVIC configuration ----------------------------------------------------- */NVIC_Configuration();/* GPIO configuration ---------------------------------------------------- */GPIO_Configuration();TIM1_DeInit();/* Time Base configuration */TIM1_TimeBaseStructure.TIM1_Prescaler = 0x00;TIM1_TimeBaseStructure.TIM1_CounterMode = TIM1_CounterMode_Up;TIM1_TimeBaseStructure.TIM1_Period = 3599;TIM1_TimeBaseStructure.TIM1_ClockDivision = 0x00;TIM1_TimeBaseStructure.TIM1_RepetitionCounter = 0x00;TIM1_TimeBaseInit(&TIM1_TimeBaseStructure);/* Channel1 Configuration in PWM mode */TIM1_OCInitStructure.TIM1_OCMode = TIM1_OCMode_PWM1;TIM1_OCInitStructure.TIM1_OutputState = TIM1_OutputState_Enable;TIM1_OCInitStructure.TIM1_OutputNState = TIM1_OutputNState_Enable;TIM1_OCInitStructure.TIM1_Pulse = 100;TIM1_OCInitStructure.TIM1_OCPolarity = TIM1_OCPolarity_Low;TIM1_OCInitStructure.TIM1_OCNPolarity = TIM1_OCNPolarity_High;TIM1_OCInitStructure.TIM1_OCIdleState = TIM1_OCIdleState_Set;TIM1_OCInitStructure.TIM1_OCNIdleState = TIM1_OCIdleState_Reset;TIM1_OC1Init(&TIM1_OCInitStructure);/* TIM1 main Output Enable */TIM1_CtrlPWMOutputs(ENABLE);/* TIM1 counter enable */TIM1_Cmd(ENABLE);/* DMA Channel1 Configuration ---------------------------------------------- */DMA_DeInit(DMA_Channel1);DMA_InitStructure.DMA_Periphera l BaseAddr = ADC1_DR_Address;DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_RegularConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 32;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_VeryHigh;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA_Channel1, &DMA_InitStructure);/* Enable DMA channel1 */DMA_Cmd(DMA_Channel1, ENABLE);/* ADC1 configuration ------------------------------------------------------ */ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);/* ADC1 regular channel14 configuration */ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_13Cycles5); /* Enable ADC1 DMA */ADC_DMACmd(ADC1, ENABLE);/* Enable ADC1 external trigger */ADC_ExternalTrigConvCmd(ADC1, ENABLE);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* TIM1 counter enable *///TIM1_Cmd(ENABLE);/* Test on channell transfer complete flag */while(!DMA_GetFlagStatus(DMA_FLAG_TC1));/* Clear channell transfer complete flag */ DMA_ClearFlag(DMA_FLAG_TC1);/* TIM1 counter disable *///TIM1_Cmd(DISABLE);while (1)())/******************************************************************************** Function Name : RCC_Configuration* Description : Configures the different system clocks.* Input : None* Output : None* Return : None*******************************************************************************/void RCC_Configuration(void) (/* RCC system reset(for debug purpose) */RCC_DeInit();/* Enable HSE */RCC_HSEConfig(RCC_HSE_ON);/* Wait till HSE is ready */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);/* HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* ADCCLK = PCLK2/4 */RCC_ADCCLKConfig(RCC_PCLK2_Div4);/* PLLCLK = 8MHz * 7 = 56 MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);/* Enable PLL */RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){)/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while(RCC_GetSYSCLKSource() != 0x08){))/* Enable peripheral clocks -------------------------------------------------- *//* Enable DMA clock */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);/* Enable GPIOA, GPIOC, ADC1 and TIM1 clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE); )/******************************************************************************** Function Name : GPIO_Configuration* Description : Configures the different GPIO ports.* Input : None * Output : None * Return : None*******************************************************************************/ void GPIO_Configuration(void)GPIO_InitTypeDef GPIO_InitStructure;/* Configure PC.01 and PC.04 (ADC Channel11 and Channel14) as analog input */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOC, &GPIO_InitStructure);/******************************************************************************* * Function Name : NVIC_Configuration * Description : Configures NVIC and Vector Table base location.* Input : None * Output : None * Return : None*******************************************************************************/ void NVIC_Configuration(void) { #ifdef VECT TAB RAM /* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT TAB FLASH */ /* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif/******************************************************************************/附录 2 : Debug LogThu Jan 03 20:00:46 2008: DLL version: V3.62a, compiled Feb 23 2007 17:06:09Thu Jan 03 20:00:46 2008: Firmware: J-Link compiled Jun 14 2007 14:36:33 ARM Rev.5Thu Jan 03 20:00:46 2008: JTAG speed is initially set to: 32 kHzThu Jan 03 20:00:46 2008: Found Cortex-M3, Little endian.Thu Jan 03 20:00:46 2008: TPIU fitted.Thu Jan 03 20:00:46 2008: FPUnit: 6 code (BP) slots and 2 literal slotsThu Jan 03 20:00:46 2008: Software reset was performedThu Jan 03 20:00:46 2008: Initial reset was performedThu Jan 03 20:00:46 2008: J-Link found 2 JTAG devices. ARM core Id: 3BA00477(Cortex M3), ARMcore Id: 00000000(ARM9)Thu Jan 03 20:00:46 2008: Device at TAP0 selectedThu Jan 03 20:00:47 2008: 3080 bytes downloaded and verified (5.20 Kbytes/sec)Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000007C, target byte: 0x42, byte in file: 0x01Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000007D, target byte: 0x08, byte in file: 0x80Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000007E, target byte: 0xCE, byte in file: 0x70Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000007F, target byte: 0x07, byte in file: 0x47Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000080, target byte: 0x42, byte in file: 0x50Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000081, target byte: 0x08, byte in file: 0xF0Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000082, target byte: 0xCF, byte in file: 0x00Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000083, target byte: 0x07, byte in file: 0x60Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000084, target byte: 0x43, byte in file: 0x81Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000085, target byte: 0x08, byte in file: 0x05 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000086, target byte: 0xCE, byte in file: 0x02 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000087, target byte: 0x07, byte in file: 0xD0 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000088, target byte: 0x42, byte in file: 0x5F Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000089, target byte: 0x08, byte in file: 0xF0 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000008A, target byte: 0xCE, byte in file: 0xFF Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000008B, target byte: 0x07, byte in file: 0x30 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000008C, target byte: 0x42, byte in file: 0x70 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000008D, target byte: 0x08, byte in file: 0x47 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000008E, target byte: 0xCF, byte in file: 0x2E Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000008F, target byte: 0x07, byte in file: 0x49 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000090, target byte: 0x41, byte in file: 0x0A Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000091, target byte: 0x08, byte in file: 0x68 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000092, target byte: 0xCE, byte in file: 0xD2 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000094, target byte: 0x41, byte in file: 0xFB Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000095, target byte: 0x08, byte in file: 0xD4 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000096, target byte: 0xCB, byte in file: 0x2D Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000097, target byte: 0x07, byte in file: 0x4A Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000098, target byte: 0x42, byte in file: 0x13 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000099, target byte: 0x08, byte in file: 0x68 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000009A, target byte: 0xCD, byte in file: 0x53 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000009B, target byte: 0x07, byte in file: 0xF0 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000005C, target byte: 0x40, byte in file: 0x15 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000005D, target byte: 0x08, byte in file: 0x00 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000005E, target byte: 0xC8, byte in file: 0x00Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000005F, target byte: 0x07, byte in file: 0x20 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000060, target byte: 0x3E, byte in file: 0x03 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000061, target byte: 0x08, byte in file: 0x4C Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000062, target byte: 0xD3, byte in file: 0x4F Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000063, target byte: 0x07, byte in file: 0xF0 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000064, target byte: 0x49, byte in file: 0x00 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000065, target byte: 0x08, byte in file: 0x00 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000066, target byte: 0xD2, byte in file: 0xA0 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000067, target byte: 0x07, byte in file: 0x47 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000068, target byte: 0x45, byte in file: 0x02 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000069, target byte: 0x08, byte in file: 0x4C Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000006A, target byte: 0xD1, byte in file: 0x03 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000006B, target byte: 0x07, byte in file: 0x4D Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000006C, target byte: 0x42, byte in file: 0xAE Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000006D, target byte: 0x08, byte in file: 0x46 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000006E, target byte: 0xCE, byte in file: 0x20 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000006F, target byte: 0x07, byte in file: 0x47 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000070, target byte: 0x41, byte in file: 0xC1 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000071, target byte: 0x08, byte in file: 0x05 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000072, target byte: 0xCA, byte in file: 0x00 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000073, target byte: 0x07, byte in file: 0x20 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000074, target byte: 0x40, byte in file: 0xC9 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000075, target byte: 0x08, byte in file: 0x06 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000076, target byte: 0xC9, byte in file: 0x00 Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000077, target byte: 0x07, byte in file: 0x20Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x20000078, target byte: 0x3B, byte in file: 0x9DThu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000007A, target byte: 0xD1, byte in file: 0x00Thu Jan 03 20:00:47 2008: Warning:Verify error at address 0x2000007B, target byte: 0x07, byte in file: 0x20Thu Jan 03 20:00:47 2008: There were warnings during download of FLASH loader, see Log WindowThu Jan 03 20:00:48 2008: Failed to load flash loader: C:\Program Files\IAR Systems\Embedded Workbench 4.0 Evaluation\ARM\config\flashloader\ST\FlashSTM32F10x.d79出处:jessemok。

STM32测试程序ADC+DMA+串口发送。全代码奉献(操作寄存器)

STM32测试程序ADC+DMA+串口发送。全代码奉献(操作寄存器)

STM32测试程序ADC+DMA+串⼝发送。

全代码奉献(操作寄存器)在参考⽹站上的例⼦(那个例⼦定义的数组为U8,这个很头痛)和⾃⼰的努⼒终于完成了ADC+DMA+串⼝发送的测试程序。

这个在我的项⽬的⽤到的。

现在和⼤家分享我的成果。

其实这个论坛上也有这样的例⼦,只是都是不全的,也没有很强的针对性。

不过他们已经完成了⼀些参数的设计,所以值得参考,我⾃⼰的程序是针对ADC+DMA+串⼝发送⽽设计,对初学者来说会很有帮助。

本程序在ALIENTEK MiniSTM32开发板上验证。

参考本论坛的资料 #include"stm32f10x_lib.h" #include "sys.h" #include "delay.h"#define USART1_DR_Base 0x40013804 #define ADC1_DR_Address 0x4001244C//0x40012400+0x4C//#define DMA1_MEM_ADD (u32)ADC_Buf //#define DMA1_MEM_SIZE(u32)sizeof(ADC_Buf) u16 ADC_Buf[512];void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx);//配置DMA1_CHx voidMYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);//使能DMA1_CHx voidMYDMA_GOnes(DMA_Channel_TypeDef*DMA_CHx); //执⾏⼀次DMA void adc_init(void) ;void USART_Initaize(u32 pclk2,u32 bound); void Uart1_PutChar(u8 ch); voidUart1_PutString(u8 *Buf, u8 Len);//主函数的内容: int main(void) { u16 times=0; u16 t; u32 temp =0; u16 adcx; u8 table[5]; u8*p; p= table; Stm32_Clock_Init(9);//88M delay_init(72); //延时初始化USART_Initaize(72,9600); //设置波特率 adc_init(); while (1) { if(DMA1->ISR&(1<<1)) //传输完成了 { times++; for(t=0;t<5;t++) { temp = temp + ADC_Buf[t]; } temp =temp /5; adcx=temp*330/4096;; table[0]=adcx / 100 + 0x30; table[1]='.'; table[2]=adcx% 100/10 + 0x30; table[3]= adcx %10 + 0x30; table[4]='V'; Uart1_PutString(p,5);Uart1_PutString("\r\n",2); temp =0; DMA1->IFCR|=1<<1;MYDMA_GOnes(DMA1_Channel1); } } } void adc_init(void) {RCC->APB2ENR|=1<<2; //使能PORTA⼝时钟 GPIOA->CRL&=0XFFFFFFF0;//PA.0anolog输⼊ //通道10/11设置 RCC->APB2ENR|=1<<9; //ADC1时钟使能 __nop();__nop(); RCC->APB2RSTR|=1<<9; //ADC1复位 RCC->APB2RSTR&=~(1<<9);//复位结束 RCC->CFGR|=3<<14; //SYSCLK/DIV2=88M/8=11Mhz 得到ADC采样率位43.65KhzADC1->CR1&=0XF0FFFF; //独⽴⼯作模式 ADC1->CR1|=1<<8; //扫描模式 ADC1->CR2|=1<<1; //连续转换模式 ADC1->CR2|=0x000E0000; //软件控制转换由bit21控制ADC1->CR2|=1<<20; //使⽤⽤外部触发(SWSTART) 必须使⽤⼀个事件来触发 ADC1->CR2&=~(1<<11); //右对齐ADC1->SQR1&=0xFFF0FFFF;//1个转换在规则序列中 ADC1->SQR3&=0XFFFFFFE0;//规则序列1=通道0 ADC1->SQR3|=0; ADC1->SMPR2|=0X07; //通道0的转换时间为:239.5+12.5个ADC时钟周期 ADC1->CR2|=1<<0; //开启AD转换器,第⼀次唤醒AD转换器 ADC1->CR2|=1<<3; //使能复位校准 while(ADC1->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//等待ADC1校准完成
while(ADC_GetCalibrationStatus(ADC1));
//使能ADC1软件开始转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
//配置ADC时钟=PCLK2 1/6 12MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//开启DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//配置DMA中断
NVIC_Config();
//设置DMA源:地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1 -> DR;
uint32_t SendBuff;
extern float ADC_Received;
extern uint8_t ADC_Received2[11];
//描述:DMA串口的初始化配置
void DMA_Config(void)
{
//初始化结构体
DMA_InitTypeDef DMA_InitStructure;
ADC_Received1 = ADC_Received * 1000000000;
ADC_Received2[0]=(ADC_Received1/1000000000 + 0x30);
//usart_putchar(0x2e);
ADC_Received2[1]=(ADC_Received1%1000000000/100000000 + 0x30);
uint32_t ADC_Received1;
uint8_t ADC_Received2[11];
//printf函数重新定向,方便在程序中使用
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (unsigned char) ch);
while (!(USART1->SR & USART_FLAG_TXE));
ADC_Received2[5]=(ADC_Received1%1000000000%100000000%10000000%1000000%100000/10000 + 0x30);
ADC_Received2[6]=(ADC_Received1%1000000000%100000000%10000000%1000000%100000%10000/1000 + 0x30);
ADC_Received2[9]=(ADC_Received1%10 + 0x30);
ADC_Received2[10]=0x0d;
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
//delay_ms(1000);
//USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);
//while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
//usart_putchar('\r');
//usart_putchar('\n');
//usart_putchar(0x0d);
//usart_putchar(0x0a);
//printf("\r");
//printf("\n");
//printf("\r\n V = %fv\r\n",ADC_Received);
}
}
#include "ADC1.h"
void ADC1_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_Received2[7]=(ADC_Received1%1000000000%100000000%10000000%1000000%100000%10000%1000/100 + 0x30);
ADC_Received2[8]=(ADC_Received1%1000000000%100000000%10000000%1000000%100000%10000%1000%100/10 + 0x30);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA , &GPIO_InitStructure);
}
#include "DMA1.h"
/*其他函数里USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);*/
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;;//ADC转换工作在连续模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//由软件控制转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换数据右对齐
//*内存地址(要传输的变量的指针)
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_Received2;
ADC_Received2[2]=(ADC_Received1%1000000000%100000000/10000000 + 0x30);
ADC_Received2[3]=(ADC_Received1%1000000000%100000000%10000000/1000000 + 0x30);
ADC_Received2[4]=(ADC_Received1%1000000000%100000000%10000000%1000000/100000 + 0x30);
//*DMA模式:一次传输/循环
//DMA_Mode_Circular工作在循环缓存模式
// DMA_Mode_Normal工作在正常缓存模式
// DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
ADC_InitStructure.ADC_NbrOfChannel = 1;//转换通道为通道1
ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC
//ADC1选择信道0,顺续等级1,采样时间239.5个周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5);
//*内存地址(要传输的变量的指针)
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&SendBuff;
//外设作为数据传输的来源
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//指定DMA通道的DMA缓存的大小,单位为数据单位。
ADC1_Gpio_Config();
ADC_DeInit(ADC1); //复位ADC1,将外设ADC1的全部寄存器重设为缺省值
// ADC1配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC1工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;//使能扫描
return (ch);
}
void usart_putchar(uint8_t ch)
{
USART_SendData(USART1,ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}
int main()
{
ADC1_Config();
//****************************************************///
//****************************************************///
//设置DMA源:地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1 -> DR;
DMA_InitStructure.DMA_BufferSize = 1;
//*外设地址不增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//*内存地址不增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_Config();
USART1_Config();
while(1)
{
//ADC_Received = (float)ADC_GetConversionValue(ADC1)*3.3/4069;
//ADC_Received1 = ADC_Received * 1000000000;
相关文档
最新文档