一、国民技术芯片ADC采集配置
cpp
复制代码
/*
PA1 ADC1_IN2 默认功能
DMA 通道1由ADC1触发
外部晶振16 系统时钟144M AHB 2分频 HCLK=72M
HCLK 经APB1 4分频 pclk1 = 18M=HCLK/4
HCLK 经APB2 4分频 pclk2 = 18M=HCLK/4
ADCCLK不得超过14M
*/
void DMA_ADC_Config(void)
{
ADC_InitType ADC_InitStructure;
DMA_InitType DMA_InitStructure;
GPIO_InitType GPIO_InitStructure;
/* Enable peripheral clocks ------------------------------------------------*/
/* Enable DMA1 and DMA2 clocks */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1 , ENABLE);
/* Enable ADC1, ADC2, ADC3 and GPIOC clocks */
// RCC_EnableAPB2PeriphClk(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2_PERIPH_GPIOC, ENABLE);
/* Enable GPIOC clocks */ RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
/* Enable ADC1, ADC2, ADC3 and ADC4 clocks */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1,ENABLE);
/* RCC_ADCHCLK_DIV16 144/16 72/8*/
ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV8);
GPIO_InitStructure.Pin = GPIO_PIN_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_CH1);
DMA_InitStructure.PeriphAddr = (uint32_t)&ADC1->DAT;
DMA_InitStructure.MemAddr = (uint32_t)&ADCConvertedValue;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = 1;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_DISABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.CircularMode = DMA_MODE_CIRCULAR;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(DMA1_CH1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_EnableChannel(DMA1_CH1, ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT;
ADC_InitStructure.MultiChEn = ENABLE;
ADC_InitStructure.ContinueConvEn = ENABLE;
ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE;
ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R;
ADC_InitStructure.ChsNumber = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 配置ADC时钟分频因子 不超过14M 8分频得到
// 使用外部高速时钟
// RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV2);
/* ADC1 regular channel14 configuration */
//ADC_ConfigRegularChannel(ADC1, ADC_CH_2, 1, ADC_SAMP_TIME_55CYCLES5);
ADC_ConfigRegularChannel(ADC1, ADC1_Channel_02_PA1, 1, ADC_SAMP_TIME_55CYCLES5);
/* Enable ADC1 DMA */
ADC_EnableDMA(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Enable(ADC1, ENABLE);
/*Check ADC Ready*/
while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET);
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while (ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_EnableSoftwareStartConv(ADC1, ENABLE);
}
二、stm32 ADC采集
cpp
复制代码
// ADC多通道采集
void ADC_IN_x_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
// 使能ADC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
// ADC结构体配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式 ADC1/2/3/4只使用了一个
ADC_InitStructure.ADC_ScanConvMode = ENABLE; // 扫描模式
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE; // 连续转换(多次转换ENABLE) 一次转换(disable)
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; // 禁止触发检测、使用软件触发 ADC_ExternalTrigConv_None
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right; // 右对齐
ADC_InitStructure.ADC_NbrOfChannel=NOFCHANEL; // 2个转换在规则序列中
ADC_Init(ADC1,&ADC_InitStructure);
// 配置ADC时钟分频因子 不超过14M APB2=72M APB2 8分频得到
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
// 配置ADC通道的转换顺序和采样时间 Tconv = 采样时间 + 12.5 个周期 第三个参数为通道转换序列
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // 配置 ADC 通道转换顺序为 1,第一个转换,采样时间为 55.5 个时钟周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); // 配置 ADC 通道转换顺序为 2,第二个转换,采样时间为 55.5 个时钟周期
//ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); // ADC 转换结束产生中断,在中断服务程序中读取转换值
ADC_DMACmd(ADC1,ENABLE); // 使能ADC DMA请求
// 使能ADC并开始转换
ADC_Cmd(ADC1,ENABLE);
// 初始化并校准寄存器
ADC_ResetCalibration(ADC1);
// 等待校准寄存器初始化完成
while(ADC_GetResetCalibrationStatus(ADC1));
// ADC开始校准
ADC_StartCalibration(ADC1);
// 等待校准完成
while(ADC_GetCalibrationStatus(ADC1));
// 软件触发ADC转换,没有使用时外部触发
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
/*********************************************DMA配置*********************************************/
// 1、DMA_Chx DMA通道 2、Dpba 外设地址 3、Dmba 存储器地址 4、Dbse DMA通道的缓冲区大小
void DMA_Config(DMA_Channel_TypeDef* DMA_Chx,uint32_t Dpba,uint32_t Dmba,uint32_t Dbs)
{
DMA_InitTypeDef DMA_InitStructure;
// 使能时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 复位DMA控制器 DMA 通道复位
DMA_DeInit(DMA_Chx);
// 配置结构体
DMA_InitStructure.DMA_PeripheralBaseAddr=Dpba; // ADC数据寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr=Dmba; // 存储器地址 目标地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;// 数据传输方向:数据来源于外设
DMA_InitStructure.DMA_BufferSize=Dbs; // DMA缓冲区大小=数据目的地的大小
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工作模式 循环输出模式 正常工作模式DMA_Mode_Normal
DMA_InitStructure.DMA_Priority=DMA_Priority_High; // 优先级 DMA 传输通道优先级为高,当使用一个 DMA 通道时,优先级设置不影响
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 禁用内存到内存的传输模式 外设->内存
DMA_Init(DMA_Chx,&DMA_InitStructure);
DMA_Cmd(DMA_Chx,ENABLE);
}
初始化
cpp
复制代码
#define ADC_X_PIN GPIO_Pin_0
#define ADC_X_CHANNEL ADC_Channel_8
#define ADC_Y_PIN GPIO_Pin_1
#define ADC_Y_CHANNEL ADC_Channel_9
// ADC1 对应 DMA1 通道 1,ADC3 对应 DMA2 通道 5,ADC2 没有 DMA 功能
#define ADC_DMA_CHANNEL DMA1_Channel1
ext short int ADC_CollectValue[NOFCHANEL]; // 需要ADC转换的电压值
#define NOFCHANEL 2
void ADC_XY_Init(void)
{
// x(PA0)、y轴 引脚初始化 模拟输入 AD
// GPIOx_Config(RCC_APB2Periph_GPIOA,GPIOA,GPIO_Pin_0|GPIO_Pin_1,GPIO_Mode_AIN);
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; // 模拟输入
GPIO_Init(GPIOA,&GPIO_InitStructure);
// ADC配置
// Tconv = 采样时间 + 12.5 个周期 55.5+12.5 Tconver=(55.5+12.5)*1/9=7.55us
ADC_IN_x_Config();
//ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
// DMA配置 1、DMA通道 2、外设地址 3、存储器地址 4、缓冲区大小,应该等于数据目的地的大小
DMA_Config(ADC_DMA_CHANNEL,(u32)(&( ADC1->DR )),(u32)ADC_CollectValue,NOFCHANEL);
}