在MSM8909 Android下配置CS1237驱动,读取PT100温度传感器
前言
上面一个文章配置了普通的GPIO口。然后根据在单片机的经验,尝试配置CS1237驱动。
CS1237是一款高精度、低功耗模数转换芯片,一路差分输入通道,内置温度传感器和高精度振荡器。通过 2线SPI接口 通信。
在单片机中是使用模拟IO口的方式实现SPI通信。在Android里也是一样。
目录
前言
实现
1.首先还是配置DTS设备树,修改kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi。
2.在 kernel/drivers/misc 下添加 cs1237.c文件
(1)IO口函数操作定义
(2)cs1237配置初始化,读取配置函数
(3)probe函数中添加
(4)读取CS1237数值
3.修改 kernel/drivers/misc 下 Makefile 和 Kconfig 文件(和上篇文章普通IO口配置一样)
4. 修改 kernel/arch/arm/configs 下的 msm8909-1gb_defconfig 文件(和上篇文章普通IO口配置一样)
5. 执行编译、烧录
6. 测试驱动
7.java层获取PT100温度数值
jni层调用cat命令获取cs1237读数
java层调用jni函数,将读数转成温度数值
PT100是一直热电阻温度传感器
实现
1.首先还是配置DTS设备树,修改kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi。
cs1237 {compatible = "cs1237";//这是一个enable的pincs1237,gpio0 = <&msm_gpio 0 0>;//SDA pincs1237,gpio68 = <&msm_gpio 68 0>;//SCL pincs1237,gpio69 = <&msm_gpio 69 0>;label = "cs1237";};
2.在 kernel/drivers/misc 下添加 cs1237.c文件
(1)IO口函数操作定义
void CLK_H(void){gpio_set_value(CLK_PIN, GPIO_HIGH);}
void CLK_L(void){gpio_set_value(CLK_PIN, GPIO_LOW);}
void SDA_H(void){gpio_set_value(SDA_PIN, GPIO_HIGH);}
void SDA_L(void){gpio_set_value(SDA_PIN, GPIO_LOW);}
int SDA_Read(void){return gpio_get_value(SDA_PIN);}
void SDA_OUT(void){gpio_direction_output(SDA_PIN, 1);}
void SDA_IN(void){gpio_direction_input(SDA_PIN);}
(2)cs1237配置初始化,读取配置函数
unsigned char cs1237_init_config(void)
{int count_i = 0; //溢出计时器int i = 0;unsigned char dat = PGA_2 | SPEED_640 | REF_ON;SDA_OUT();//SDA_H();SDA_IN();CLK_L();while(SDA_Read() == 1) { //等待CS237准备好mdelay(5);count_i++;if(count_i > 300) {SDA_OUT();//SDA_H(); // OUT引脚拉高CLK_H(); // CLK引脚拉高return -1;//超时,则直接退出程序}}for(i = 0; i < 29; i++) { // 1 - 29CLK_H();udelay(1);CLK_L();udelay(1);}SDA_OUT();CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//30CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//31CLK_H();udelay(1);SDA_L();CLK_L();udelay(1);//32CLK_H();udelay(1);SDA_L();CLK_L();udelay(1);//33CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//34CLK_H();udelay(1);SDA_L();CLK_L();udelay(1);//35CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//36CLK_H();udelay(1);CLK_L();udelay(1); //37 写入了0x65for(i = 0; i < 8; i++) { // 38 - 45个脉冲了,写8位数据CLK_H();udelay(1);if(dat & 0x80)SDA_H();elseSDA_L();dat <<= 1;CLK_L();udelay(1);}SDA_H();CLK_H();udelay(1);CLK_L();udelay(1);return 0;
}// 读取芯片的配置数据
unsigned char Read_Config(void)
{unsigned char i;unsigned char dat = 0; //读取到的数据unsigned int count_i = 0; //溢出计时器SDA_OUT();//SDA_H();SDA_IN();CLK_L();//时钟拉低while(SDA_Read() == 1) { //等待芯片准备好数据mdelay(1);count_i++;if(count_i > 300) {SDA_OUT();CLK_H(); // CLK=1;//SDA_H(); // OUT=1;return -1;//超时,则直接退出程序}}//CLK引脚拉高拉低即为一个时钟for(i = 0; i < 29; i++) { // 产生第1到29个时钟CLK_H(); udelay(1);CLK_L();udelay(1);}SDA_OUT();CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//30CLK_H();udelay(1);SDA_L();CLK_L();udelay(1);//31CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//32CLK_H();udelay(1);SDA_L();CLK_L();udelay(1);//33CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//34CLK_H();udelay(1);SDA_H();CLK_L();udelay(1);//35CLK_H();udelay(1);SDA_L();CLK_L();udelay(1);//36SDA_H();CLK_H();udelay(1);CLK_L();udelay(1);//37 写入0x56 即读命令dat = 0;SDA_IN();for(i = 0; i < 8; i++) { // 第38 - 45个脉冲了,读取数据CLK_H();udelay(1);CLK_L();udelay(1);dat <<= 1;if(SDA_Read())dat++;}//第46个脉冲CLK_H();udelay(1);CLK_L();udelay(1);SDA_OUT();//SDA_H(); //OUT引脚拉高return dat;
}
(3)probe函数中添加
static int gpio_probe(struct platform_device *pdev)
{int ret = 0;printk("*************cs1237 probe *************\n");cs1237_class = class_create(THIS_MODULE, "cs1237");if(IS_ERR(cs1237_class)){ret = PTR_ERR(cs1237_class);pr_err("Failed to create class.\n");return ret;}cs1237_dev = device_create(cs1237_class, NULL, 0, NULL, "cs1237");if (IS_ERR(cs1237_dev)){ret = PTR_ERR(cs1237_class);pr_err("Failed to create device(cs1237)!\n");return ret;}ret = device_create_file(cs1237_dev, &cs1237_dev_attr);if(ret){pr_err("%s: cs1237 creat sysfs failed\n",__func__);return ret;}ret = device_create_file(cs1237_dev, &cs1237_config_attr);if(ret){pr_err("%s: cs1237 creat sysfs failed\n",__func__);return ret;}ret = device_create_file(cs1237_dev, &cs1237_init_attr);if(ret){pr_err("%s: cs1237 creat sysfs failed\n",__func__);return ret;}//寻找设备树dts下的 "cs1237,gpio0" 名称对应的GPIO口ENABLE_PIN = of_get_named_gpio(pdev->dev.of_node, "cs1237,gpio0", 0);if (ENABLE_PIN < 0)printk( "ENABLE_PIN is not available \n");//对应修改的dts的 labelret = gpio_request(ENABLE_PIN, "cs1237");if(0 != ret) {printk( "gpio request %d failed.", CLK_PIN);return -EIO;}gpio_direction_output(ENABLE_PIN, 1);gpio_set_value(ENABLE_PIN, GPIO_HIGH);SDA_PIN = of_get_named_gpio(pdev->dev.of_node, "cs1237,gpio68", 0);if (SDA_PIN < 0)printk( "SDA_PIN is not available \n");//对应修改的dts的 labelret = gpio_request(SDA_PIN, "cs1237");if(0 != ret) {printk( "gpio request %d failed.", SDA_PIN);return -EIO;}gpio_direction_output(SDA_PIN, 1);CLK_PIN = of_get_named_gpio(pdev->dev.of_node, "cs1237,gpio69", 0);if (CLK_PIN < 0)printk( "CLK_PIN is not available \n");//对应修改的dts的 labelret = gpio_request(CLK_PIN, "cs1237");if(0 != ret) {printk( "gpio request %d failed.", CLK_PIN);return -EIO;}gpio_direction_output(CLK_PIN, 1);CLK_H();cs1237_init_config();CONFIG = Read_Config();if(CONFIG == 36){printk("cs1237_probe ok , config is %d\n",ret);}else{printk("cs1237_probe failed, config is %d\n",ret);}return 0;
}
(4)读取CS1237数值
//读取ADC数据,返回的是一个有符号数据
int Read_CS1237(void)
{unsigned char i;uint32_t dat = 0; //读取到的数据unsigned int count_i = 0; //溢出计时器int temp;SDA_OUT();//SDA_H(); //OUT引脚拉高SDA_IN();CLK_L();//时钟拉低while(SDA_Read()) { //等待芯片准备好数据mdelay(1);count_i++;if(count_i > 300) {SDA_OUT();CLK_H(); // CLK=1;//SDA_H(); // OUT=1;return -1;//超时,则直接退出程序}}dat = 0;for(i = 0; i < 24; i++) { //获取24位有效转换CLK_H();udelay(1);dat <<= 1;if(SDA_Read())dat++;CLK_L();udelay(1);}for(i = 0; i < 3; i++) { //接着前面的时钟 再来3个时钟CLK_H();udelay(1);CLK_L();udelay(1);}SDA_OUT();//SDA_H();if(dat == 0x00800000)return -1;if(dat & 0x00800000) { // 判断是负数 最高位24位是符号位temp = (((~dat) & 0x007FFFFF) + 1); // 补码变源码} elsetemp = dat; // 正数的补码就是源码return temp;
}
3.修改 kernel/drivers/misc 下 Makefile 和 Kconfig 文件(和上篇文章普通IO口配置一样)
4. 修改 kernel/arch/arm/configs 下的 msm8909-1gb_defconfig 文件(和上篇文章普通IO口配置一样)
5. 执行编译、烧录
make bootimage -j6
6. 测试驱动
系统启动后,用adb命令进入系统
可以看到在 /sys/class/ 目录下生成了 cs1237 文件夹,里面有个 cs1237 文件夹。
下面我们就可以控制 value 文件,去读取cs1237读数。
7.java层获取PT100温度数值
jni层调用cat命令获取cs1237读数
char path[DIRECTION_MAX];char value_str[10];int fd;snprintf(path, DIRECTION_MAX, "/sys/class/cs1237/cs1237/value");fd = open(path, O_RDONLY);if (fd < 0) {LOGE("failed to open gpio value for reading!\n");return 1003;}if (read(fd, value_str, 10) < 0) {LOGE("failed to read value!\n");return 1003;}close(fd);return (atoi(value_str));
java层调用jni函数,将读数转成温度数值
public static float getTemp() {//获取得到AD数值int data = JNIhardware.getTempure();//Log.e("Temp","temp ad data =>"+data);//根据电路图,将AD数值转成电压float vo = (float)data/(float)0x800000 * 3.3f / 2.0f;vo = vo/2;//将电压转换成pt100电阻值float pt100 = 3000 * vo / (3.3f - vo);//根据pt100电阻特性,得到温度。offset_tem表示误差float tempdat = ( pt100 - 100) / 0.39f + offset_tem;Log.e("Temp","temp => "+tempdat);return tempdat;}
这里是完整的cs1237.c文件
在MSM8909 Android下配置CS1237驱动,读取PT100温度传感器相关推荐
- android下配置偏好信息的管理
android下配置偏好信息的管理 佣工7001 应用程序一般都有这样的需求,为了应用有更好的适应性,有一些参数设置需要独立出来放在配置文件里面.这个配置文件应该是开发的时候就编辑好的设好了默认值,安 ...
- android下调试声卡驱动之总结
1.在调试中出现问题后,首先看I2C通信有没有问题,wm8960寄存器的设置是靠I2C来完成,另外I2C通信不成功在开发板中是没 有声卡相关的设备节点. a.首先查看Machine代码中的I2C的序号 ...
- Android下的摄像头驱动开发
Android下的摄像头驱动开发 由 King 发表于:2012/02/14 10:00 星期二 这几天拿到一个MINI210开发板,于是尝试着把ov7670移植到开发板上.仔细的观察了一下友善给的驱 ...
- 身份证读取设备开发解决方案:2、Android下通过usb转串口读取身份证信息
身份证读取设备开发解决方案:2.Android下通过usb转串口读取身份证信息 文章目录 身份证读取设备开发解决方案:2.Android下通过usb转串口读取身份证信息 1. 前言 2. 准备 3. ...
- android下调试声卡驱动之概述
在Android中音频系统使用的是ALSA系统架构.ASoC--ALSA System on Chip .是建立在标准ALSA驱动层上,为了更好地支持 嵌入式处理器和移动设备中的音频Codec的一套软 ...
- android音量加减驱动,android下调试声卡驱动之概述
在Android中音频系统使用的是ALSA系统架构.ASoC--ALSA System on Chip .是建立在标准ALSA驱动层上,为了更好地支持 嵌入式处理器和移动设备中的音频Codec的一套软 ...
- 红旗linux无线网卡驱动,红旗Linux下配置无线网卡(驱动安装/wep sid设置)[图文]
下载了一个红旗Linux 6.0 SP1的iso光盘镜像,准备安装一个学习下. 下载的很成功.刻录的很成功.安装的也很成功,但是安装了以后,不能使用无线上网.在笔记本普遍配置无线网卡的情况下,Linu ...
- 在Windows环境下配置QT Creator 读取NC文件(NetCDP,C++接口)
文章目录 前言 一.资源下载 1.1 首先下载NetCDF-c与NetCDF-cxx 二.使用步骤 1.下载文件 2.将需要的.h与.cpp拷贝出来 3.找到netcdf 4 找到netcdf.h 二 ...
- hue 添加jar_在hue下配置jdbc驱动
cloudera的cdh是一个方便的工具,其中的hue号称是hadoop UI,提供了强大的图形操作界面,是一个非常好用的工具.下面介绍如何配置jdbc来进行数据的采集. Installing the ...
最新文章
- JAVA IO操作中的IN和OUT问题
- Java的Excel导出方案介绍
- 91.91p10.space v.php,luogu P1091 合唱队形
- Openshift 4.4 静态 IP 离线安装系列:准备离线资源
- python 漏洞扫描器_自动扫描全网漏洞的扫描器
- 机器学习(一元线性回归)
- C语言计算个人所得税
- 如何使用Servlet,JSP和MySQL将文件上传到数据库
- 银河麒麟禁止抓屏printScreen
- 吴恩达机器学习ex1——通过人口预测小摊经济状况
- 极限钓鱼!FBI开发加密通讯设备并通过线人流入黑市,800多名罪犯被监控并抓捕...
- person_reID
- Android APK签名 JKS 密钥库使用专用格式。建议使用 “keytool -importkeystore -srckeystore E:\xxxxxx- pkcs12“ 迁移到行业标准格式
- 【SQL学习笔记】《SQL进阶教程》1.2
- HTML+CSS精美漂亮的登录页面
- 当前页面实现简单搜索功能
- 基于Ethernet KRL,上位机C#通过TCP/IP与KUKA库卡机械臂通讯Demo
- [Python Tips]去除 Trivial 赋值语句
- vs和mysql做管理系统_FytSoaCms0: CMS内容管理系统
使用NetCore2.1开发, Vs2017 数据Mysql...
- linux查找内容高亮显示,设置grep高亮显示匹配项