从上图可以看到注入通道有4个,规则通道有16个,在这里规则通道类似于程序从上往下跑是有顺序的去检查通道的值而注入通道类似于中断是可以打断规则通道先检测注入通道的值的。
从图中我们也可以知道规则通道和注入通道的标志位不同
从图的下半部分我们知道ADC是可以使用定时器的并且需要分频(分频之后最好不要超过32Mhz不然会不准确)
下面是ADC的通道表
ADC可以单次、连续、扫描、间断转换,单次转换是每次转换结束之后可以产生中断和设置标志,连续转换是当全部都转换完成后才可以产生中断设置标志位,扫描模式是把该组所有通道都扫描那么本次使用的是单次转换。
配置ADC的步骤
- 使能对应的GPIO口,使能ADC
- 配置GPIO口为模拟输入
- 配置ADC_CommonInitTypeDef结构体(通用配置结构体)
- 配置ADC_InitTypeDef结构体(配置结构体)
- 使能配置
获取值的步骤
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles ); //ADC1,ADC通道,480个周期,提高采样时间可以提高精确度
ADC_SoftwareStartConv(ADC1); //使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果 |
完整代码
//初始化SR505 PA1 输入 使能ADC1 通道1 void SR505_Init(void) { //重定义结构体名称 GPIO_InitTypeDef GPIO_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; //使能GPIOA 使能ADC1 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //GPIOA_Pin1配置成模拟输入模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PA1 通道5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位 RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束 ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;//独立模式 ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;//不需要DMA ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;//采样周期之间延迟5个时钟 ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//APB2的频率是84/4=21 不超过32 ADC_CommonInit(&ADC_CommonInitStructure);//初始化 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化 ADC_Cmd(ADC1, ENABLE);//开启AD转换器 } //获得ADC值 //ch: @ref ADC_channels //通道值 0~16取值范围为:ADC_Channel_0~ADC_Channel_16 //返回值:转换结果 u16 Get_SR505_Adc(u8 ch) { //设置指定ADC的规则组通道,一个序列,采样时间 ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles ); //ADC1,ADC通道,480个周期,提高采样时间可以提高精确度
ADC_SoftwareStartConv(ADC1); //使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果 } //获取通道ch的转换值,取times次,然后平均 //ch:通道编号 //times:获取次数 //返回值:通道ch的times次转换结果平均值 u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t; for(t=0;t<times;t++) { temp_val+=Get_SR505_Adc(ch); delay_ms(5); } return temp_val/times; } |