发新帖我要提问
12
返回列表
打印
[应用相关]

STM32 ADC 电压输出

[复制链接]
楼主: chenqiang10
手机看帖
扫描二维码
随时随地手机跟帖
21
chenqiang10|  楼主 | 2018-5-28 19:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
每个 GPIO 口都有对应的通道的,我 们可以通过下表来选择相应的通道。


使用特权

评论回复
22
chenqiang10|  楼主 | 2018-5-28 19:37 | 只看该作者
我们三个 ADC 通道分别是 PA1,PB0,PB1。所以对应通道 0、通道 8、 通道 9。
第三个参数选择采样周期的设置的,一般来说 AD 采样时间是需要时间 的, STM32
的 AD 最大转换速率是 1us, 所以这里设置的时候, 不要小于 1us, 否则会导致结
果误差大。那么怎么设置呢?比如说,我们设置的采样周期为 1.5 个周期,而我们的 AD
频率为 14MHZ。 (这个频率是通过上面说设置分 频得到的。) 那么我们的转换时间
是多少呢?那么 AD 转换一次所需要的总 的周期数为 1.5 + 12.5 = 14。这个 1.5 就是
我们设置的采样周期,而这个 12.5 是固定的必须加的,它是基础时间。那么我们就可
以很轻易算出,在 14MHZ 的频率下, 14 个周期的时间就是 1us。 而我们上面设置
的时钟频率为 12MHZ, 我们设置的分频呢,就不这么讲究了,只要不要少于 1us 就行,
所以我们设 置最大的采样周期:ADC_SampleTime_239Cycles5。

使用特权

评论回复
23
chenqiang10|  楼主 | 2018-5-28 19:51 | 只看该作者
开始转换。
我们使用的是软件触发功能,所以要软件开启转换。
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的 ADC1 的软件转换功能

使用特权

评论回复
24
chenqiang10|  楼主 | 2018-5-28 19:56 | 只看该作者
等待转换完成,并读取转换结果。
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
读取转换结果可以使用 ADC_GetConversionValue()函数,它返回最后一 次规则转换结
果。它有一个参数,用来选择读取哪个 ADC 的转换结果。我 们设置为:ADC1。

使用特权

评论回复
25
changle11sdo5| | 2018-5-28 19:58 | 只看该作者
不错,有时间继续写其它的

使用特权

评论回复
26
chenqiang10|  楼主 | 2018-5-28 21:28 | 只看该作者
电路设计


本设计是将电位器输出端接到单片机的 PA1 管脚上,也就是通过 ADC1 的通
道 1 进行 AD 转换。因此除了需要对 ADC 进行初始化外还需要对 PA1 端口进行配置。

使用特权

评论回复
27
chenqiang10|  楼主 | 2018-5-28 21:28 | 只看该作者
void adc_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Per
iph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12M 最大 14M 设置 ADC 时钟(ADCCLK)
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//ADC
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //模拟输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
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);
//设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);//重置指定的 ADC 的校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));//获取 ADC 重置校准寄存器的状态
ADC_StartCalibration(ADC1);//开始指定 ADC 的校准状态
while(ADC_GetCalibrationStatus(ADC1));//获取指定 ADC 的校准程序
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的 ADC 的软件转换启
动功能
}

使用特权

评论回复
28
chenqiang10|  楼主 | 2018-5-28 21:28 | 只看该作者
adc_init();  //ADC 初始化
printf_init(); //printf 初始化
while(1)
{
ad=0;
for(i=0;i<50;i++)//读取 50 次的 AD 数值取其平均数较为准确
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//转换结束标志位
ad=ad+ADC_GetConversionValue(ADC1);//返回最近一次 ADCx 规则组的转换结

}
ad=ad/50;
printf("ad=%fV\n",ad*3.3/4096);
delay_ms(1000);
}

使用特权

评论回复
29
chenqiang10|  楼主 | 2018-5-28 21:29 | 只看该作者
主程序的效果是,读取到的 AD 值通过 printf 输出打印到串口助手上。

使用特权

评论回复
30
chenqiang10|  楼主 | 2018-5-28 21:30 | 只看该作者

串口助手显示读取的电压值。

使用特权

评论回复
31
chenqiang10|  楼主 | 2018-5-28 21:31 | 只看该作者
changle11sdo5 发表于 2018-5-28 19:58
不错,有时间继续写其它的

有时间接着分享。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则