前言

上面一个文章配置了普通的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温度传感器相关推荐

  1. android下配置偏好信息的管理

    android下配置偏好信息的管理 佣工7001 应用程序一般都有这样的需求,为了应用有更好的适应性,有一些参数设置需要独立出来放在配置文件里面.这个配置文件应该是开发的时候就编辑好的设好了默认值,安 ...

  2. android下调试声卡驱动之总结

    1.在调试中出现问题后,首先看I2C通信有没有问题,wm8960寄存器的设置是靠I2C来完成,另外I2C通信不成功在开发板中是没 有声卡相关的设备节点. a.首先查看Machine代码中的I2C的序号 ...

  3. Android下的摄像头驱动开发

    Android下的摄像头驱动开发 由 King 发表于:2012/02/14 10:00 星期二 这几天拿到一个MINI210开发板,于是尝试着把ov7670移植到开发板上.仔细的观察了一下友善给的驱 ...

  4. 身份证读取设备开发解决方案:2、Android下通过usb转串口读取身份证信息

    身份证读取设备开发解决方案:2.Android下通过usb转串口读取身份证信息 文章目录 身份证读取设备开发解决方案:2.Android下通过usb转串口读取身份证信息 1. 前言 2. 准备 3. ...

  5. android下调试声卡驱动之概述

    在Android中音频系统使用的是ALSA系统架构.ASoC--ALSA System on Chip .是建立在标准ALSA驱动层上,为了更好地支持 嵌入式处理器和移动设备中的音频Codec的一套软 ...

  6. android音量加减驱动,android下调试声卡驱动之概述

    在Android中音频系统使用的是ALSA系统架构.ASoC--ALSA System on Chip .是建立在标准ALSA驱动层上,为了更好地支持 嵌入式处理器和移动设备中的音频Codec的一套软 ...

  7. 红旗linux无线网卡驱动,红旗Linux下配置无线网卡(驱动安装/wep sid设置)[图文]

    下载了一个红旗Linux 6.0 SP1的iso光盘镜像,准备安装一个学习下. 下载的很成功.刻录的很成功.安装的也很成功,但是安装了以后,不能使用无线上网.在笔记本普遍配置无线网卡的情况下,Linu ...

  8. 在Windows环境下配置QT Creator 读取NC文件(NetCDP,C++接口)

    文章目录 前言 一.资源下载 1.1 首先下载NetCDF-c与NetCDF-cxx 二.使用步骤 1.下载文件 2.将需要的.h与.cpp拷贝出来 3.找到netcdf 4 找到netcdf.h 二 ...

  9. hue 添加jar_在hue下配置jdbc驱动

    cloudera的cdh是一个方便的工具,其中的hue号称是hadoop UI,提供了强大的图形操作界面,是一个非常好用的工具.下面介绍如何配置jdbc来进行数据的采集. Installing the ...

最新文章

  1. JAVA IO操作中的IN和OUT问题
  2. Java的Excel导出方案介绍
  3. 91.91p10.space v.php,luogu P1091 合唱队形
  4. Openshift 4.4 静态 IP 离线安装系列:准备离线资源
  5. python 漏洞扫描器_自动扫描全网漏洞的扫描器
  6. 机器学习(一元线性回归)
  7. C语言计算个人所得税
  8. 如何使用Servlet,JSP和MySQL将文件上传到数据库
  9. 银河麒麟禁止抓屏printScreen
  10. 吴恩达机器学习ex1——通过人口预测小摊经济状况
  11. 极限钓鱼!FBI开发加密通讯设备并通过线人流入黑市,800多名罪犯被监控并抓捕...
  12. person_reID
  13. Android APK签名 JKS 密钥库使用专用格式。建议使用 “keytool -importkeystore -srckeystore E:\xxxxxx- pkcs12“ 迁移到行业标准格式
  14. 【SQL学习笔记】《SQL进阶教程》1.2
  15. HTML+CSS精美漂亮的登录页面
  16. 当前页面实现简单搜索功能
  17. 基于Ethernet KRL,上位机C#通过TCP/IP与KUKA库卡机械臂通讯Demo
  18. [Python Tips]去除 Trivial 赋值语句
  19. vs和mysql做管理系统_FytSoaCms0: CMS内容管理系统 使用NetCore2.1开发, Vs2017 数据Mysql...
  20. linux查找内容高亮显示,设置grep高亮显示匹配项

热门文章

  1. 云计算在物联网中的应用
  2. 推荐不错的软件测试微信公众号
  3. 再无需从头训练迁移学习模型!亚马逊开源迁移学习数据库 Xfer...
  4. cie规定的标准光源_标准施照体与标准光源_应用光学与光学设
  5. 中国电子信息产业发展研究院、德国弗劳恩霍夫协会 IOSB-INA、美国通用智能系统和技术公司合作谅解备忘录签约仪式在京举行
  6. 80后90后夹缝中的一代!
  7. 法国制药巨头赛诺菲将利用人工智能来打击流感
  8. IPTV 和OTT TV 理解比较和应用
  9. 中国互联网视频分析 – 群雄逐鹿
  10. windows bat批处理文件,实现某个软件的重启