即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

STM32:ADC采集数据实例(采用DMA模式)

编程语言 sinat_36184075 11℃ 0评论

硬件平台:stm32f10xZET6


开发环境:keil MDK uVision v4.10


开发语言:C、ST_lib_3.5固件库





将STM32 开发板供电(DC5V),插上 JLINK,插上串口线(两头都是母的交叉线),打开超级终端,配置超级终端为 115200 8-N-1,将编译好的程序下载到开发板,即可看到超级终端打印数字信息显示电压值。


当旋转开发板开发板上的滑动变阻器时, ADC1 转换的电压值则会改变。板载的是 20K 的精密电阻,旋转的圈数要多点才能看到 ADC 值的明显变化。




/* 代码演示 main.c */
#include "stm32f10x.h"
#include "bsp_usart1.h"
#include "bsp_adc.h"

// ADC1转换的电压值通过MDA方式传到SRAM
extern __IO uint16_t ADC_ConvertedValue;

// 局部变量,用于保存转换计算后的电压值   
float ADC_ConvertedValueLocal;        

// 软件延时
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
} 

/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{ 
 /* USART1 config */
 USART1_Config();
 
 /* enable adc1 and config adc1 to dma mode */
 ADC1_Init();
 
 printf("\r\n ----这是一个ADC实验(DMA传输)----\r\n");
 
 while (1)
 {
  ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3; // 读取转换的AD值
 
  printf("\r\n The current AD value = 0x%04X \r\n", ADC_ConvertedValue); 
  printf("\r\n The current AD value = %f V \r\n",ADC_ConvertedValueLocal); 

  Delay(0xffffee);  
 }
}
/* 代码演示 bsp_adc模块 */
#ifndef __ADC_H
#define __ADC_H

#include "stm32f10x.h"
void ADC1_Init(void);

#endif /* __ADC_H */
//---------------------------------------------------------
/**
  ******************************************************************************
  * @file    bsp_adc.c
  ******************************************************************************
  */ 
  
#include "bsp_adc.h"

#define ADC1_DR_Address    ((u32)0x40012400+0x4c)

__IO uint16_t ADC_ConvertedValue;
//__IO u16 ADC_ConvertedValueLocal;

/**
  * @brief  使能ADC1和DMA1的时钟,初始化PC.01
  * @param  无
  * @retval 无
  */
static void ADC1_GPIO_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 
 /* Enable DMA clock */
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
 /* Enable ADC1 and GPIOC clock */
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
 
 /* Configure PC.01  as analog input */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
 GPIO_Init(GPIOC, &GPIO_InitStructure);    // PC1,输入时不用设置速率
}

/**
  * @brief  配置ADC1的工作模式为MDA模式
  * @param  无
  * @retval 无
  */
static void ADC1_Mode_Config(void)
{
 DMA_InitTypeDef DMA_InitStructure;
 ADC_InitTypeDef ADC_InitStructure;
 
 /* DMA channel1 configuration, 参数传递基地址宏 */
 DMA_DeInit(DMA1_Channel1);
 
 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;         // ADC地址
 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;         // 内存地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                          // 指定外设是数据源地址或数据目的地址
 DMA_InitStructure.DMA_BufferSize = 1;                                       // 指定缓冲区大小为1个数据单元大小,其值等于外设或内存配置的大小
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;         // 外设地址固定
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;          // 内存地址固定
 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通道的软件优先级
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                // 指定DMA通道是否使用内存到内存的传输方式

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
 /* Enable DMA channel1 */
 DMA_Cmd(DMA1_Channel1, ENABLE);
 
 /* ADC1 configuration */ 
 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;               // 独立ADC模式
 ADC_InitStructure.ADC_ScanConvMode = DISABLE ;               // 禁止扫描模式,扫描模式用于多通道采集
 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;               // 开启连续转换模式,即不停地进行ADC转换
 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;     // 不使用外部触发转换
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                  // 采集数据右对齐
 ADC_InitStructure.ADC_NbrOfChannel = 1;          // 要转换的通道数量1个
 ADC_Init(ADC1, &ADC_InitStructure);
 
 /*配置ADC时钟,为PCLK2的8分频,即9MHz*/
 RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
 /*配置ADC1的通道11为55. 5个采样周期,序列为1 */ 
 ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
 
 /* Enable ADC1 DMA */
 ADC_DMACmd(ADC1, ENABLE);
 
 /* Enable ADC1 */
 ADC_Cmd(ADC1, ENABLE);

        /* ADC的自校准,在开始ADC转换之前需要启动自校准 */ 
 ADC_ResetCalibration(ADC1);                     // 复位校准寄存器
 while(ADC_GetResetCalibrationStatus(ADC1));     // 等待校准寄存器复位完成
 ADC_StartCalibration(ADC1);                     // ADC校准
 while(ADC_GetCalibrationStatus(ADC1));          // 等待校准完成
 
 /* 由于没有采用外部触发,所以使用软件触发ADC转换 */ 
 ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

/**
  * @brief  ADC1初始化
  * @param  无
  * @retval 无
  */
void ADC1_Init(void)
{
 ADC1_GPIO_Config();
 ADC1_Mode_Config();
}








转载请注明:CodingBlog » STM32:ADC采集数据实例(采用DMA模式)

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情