SAR使用参考
1. 概述¶
SAR口一共四个,10bit 精度,获取到的值范围在0~0x3ff之间,参考电压为3.3V,即如果你读到的值是0x1D2,得到的电压就是0x1D2/0x3FF *3.3=1.5v左右。
1.1. kernel中添加sar的支持¶
-
确保
arch/arm/boot/dts/mercury6.dtsi
里面有打开sar的支持 -
make menuconfig,确认sar的驱动有编译到kernel
Device Drivers ---> [*] SStar SoC platform drivers ---> \<*> sar driver
2. 内核使用SAR¶
2.1. 初始化为SAR口¶
先申明一下extern void ms_sar_hw_init (void )函数,再通过这个函数初始化SAR。
-
目的
初始化
-
语法
void ms_sar_hw_init ();
-
参数
参数名称 描述 无 -
返回值
返回值 描述 无
2.2. 取SAR值¶
先申明一下extern int ms_sar_get (int ch)函数,再通过这个函数读取sar口电平。
-
目的
获取SAR口电平
-
语法
int ms_sar_get (int ch)
-
参数
参数名称 描述 ch SAR 通道,值范围为0~3 -
返回值
返回值 描述 int 当前SAR口的电平
2.3. 举例¶
#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <linux/watchdog.h> #include <linux/init.h> #include <linux/version.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/kthread.h> #include <linux/semaphore.h> #include <linux/init.h> #include <linux/mutex.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/random.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> #include <linux/proc_fs.h> static int chn = 0; module_param(chn, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(chn, "sar chn num"); extern void ms_sar_hw_init(void); extern int ms_sar_get(int ch); static int __init sar_test_init(void) { int value = 0; ms_sar_hw_init(); value = ms_sar_get(chn); printk("chn=%d, value=%d\n", chn, value); return 0; } static void __exit sar_test_exit(void) { printk("sar_test driver exit success\n"); } module_init(sar_test_init); module_exit(sar_test_exit); MODULE_DESCRIPTION("SAR_TEST driver"); MODULE_AUTHOR("SigmaStar"); MODULE_LICENSE("GPL");
3. 用户空间使用SAR¶
用户空间访问sar,通过IOCTL 的方式,首先open /dev/sar,通过IOCTL初始化SAR和读取电平。
3.1. IOCTL 初始化SAR¶
#define MS_SAR_INIT _IO(SARADC_IOC_MAGIC, 0) sar_fd= open("/dev/sar", /*O_RDONLY*/O_RDWR); ioctl(sar_fd, MS_SAR_INIT, 0);
3.2. IOCTL 读取SAR值¶
#define SARADC_IOC_MAGIC 'a' #define MS_SAR_SET_CHANNEL_READ_VALUE _IO(SARADC_IOC_MAGIC, 1) typedef struct { int channel_value; ////0~3 int adc_value; ///读取到的值 }ADC_CONFIG_READ_ADC; stCfg.channel_value=0; ///SAR0 ioctl(sar_fd, MS_SAR_SET_CHANNEL_READ_VALUE, &stCfg); printf("0: read stCfg.adc_value=:%x\n", stCfg.adc_value);
3.3. 举例¶
#include <fcntl.h> #include <stdio.h> #include <ctype.h> #include <sys/ioctl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdlib.h> #define SARADC_IOC_MAGIC 'a' #define MDRV_SARADC_SET_CHANNEL_MODE_READ_ADC _IO(SARADC_IOC_MAGIC, 1) #define MS_SAR_INIT _IO(SARADC_IOC_MAGIC, 0) #define SAR_MAX_CHN_NUM 4 #define SAR_DEV_NAME "/dev/sar" /// mdrv_sar_io.h typedef struct { int channel_value; int adc_value; } ADC_CONFIG_READ_ADC; int main(int argc, char **argv) { ADC_CONFIG_READ_ADC stCfg; int sar_fd = -1; int chn = 0; int ret = 0; if (argc < 2) { printf("%s %d, such as: %s 1\n", __func__, __LINE__, argv[0]); return -1; } chn = atoi(argv[1]); if (chn < 0 || chn > SAR_MAX_CHN_NUM) { printf("%s %d, chn range is %d~%d\n", __func__, __LINE__, 0, SAR_MAX_CHN_NUM); return -1; } sar_fd = open(SAR_DEV_NAME, O_RDWR); if (sar_fd < 0) { perror("open error"); return -1; } if (0 > ioctl(sar_fd, MS_SAR_INIT)) { perror("ioctl MS_SAR_INIT error"); close(sar_fd); return -1; } memset(&stCfg, 0, sizeof(ADC_CONFIG_READ_ADC)); stCfg.channel_value = chn; if (0 > ioctl(sar_fd,MDRV_SARADC_SET_CHANNEL_MODE_READ_ADC, &stCfg)) { perror("ioctl MDRV_SARADC_SET_CHANNEL_MODE_READ_ADC error"); close(sar_fd); return -1; } printf("get success, chn=%d, value=%d\n", stCfg.channel_value, stCfg.adc_value); close(sar_fd); return 0; }