盼盼_dRglQm · 1月5日

【灵动Mini-F5265-OB】ADC之片内温度传感器与参考电压获取

【F5265ADC简介】
ADC 是 12 位的逐次逼近型(SAR)模拟数字转换器,可以将模拟信号转换成数字信号。ADC 有可测量内部或外部信号源,其中 ADC1 有 14 路外部输入通道,ADC2 有 17 路外部输入通道和 2 路内部通道。这些 ADC 的通道可以单次、单周期和连续进行转换。根据不同的方式又可以选择普通通道转换、任意通道转换。
ADC 的最大输入时钟为 48MHz,它是由 APB2 时钟(PCLK2)分频产生
【功能框图】
image.png
T_SENSOR(温度传感器)通道在 ADC2 的 AIN17 通道,V_SENSOR(内部参考电压)通道在ADC2 的 AIN18 通道。
本篇就是分享如何获取T_SENSOR(温度传感器)通道 与V_SENSOR(内部电压),并显示在LCD屏上。
【ADC配置与初始化】
根据示例中,代码初始化如下:

/***********************************************************************************************************************
  * @brief
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void ADC_Configure(void)
{
    ADC_InitTypeDef  ADC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);

    ADC_CalibrationConfig(ADC2, 0x1FE);

    ADC_StructInit(&ADC_InitStructure);
    ADC_InitStructure.ADC_Resolution       = ADC_Resolution_12b;
    ADC_InitStructure.ADC_Prescaler        = ADC_Prescaler_16;
    ADC_InitStructure.ADC_Mode             = ADC_Mode_Scan;
    ADC_InitStructure.ADC_DataAlign        = ADC_DataAlign_Right;
    ADC_Init(ADC2, &ADC_InitStructure);

    ADC_SampleTimeConfig(ADC2, ADC_Channel_TempSensor, ADC_SampleTime_240_5);
    ADC_SampleTimeConfig(ADC2, ADC_Channel_VoltReference, ADC_SampleTime_240_5);

    ADC_AnyChannelNumCfg(ADC2, 1);
    ADC_AnyChannelSelect(ADC2, ADC_AnyChannel_0, ADC_Channel_TempSensor);
    ADC_AnyChannelSelect(ADC2, ADC_AnyChannel_1, ADC_Channel_VoltReference);
    ADC_AnyChannelCmd(ADC2, ENABLE);

    ADC_TempSensorCmd(ENABLE);
    ADC_VrefSensorCmd(ENABLE);

    ADC_Cmd(ADC2, ENABLE);
}

1、使能 ADC 时钟:首先,使用 RCC_APB2PeriphClockCmd 函数使能 ADC2 的时钟,这是使用 ADC2 模块的前提。
2、ADC_CalibrationConfig(ADC2, 0x1FE); 在 ADC 初始化之前配置 ADC 校准时钟。PRECAL 必须为偶数,范围从 0 到 0x1FF。
3、接着配置,ADC为12位,16分频,单周期扫描模式,扫描结果右对齐模式。
4、配置两个转换通道、转换时间
5、配置adc 任何通道转换最大数量为1
6、配置从通道 17 和通道 18 的任何通道作为任何通道模式操作中的输入通道。
7、分别使能转换通道、开启温度、内部电压转换。
8、最后开启ADC2。
【温度转换】
在用户手册中有以下说明:
内置的温度传感器仅用来检测器件内部的温度变化(TA)。
因此需要先获取V25:
uint16_t OffsetT = (*(volatile uint32_t *)(0x1FFFF7FC) & 0xFFFF0000) >> 0x10;
T(℃)=(( Value VDDA- V25 3300) /(4096*Avg_Slope))+25
VDDA:ADC 当前采样时的 VDDA 电压,单位 mV
Value:ADC 的转换结果数据
Avg_Slope: 温度与电压曲线的平均斜率(以 mV/℃ 或 μV/℃ 表示)
采集温度并转换值如下:

        /* Internal temperature sensor */
        Value = ADC_GetAnyChannelConvertedValue(ADC2, ADC_AnyChannel_0);

        Temperature = 25 + ((float)Value * (float)Voltage * (float)1000 - (float)OffsetT * (float)3300) / ((float)4096 * (float)AVG_SLOPE);

【内部电压】
转换公式为:
Vref= (ADC_ADDR*3.3)/ 4096
获取代码为:

        /* Internal voltage sensor */
        Value = ADC_GetAnyChannelConvertedValue(ADC2, ADC_AnyChannel_1);

        Voltage = (float)(OffsetV) * (float)3.3 / (float)Value;

【获取电压、温度值代码】

/***********************************************************************************************************************
  * @brief
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void ADC_InternalTemperatureSensor_Sample(void)
{
    uint16_t Value;
        char lcd_buff[64];
    float Voltage, Temperature;

    uint16_t OffsetV = (*(volatile uint32_t *)(0x1FFFF7FC) & 0x0000FFFF) >> 0x00;
    uint16_t OffsetT = (*(volatile uint32_t *)(0x1FFFF7FC) & 0xFFFF0000) >> 0x10;

    printf("\r\nTest %s", __FUNCTION__);

    ADC_Configure();

    while (1)
    {
        ADC_SoftwareStartConvCmd(ADC2, ENABLE);

        while (RESET == ADC_GetFlagStatus(ADC2, ADC_FLAG_EOS))
        {
        }

        ADC_ClearFlag(ADC2, ADC_FLAG_EOS);

        /* Internal voltage sensor */
        Value = ADC_GetAnyChannelConvertedValue(ADC2, ADC_AnyChannel_1);

        Voltage = (float)(OffsetV) * (float)3.3 / (float)Value;

        /* Internal temperature sensor */
        Value = ADC_GetAnyChannelConvertedValue(ADC2, ADC_AnyChannel_0);

        Temperature = 25 + ((float)Value * (float)Voltage * (float)1000 - (float)OffsetT * (float)3300) / ((float)4096 * (float)AVG_SLOPE);

        printf("\r\nVDD : %0.2f, Temperature : %0.2f", Voltage, Temperature);
                sprintf(lcd_buff, "VDD:%.2fV",Voltage);
                LcdShowString(10,48,lcd_buff,WHITE,BLACK,16);
                sprintf(lcd_buff, "Temp:%.2f",Temperature);
                LcdShowString(10,64,lcd_buff,WHITE,BLACK,16);
        PLATFORM_DelayMS(500);
    }
}

【实验效果】
9f40f6c7eac580eb3da5181b03dee43.jpg

推荐阅读
关注数
0
文章数
11
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息