日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RK 利用SARADC 来做多个按键

發布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RK 利用SARADC 来做多个按键 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • #DTS配置

    • #配置DTS節點

    • #驅動文件中匹配 DTS 節點

  • #驅動說明

    • #獲取ADC通道

    • #獲取ADC值

    • #計算采集到的電壓

    • #接口說明

  • #調試方法

    • #節點ADC值

RK3399開發板上的 AD 接口有兩種,分別為:溫度傳感器 (Temperature Sensor)、逐次逼近ADC (Successive Approximation Register)。

  • TS-ADC(Temperature Sensor):支持兩通道,時鐘頻率必須低于800KHZ

  • AR-ADC(Successive Approximation Register):支持六通道單端10位的SAR-ADC,時鐘頻率必須小于13MHZ。內核采用工業 I/O 子系統來控制 ADC,該子系統主要為 AD 轉換或者 DA 轉換的傳感器設計。下面以SAR-ADC為例子,介紹 ADC 的基本配置方法。

#DTS配置

#配置DTS節點

SAR-ADC 的 DTS 節點在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 文件中定義,如下所示:

saradc: saradc@ff100000 {compatible = "rockchip,rk3399-saradc";reg = <0x0 0xff100000 0x0 0x100>;interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH 0>;#io-channel-cells = <1>;clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;clock-names = "saradc", "apb_pclk";resets = <&cru SRST_P_SARADC>;reset-names = "saradc-apb";status = "disabled";};

用戶首先需在DTS文件中添加ADC的資源描述:

&rk_key {compatible = "rockchip,key";status = "okay";io-channels = <&saradc 1>;vol-up-key {linux,code = <114>;label = "volume up";rockchip,adc_value = <1>;};vol-down-key {linux,code = <115>;label = "volume down";rockchip,adc_value = <170>;};power-key {gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;linux,code = <116>;label = "power";gpio-key,wakeup;};menu-key {linux,code = <59>;label = "menu";rockchip,adc_value = <746>;};home-key {linux,code = <102>;label = "home";rockchip,adc_value = <355>;};back-key {linux,code = <158>;label = "back";rockchip,adc_value = <560>;};camera-key {linux,code = <212>;label = "camera";rockchip,adc_value = <450>;}; };

這里申請的是SARADC通道1

#驅動文件中匹配 DTS 節點

驅動key:drivers/input/keyboard/rk_keys.c 首先在驅動文件中定義 of_device_id 結構體數組:

static const struct of_device_id rk_key_match[] = {{ .compatible = "rockchip,key", .data = NULL},{}, };

然后將該結構體數組填充到 platform_driver 中:

static struct platform_driver keys_device_driver = {.probe = keys_probe,.remove = keys_remove,.driver = {.name = "rk-keypad",.owner = THIS_MODULE,.of_match_table = rk_key_match, #ifdef CONFIG_PM.pm = &keys_pm_ops, #endif} };

接著在keys_probe中使用work 進行polling :

/* adc polling work */if (ddata->chan) {INIT_DELAYED_WORK(&ddata->adc_poll_work, adc_key_poll);schedule_delayed_work(&ddata->adc_poll_work,┊ ┊ ADC_SAMPLE_JIFFIES);}

ADC ?key Poll DTS資源解析

static void adc_key_poll(struct work_struct *work) {struct rk_keys_drvdata *ddata;int i, result = -1;ddata = container_of(work, struct rk_keys_drvdata, adc_poll_work.work);if (!ddata->in_suspend) {result = rk_key_adc_iio_read(ddata);/**讀取SARADC值*/if (result > INVALID_ADVALUE &&┊ result < (EMPTY_DEFAULT_ADVALUE - ddata->drift_advalue))ddata->result = result;for (i = 0; i < ddata->nbuttons; i++) {struct rk_keys_button *button = &ddata->button[i];if (!button->adc_value)continue;if (result < button->adc_value + ddata->drift_advalue &&┊ result > button->adc_value - ddata->drift_advalue)button->adc_state = 1;else button->adc_state = 0;if (button->state != button->adc_state)mod_timer(&button->timer,┊ jiffies + DEBOUNCE_JIFFIES);}}schedule_delayed_work(&ddata->adc_poll_work, ADC_SAMPLE_JIFFIES); }

#驅動說明

#獲取ADC通道

在解析資源DTS時 獲取對應的通道 struct iio_channel *chan; ?/定義 IIO 通道結構體chan = iio_channel_get(&pdev->dev, NULL); /獲取 IIO 通道結構體/

static int rk_keys_parse_dt(struct rk_keys_drvdata *pdata,struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node;struct device_node *child_node;struct iio_channel *chan;int ret, gpio, i = 0;u32 code, adc_value, flags, drift;if (of_property_read_u32(node, "adc-drift", &drift))pdata->drift_advalue = DRIFT_DEFAULT_ADVALUE;else pdata->drift_advalue = (int)drift;chan = iio_channel_get(&pdev->dev, NULL); ...............

#獲取ADC值

在adc_key polling中 調用 iio_read_channel_raw 函數讀取 AD 采集的原始數據并存入 val 中

ret = iio_read_channel_raw(channel, &val);

#計算采集到的電壓

Vref / (2^n-1) = Vresult / raw

注:

Vref 為標準電壓 n 為 AD 轉換的位數 Vresult 為用戶所需要的采集電壓 raw 為 AD 采集的原始數據

#接口說明

struct iio_channel *iio_channel_get(struct device *dev, const char *consumer_channel);
  • 功能:獲取 iio 通道描述

  • 參數:

    • dev: 使用該通道的設備描述指針

    • consumer_channel: 該設備所使用的 IIO 通道描述指針

void iio_channel_release(struct iio_channel *chan);
  • 功能:釋放 iio_channel_get 函數獲取到的通道

  • 參數:

    • chan:要被釋放的通道描述指針

int iio_read_channel_raw(struct iio_channel *chan, int *val);
  • 功能:讀取 chan 通道 AD 采集的原始數據。

  • 參數:

    • chan:要讀取的采集通道指針

    • val:存放讀取結果的指針

#調試方法

#節點ADC值

cat /sys/bus/iio/devices/iio\:device1/in_voltage*_raw 876 1021 164 512 513 349

? 回復「?籃球的大肚子」進入技術群聊

回復「1024」獲取1000G學習資料

總結

以上是生活随笔為你收集整理的RK 利用SARADC 来做多个按键的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。