如果有不会接线的可以参考上篇博客,电压输入采用ADC1的A5口,采集信号输出采用PF9,代码如下
gp2y.c
#include "gp2y.h"
#include "stm32f4xx.h"
static GPIO_InitTypeDef GPIO_InitStructure;
static ADC_InitTypeDef ADC_InitStructure;
static ADC_CommonInitTypeDef ADC_CommonInitStructure;
void gp2y_init(void)
{
//ADC模拟输入
//端口A时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
//ADC1硬件时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
//配置PA5引脚为模拟信号模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //第5个引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟信号模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //引脚的工作速度,速度越快,功耗越高
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不需要上下拉电阻
GPIO_Init(GPIOA, &GPIO_InitStructure); //配置端口
//配置ADC1相关参数
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立工作模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //ADC的工作频率=84MHz/2=42MHz
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //禁止DMA(直接存储访问)
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样点之间相隔时间=5*(1/42MHz)
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12bit精度,精度越高,数值越准确,但是会更耗时间
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描单个通道
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续扫描
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//不使用脉冲来让ADC1工作
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐存储转化结果值
ADC_InitStructure.ADC_NbrOfConversion = 1; //当前转换通道数目为1
ADC_Init(ADC1, &ADC_InitStructure);
//使能ADC1通道5工作,转换的先后顺序为1,对某个点的采样时间3*(1/42MHz)
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);
//使能ADC1硬件
ADC_Cmd(ADC1, ENABLE);
//模拟输出
//使能端口F的硬件时钟,说白了就是上电
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
//中断优先级分组2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//配置PF9为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //第9个引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式,才可以输出电流
//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //[可选]推挽输出模式,增加输出电流,但是也会增加功耗
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //引脚的工作速度,速度越快,功耗越高
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不需要上下拉电阻
GPIO_Init(GPIOF, &GPIO_InitStructure); //配置端口F
}
void get_PM(u8 *PM)
{
uint32_t adc_val=0;
//初始化
gp2y_init();
//启动ADC1开始转换
ADC_SoftwareStartConv(ADC1);
//等待转换完毕
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
GP2Y_Low;
delay_us(280);
//获取转换结果值
adc_val= ADC_GetConversionValue(ADC1);
delay_us(40);
GP2Y_High;
delay_us(9680);
*PM = 0.17 * adc_val-0.1;
delay_ms(1000);
}
注:这里*PM=0.17 * adc_val-0.1的公式是借鉴来的,不保证准确,如果需要的话可以采取adc_vol = 3300*adc_val/4095;将AD值转换为电压值再进行计算
gp2y.h
#ifndef __GP2Y_H__
#define __GP2Y_H__
#include "sys.h"
#include "stm32f4xx.h"
#include "delay.h"
#define GP2Y_High GPIO_SetBits(GPIOF,GPIO_Pin_9);
#define GP2Y_Low GPIO_ResetBits(GPIOF,GPIO_Pin_9);
void gp2y_init(void);
void get_PM(u8 *pm);
#endif