荔枝派nano(f1c100s)使用KEYADC(LRADC)读电池电压

硬件介绍:荔枝派nano(f1c100s)
软件介绍:嵌入式Linux开发

一、基本情况介绍

1、电池

电池用的是锂电池,满电4.2v,放电截止电压2.75v;
在这里插入图片描述

2、F1C100s KEYADC

下图是官方手册对于KEYADC的介绍,可以看到:
F1C100s KEYADC的检测电压范围在0-2V之间(全志其他芯片可能不一样);
6bit分辨率,也就是2V电压对应模拟量值为63,0V电压对应模拟量值为0;
在这里插入图片描述

3、分压电阻选择

关于检测电路我参考了这篇文章
对于R22,这里选择了330K,因为最好可以通过控制分压电阻来决定分压后的电压范围刚好与KEYADC的检测范围一致,这样有利于后面程序的编写;
可以计算一下:
当电池满电4.2V时,LRADC电压 = (4.2V * R21) / (R21 + R22) = 1260 / 630 = 2V
当电池达到放电限压2.75V时,LRADC电压 = (2.75V * R21) / (R21 + R22) = 1110 / 630 = 1.3V
在这里插入图片描述

二、驱动程序编写

下图是KEYADC相关寄存器;
程序大体思路:
1、设置KEYADC_CTRL_REG寄存器;
2、读取KEYADC_DATA_REG寄存器;
因为使用的轮询读取,程序并不复杂,简单粗暴!
在这里插入图片描述
部分关键程序如下:

#include <linux/err.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/of.h>

/* 相关寄存器宏 */
#define LRADC_BASE				0x01C23400
#define LRADC_CTRL				0x00
#define LRADC_INTC				0x04
#define LRADC_INTS				0x08
#define LRADC_DATA0				0x0c

/* LRADC_CTRL bits */
#define FIRST_CONVERT_DLY(x)	((x) << 24) /* 8 bits */
#define CHAN_SELECT(x)			((x) << 22) /* 2 bits */
#define CONTINUE_TIME_SEL(x)	((x) << 16) /* 4 bits */
#define KEY_MODE_SEL(x)			((x) << 12) /* 2 bits */
#define LEVELA_B_CNT(x)			((x) << 8)  /* 4 bits */
#define HOLD_EN(x)				((x) << 6)
#define LEVELB_VOL(x)			((x) << 4)  /* 2 bits */
#define SAMPLE_RATE(x)			((x) << 2)  /* 2 bits */
#define ENABLE(x)				((x) << 0)

static volatile unsigned int *KEYADC_CTRL_REG;
static volatile unsigned int *KEYADC_DATA_REG;

//在驱动程序的read函数里读取KEYADC_DATA_REG寄存器
static ssize_t adc_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	int err;
	unsigned int tmpValue, voltage;

	//3、读取KEYADC_DATA_REG寄存器
	tmpValue = (*KEYADC_DATA_REG) & 0x3f;	
	voltage = tmpValue * 2000000 / 63;		//把读到寄存器的值换算成mV,2000000/63是分辨率
	
	err = copy_to_user(buf, &voltage, 4);	//把换算后的值返回到应用程序
	
	return 0;
}

//在驱动程序的open函数里内存映射、设置寄存器
static int adc_drv_open (struct inode *node, struct file *file)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);

	//1、内存映射
	KEYADC_CTRL_REG = ioremap(LRADC_BASE + LRADC_CTRL, 4);
	KEYADC_DATA_REG = ioremap(LRADC_BASE + LRADC_DATA0, 4);

	if(KEYADC_CTRL_REG == NULL)
		printk("KEYADC_CTRL_REG is NULL\n");

	if(KEYADC_DATA_REG == NULL)
		printk("KEYADC_DATA_REG is NULL\n");
	
	//2、设置KEYADC_CTRL_REG寄存器,这些设置是参考的官方的KEYADC驱动
	writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(2) | HOLD_EN(1) |
		SAMPLE_RATE(0) | ENABLE(1), KEYADC_CTRL_REG);
	
	return 0;
}

三、测试

我是在Qt里写的测试程序,关键部分如下:
在这里插入图片描述
在这里插入图片描述
注意:这里电量显示为86%,和上面应用程序中举的例子没有关系。

四、总结

1、程序写完后,要使用正确的方法来测试,因为KEYADC检测的电压范围就是0-2V,只要超过2V,读出来的值都是63;
2、欢迎纠错点评!

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值