小凌派-RK2206开发板:ADC按键案例
liebian365 2025-01-02 17:42 21 浏览 0 评论
一、简介
在嵌入式系统产品开发中,按键板的设计是最基本的,也是项目评估阶段必须要考虑的问题。其实现方式有很多种,具体使用那一种就需要结合可用IO数量,并综合考虑成本,做出最终选择。传统的按键检测方法是一个按键对应一个GPIO口,进行高低电平输入检测。可是在GPIO口紧缺的情况下,不得不需要一个有效的解决方案,其中ADC检测实现按键功能是一种相对有效的解决方案。
ADC检测实现简单实用的按键方法:仅需要一个ADC和若干个电阻就可实现多个按键的输入检测。工作原理:按下按键时,通过电阻分压得到不同的电压值,ADC采集在各个范围内的值来判定是哪个按键按下。
本文采用RK2206芯片自带的逐次逼近寄存器型模数转换器(Successive-Approximation Analog to Digital Converter),是一种常用的A/D转换结构,其较低的功耗表现,不错的转换速率,在有低功耗要求(可穿戴设备、物联网)的数据采集场景下广泛应用。
二、硬件电路设计
ADC检测实现简单实用的按键方法:仅需要一个ADC和若干个电阻就可实现多个按键的输入检测。工作原理:按下按键时,通过电阻分压得到不同的电压值,ADC采集在各个范围内的值来判定是哪个按键按下。
模块整体硬件电路如下图所示,电路中包含了1根ADC引脚和4个按键。
其中,4个按键分别连接不同的电阻。当按键按下时,USER_KEY_ADC检测到不同的电压。具体如下所示:
序号 | 按键 | 电压(单位:V) |
1 | Key1 | 0.01 |
2 | Key2 | 0.55 |
3 | Key3 | 1.00 |
4 | Key4 | 1.65 |
表1 按键对应电压表
USER_KEY_ADC引脚连接到RK2206芯片的GPIO0_C5,如下图所示:
三、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)当前无按键。
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
……
好了,今天的课程就到这里,我们下次再见!
相关推荐
- python如何对字符串进行操作(python如何对字符串进行操作输出)
-
1.字符串的创建可通过直接赋值、构造或转义字符来创建字符串。#普通字符串s="Hello,World!"#多行字符串(使用三引号)multi_line_str='''Thisi...
- Excel表格中11个常用的字符串函数
-
今天和大家聊聊常用的字符串函数,在不同的条件下,如何选择字符串函数很关键。下面我为大家列举了11个关于字符串的函数公式。一、EXACT(两个字符串进行结果比较)比较两个字符串是否完全相同(这里是要区分...
- 详细介绍一下Python中如何对字符串进行操作?
-
在Python中,字符串做为一种常见的数据处理类型,几乎在每个应用程序中都会被用到。而作为Python中使用最广泛的数据类型Python也是提供了很多强大的方法来支持对于字符串的处理操作。下面我们就来...
- Java中你知道几种从字符串中找指定的字符的数量
-
遇到这样的问题,常规的思路估计就是遍历String,然后逐个对比。下面先看循环遍历循环遍历privatestaticintgetNum(StringoriginStr,Stringtarg...
- C语言strcspn函数详解:字符串的“扫雷探测器”
-
strcspn是C语言标准库中的一个函数,定义在头文件中。它用于计算从字符串的开始到首次出现任何属于指定字符集合的字符之间的字符数量。换句话说,strcspn计算的是主字符串中不包含指定字符集...
- 如何使用 Python 的 f-string 进行字符串格式化
-
Python中的字符串格式化曾经有点麻烦。必须在...
- java判断字符串中是否包含某个字符
-
1使用String类的contains()方法contains()方法用于判断字符串中是否包含指定的字符或字符串。语法如下:publicbooleancontains(CharSequence...
- Python基础:f-string不同数据类型的格式化选项,终极指南!
-
上一篇文章我们介绍了4种字符串格式化方法,其中最现代、最直观的方式是f-string,从Python3.6开始引入,而且时不时就增加一些超级优雅的小改进。今天,钢铁老豆想要继续给大家展开介绍不同数据...
- Excel查找指定字符串,返回相应的结果
-
通过下面的函数,可以实现查找指定字符串,若找到返回“有”,若找不到返回“无”。=IF(ISNUMBER(SEARCH("失业",G3)),"有","无")...
- 一个list中,有b.a.b.c.b.b.写个方法去掉所有b
-
importjava.util.ArrayList;importjava.util.List;publicclassRemoveBFromStringList{/**...
- 掌握Python f-string(掌握催眠能力之后的日常生活)
-
f-string,通常称为格式化字符串文本,是Python3.6中添加的一项强大功能,它提供了一种将表达式包含在字符串文本中的清晰实用的方法。,...
- 深入了解字符串:定义、转义字符和字符串下标
-
字符串是编程中常见的数据类型之一,用于表示文本信息。在绝大多数编程语言中,字符串都是由一系列字符组成的序列,可以包含字母、数字、符号以及空格等。字符串的定义:...
- 100个Java工具类之70:字符串处理工具类StringUtils
-
StringUtils是常用的工具类,提供大量处理字符串的静态方法。StringUtils主要特点...
- Shell中针对字符串的切片,截取,替换,删除,大小写操作
-
切片返回字符串变量var的长度...
- Sqlite - 常规函数 - RTRIM(sqlite命令行工具)
-
在SQLite中,RTRIM函数是一个用于处理字符串的函数,其主要作用是移除字符串右侧(尾部)的指定字符。如果不指定要移除的字符,默认会移除字符串右侧的空格字符。以下是对RTRIM函数的详细...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)