发新帖我要提问
12
返回列表
打印
[其他ST产品]

怎样用STM32 ADC测量电压(中断方式)

[复制链接]
楼主: 是你的乱码
手机看帖
扫描二维码
随时随地手机跟帖
21
是你的乱码|  楼主 | 2023-1-15 19:34 | 只看该作者 回帖奖励 |倒序浏览
大致步骤如下:

1-初始化ADC用到的GPIO
2-初始化ADC初始化结构体,数字时钟。
3-配置ADC模拟时钟,配置通道的转换顺序和采样时间
4-使能ADC转换完成中断,配置中断优先级,初始化校准寄存器并等待校准完成。

使用特权

评论回复
22
是你的乱码|  楼主 | 2023-1-15 19:34 | 只看该作者
//定义ADC2中断函数
#define    ADC_IRQHandler                ADC1_2_IRQHandler

// 定义一个变量存放ADC转换值
__IO uint16_t ADC2_Value;


// 定义变量,用于保存转换计算后的电压值          
float ADC_Vol;        

static void ADC2_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        // 因为用的PC1,因此需要打开GPIOC的时钟
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
       
        // 配置 ADC IO 引脚模式为模拟输入
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
       
        // 初始化 ADC IO
        GPIO_Init(GPIOC, &GPIO_InitStructure);                               
}




static void ADC2_Mode_Config(void)
{
        ADC_InitTypeDef ADC_InitStructure;       

        // 打开ADC2数字时钟
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_ADC2, ENABLE );
       
        // ADC 模式配置
        // 只使用一个ADC2,属于独立模式
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
       
        // 禁止扫描模式,多通道才要,单通道不需要
        ADC_InitStructure.ADC_ScanConvMode = DISABLE ;

        // 连续转换模式
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

        // 不用外部触发转换,软件开启即可
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

        // 转换结果右对齐
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
       
        // 转换通道1个
        ADC_InitStructure.ADC_NbrOfChannel = 1;       
               
        // 初始化ADC2
        ADC_Init(ADC2, &ADC_InitStructure);
       
        // 配置ADC2模拟时钟为PCLK2的8分频,72/8 即9MHz
        RCC_ADCCLKConfig(RCC_PCLK2_Div8);
       
        // 配置 ADC2 通道转换顺序和采样时间
        ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1,
                                 ADC_SampleTime_55Cycles5);
       
        // ADC2 转换结束产生中断,在中断服务程序中读取转换值
        ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);
       
        // 开启ADC2 ,并开始转换
        ADC_Cmd(ADC2, ENABLE);
       
        // 初始化ADC2 校准寄存器  
        ADC_ResetCalibration(ADC2);
        // 等待校准寄存器初始化完成
        while(ADC_GetResetCalibrationStatus(ADC2));
       
        // ADC2开始校准
        ADC_StartCalibration(ADC2);
        // 等待校准完成
        while(ADC_GetCalibrationStatus(ADC2));
       
        // 由于没有采用外部触发,所以使用软件触发ADC2转换
        ADC_SoftwareStartConvCmd(ADC2, ENABLE);
}



static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
        // 优先级分组
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void ADC2_IRQHandler(void)
{       
        if (ADC_GetITStatus(ADC2,ADC_IT_EOC)==SET)
        {
                // 读取ADC的转换值
                ADC2_Value = ADC_GetConversionValue(ADC2);
        }
        ADC_ClearITPendingBit(ADC2,ADC_IT_EOC);
}

void ADC2_Init(void)
{
        ADC2_GPIO_Config();
        ADC2_Mode_Config();
        ADC_NVIC_Config();
}

int main(void)
{       
        // 配置串口 此函数请自行实现
        USART_Config();
       
        // ADC2 初始化
        ADC2_Init();
       
       
       
        while (1)
        {
                ADC2_Vol =(float) ADC2_Value/4096*3.3; //  2^12=4096
       
                printf("\r\n The current AD value = 0x%04X \r\n",
                       ADC2_Value);
                printf("\r\n The current  voltage = %f V \r\n",
                       ADC2_Vol);
                printf("\r\n\r\n");

                Delay(0xffffee);  //  此函数请自行实现
        }
}

使用特权

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

本版积分规则