1、开启 ADC1 的时钟,由于 ADC1 是在 PA1 上,所以同时也要打开 PA 的时钟,并进
行相关的配置、对于这个配置,要把 PA1 设置成模拟输入,为什么呢??大家打开中文参
考手册可以看到
啊哈、、这下子清楚了吧、
2、复位 ADC1,(本人觉得没必要、为什么,待会我会跟你说,留下悬念先),设置 ADC1
的分频因子,(记住,这里的 ADC 的时钟不能超过 14MHZ),而且其采样周期长点会好
点,
ADCCLK---最快可达 14MHz, 时钟来自经过分频器的 PCLK2(2、4、6、8 分频)
整个转换时间 = 采样时间 + 12.5 个周期(固定时间)
转换时间:1μs (14 个周期 cycles)� 在 14MHz 和采样时间位 1.5 周期时
当 ADCCLK=14MHz 和 1.5 周期的采样时间:
TCONV = 1.5 + 12.5 = 14 周期 = 14×(1 / (14 × 1000000)) = 1μs
其采样周期一览表:
涉及到采样周期、这里来看看转换序列:
最多达 16 个转换通道且可以采样不同的顺序排列,不同的采样时间和过采样的可能性。
例如:- 转换通道:1、2、8、4、7、3、11
- 不同的采样时间;
- Oversampling of channel 7。
3、初始化 ADC1 的参数、设置 ADC1 的工作模式和规则序列的相关信息;
大家通过打开"stm32f10.adc.h"可以看到:
typedef struct
{
uint32_t ADC_Mode; //设置 ADC 模式-->独立模式
FunctionalState ADC_ScanConvMode; //设置是否开启扫描模式 --->否
FunctionalState ADC_ContinuousConvMode; //设置是否开启连续转换模式
---->否
uint32_t ADC_ExternalTrigConv; //设置启动规则转换组转换模式
---->软件触发
uint32_t ADC_DataAlign; //设置数据对齐方式----->右对
齐
uint8_t ADC_NbrOfChannel; //设置规则序列的长度---->顺
序进行规则转换的 ADC 通道数目 1
}ADC_InitTypeDef;
4、使能 ADC 并校准
注:在设置完了以上信息后,使能 AD 转换器,执行复位校准和 AD 校准(这两步校准一定
要,否则数据将不准)
还有记住,每次进行校准之后都要等待校准结束,但是通过什么方式知道校准结束呢?
这里是通过获取校准状态来判断是否校准结束,相关的库函数请看代码
分别的库函数请看待会的代码。(请用比较老外的方式去看,也就是用英语啦,为什么
呢?请看下文)
5、读取 AD 的值
当然,这里说读取 AD 值并不是那么的简单,以上我们只是准备好了 AD,还没有设置相
关的规则序列通道,采样顺序,以及采样周期,设置完之后启动 AD 转换就行了、然后才直
接读取哈、、
相关的库函数请看代码、
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADC1 and GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA,
ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12MHZ
/* Configure PA.1 (ADC Channel) as analog input
-------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//ADC_DeInit(ADC1);//在这里复位被我注释掉了、至于为什么,我待会会
说
/* 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_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* Enable ADC1 *///知道我为啥要在上面提醒大家要用老外的方式来看了吧、
因为这里的注释都是用英文的
//请不要以为我装逼,我这样做是有原因的、、原因我待会会说、你也会明白
我最初的标题为何那样写
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
u16 Get_val(u8 ch)
{
u16 DataValue; //又是英文注释、、啊哈
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
/* Test if the ADC1 EOC flag is set or not */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
//FlagStatus Status;
//Status = ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC);
//while(!Status);---->这样做实现不了、请注意
/*Returns the ADC1 Master data value of the last converted channel*/
DataValue = ADC_GetConversionValue(ADC1);
return DataValue;
}
u16 ADC_Get_aveg(u8 ch,u8 n)
{
u32 ad_sum = 0;
u8 i;
for(i=0;i<n;i++)
{
ad_sum += Get_val(ch);
delay_ms(5);
}
评论0