采用RK2206芯片的ADC按键设计 含ADC驱动程序设计

采用RK2206芯片的ADC按键设计 含ADC驱动程序设计,第1张

  一、简介

  在嵌入式系统产品开发中,按键板的设计是最基本的,也是项目评估阶段必须要考虑的问题。其实现方式有很多种,具体使用那一种就需要结合可用IO数量,并综合考虑成本,做出最终选择。传统的按键检测方法是一个按键对应一个GPIO口,进行高低电平输入检测。可是在GPIO口紧缺的情况下,不得不需要一个有效的解决方案,其中ADC检测实现按键功能是一种相对有效的解决方案。

  ADC检测实现简单实用的按键方法:仅需要一个ADC和若干个电阻就可实现多个按键的输入检测。工作原理:按下按键时,通过电阻分压得到不同的电压值,ADC采集在各个范围内的值来判定是哪个按键按下。

  本文采用RK2206芯片自带的逐次逼近寄存器模数转换器(Successive-ApproximaTIon Analog to Digital Converter),是一种常用的A/D转换结构,其较低的功耗表现,不错的转换速率,在有低功耗要求(可穿戴设备、物联网)的数据采集场景下广泛应用。

  二、硬件电路设计

  ADC检测实现简单实用的按键方法:仅需要一个ADC和若干个电阻就可实现多个按键的输入检测。工作原理:按下按键时,通过电阻分压得到不同的电压值,ADC采集在各个范围内的值来判定是哪个按键按下。

  模块整体硬件电路如下图所示,电路中包含了1根ADC引脚和4个按键。

  

采用RK2206芯片的ADC按键设计 含ADC驱动程序设计,采用RK2206芯片的ADC按键设计,第2张

 

  图1 硬件电路图

  其中,4个按键分别连接不同的电阻。当按键按下时,USER_KEY_ADC检测到不同的电压。具体如下所示:

  表1 按键对应电压表

  

采用RK2206芯片的ADC按键设计 含ADC驱动程序设计,采用RK2206芯片的ADC按键设计,第3张

 

  USER_KEY_ADC引脚连接到RK2206芯片的GPIO0_C5,如下图所示:

  

采用RK2206芯片的ADC按键设计 含ADC驱动程序设计,采用RK2206芯片的ADC按键设计,第4张

 

  图2 USER_KEY_ADC引脚的硬件电路图

  三、ADC接口

  ADC相应接口头文件在:

  /device/rockchip/rk2206/adapter/include/lz_hardware.h

  RK2206芯片提供以下两大类接口:

  (1)初始化、销毁ADC;

  (2)ADC读 *** 作。

  具体接口如PPT所示。以下我们详细讲解这些接口。

  (1)LzSaradcInit

  该函数主要功能是SARADC设备初始化。

  int LzSaradcInit(void);

  成功返回LZ_HARDWARE_SUCCESS, 其余为失败。

  (2)LzSaradcDeinit

  该函数主要功能是SARADC设备释放。

  int LzSaradcDeinit(void);

  成功返回LZ_HARDWARE_SUCCESS, 其余为失败。

  (3)LzSaradcReadValue

  该函数主要功能是SARADC设备读取。

  int LzSaradcReadValue(unsigned int chn, unsigned int *val);

  参数chn:ADC通道id;

  参数val:读取值。

  成功返回LZ_HARDWARE_SUCCESS, 其余为失败。

  四、程序设计

  ADC按键程序每1秒通过GPIO0_PC5读取一次按键电压,通过电压数值判断当前是哪个按键被按下,并打印出该按键名称。

  如图所示为ADC按键主程序流程图,开机LiteOS系统初始化后,进入主程序先初始化ADC设备。程序进入主循环,1秒获取一次ADC采样电压,判断:

  (1)采样电压在0.00~0.11V之间,则当前是按下Key1,打印Key1;

  (2)采样电压在0.45~0.65V之间,则当前是按下Key2,打印Key2;

  (3)采样电压在0.90~1.1V之间,则当前是按下Key3,打印Key3;

  (4)采样电压在1.55~1.75V之间,则当前是按下Key4,打印Key4;

  (5)当前无按键。

  

采用RK2206芯片的ADC按键设计 含ADC驱动程序设计,采用RK2206芯片的ADC按键设计,第5张

 

  图3 主程序流程图

void adc_process()
{
    float voltage;

    /* 初始化adc设备 */
    adc_dev_init();
    
    while (1)
    {
        printf("***************Adc Example*************\r\n");
        /*获取电压值*/
        voltage = adc_get_voltage();
        printf("vlt:%.3fV\n", voltage);

        if ((0.11 >= voltage) && (voltage >= 0.00))
        {
            printf("\tKey1\n");
        }
        else if ((0.65 >= voltage) && (voltage >= 0.45))
        {
            printf("\tKey2\n");
        }
        else if ((1.1 >= voltage) && (voltage >= 0.9))
        {
            printf("\tKey3\n");
        }
        else if ((1.75 >= voltage) && (voltage >= 1.55))
        {
            printf("\tKey4\n");
        }

        /* 睡眠1秒 */
        LOS_Msleep(1000);
    }
} 

  ADC初始化程序主要分为ADC初始化和配置ADC参考电压为外部电压两部分

staTIc unsigned int adc_dev_init()
{
    unsigned int ret = 0;
    uint32_t *pGrfSocCon29 = (uint32_t *)(0x41050000U + 0x274U);
    uint32_t ulValue;

    ret = DevIoInit(m_adcKey);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Key IO Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }
    ret = LzSaradcInit();
    if (ret != LZ_HARDWARE_SUCCESS) {
        printf("%s, %s, %d: ADC Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
}

    /* 设置saradc的电压信号,选择AVDD */
    ulValue = *pGrfSocCon29;
    ulValue &= ~(0x1 << 4);
    ulValue |= ((0x1 << 4) << 16);
    *pGrfSocCon29 = ulValue;
    
    return 0;
} 

  RK2206芯片采用一种逐次逼近寄存器型模数转换器(Successive-ApproximaTIon Analog to Digital Converter),是一种常用的A/D转换结构,其较低的功耗表现,还不错的转换速率,在有低功耗要求(可穿戴设备、物联网)的数据采集场景下广泛应用。该ADC采用10bit采样,最高电压为3.3V。简而言之,ADC采样读取的数据,bit[0~9]有效,且最高数值0x400(即1024)代表实际电压差3.3V,也就是说1个数值等于3.3V / 1024 = 0.003222V

staTIc float adc_get_voltage()
{
    unsigned int ret = LZ_HARDWARE_SUCCESS;
    unsigned int data = 0;

    ret = LzSaradcReadValue(ADC_CHANNEL, &data);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Read Fail\n", __FILE__, __func__, __LINE__);
        return 0.0;
}

return (float)(data * 3.3 / 1024.0);
}

  五、编译过程

  1、打开sdk下面路径的文件

  /vendor/lockzhiner/rk2206/samples/b1_adc/adc_example.c

  注意:Gitee上的ADC案例为通用案例,请大家根据上述的需求修改相关源代码。

  2、修改编译脚本

  修改 vendor/lockzhiner/rk2206/sample 路径下 BUILD.gn 文件,指定 adc_example 参与编译。

  “./b0_adc:adc_example”,

  修改 device/lockzhiner/rk2206/sdk_liteos 路径下 Makefile 文件,添加 -ladc_example 参与编译。

  hardware_LIBS = -lhal_iothardware -lhardware -ladc_example

  3、编译固件

hb set -root .
hb set
hb build -f

  4、烧写固件

  5、通过串口查看结果

  运行结果

***************Adc Example*************
vlt:3.297V
***************Adc Example*************
vlt:3.297V
***************Adc Example*************
vlt:3.297V
***************Adc Example*************
vlt:3.297V
***************Adc Example*************
vlt:3.297V
***************Adc Example*************
vlt:3.297V
……

  好了,今天的课程就到这里,更多技术干货请关注福州市凌睿智捷电子有限公司(凌智电子),持续更新中…

  审核编辑:汤梓红

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/dianzi/2425099.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-02
下一篇 2022-08-02

发表评论

登录后才能评论

评论列表(0条)

保存