模拟IIC协议驱动气压传感器bmp085
来源:互联网 发布:eclipse mac 百度网盘 编辑:程序博客网 时间:2024/04/27 23:51
bmp085的驱动文件如下
#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/serio.h>#include <linux/delay.h>#include <linux/clk.h>#include <linux/wait.h>#include <linux/sched.h>#include <linux/cdev.h>#include <linux/miscdevice.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <mach/gpio.h>#define DEVICE_NAME "bmp085"#define BMP085_SlaveAddress 0xee //定义器件在IIC总线中的从地址 #define SDA S5PV210_GPH3(1) #define SCL S5PV210_GPH3(0) #define ONE 1#define ZERO 0#define OSS 0#define GET_PARAMETE 0x10#define GET_TEMP 0x20#define GET_PRESSURE 0x30#define BMP085_FINAL_TEMP 0x40#define BMP085_FINAL_PRESSURE 0x50#define GET_FINAL_START 0x60#define UDELAY {udelay(5);}#define MDELAY {mdelay(5);}//bmp085器件参数static long temperature=0;static long pressure=0xff; static char buf[6]; //data buffferstatic int read_falg;static struct BMP085_PARAMETER{short ac1;short ac2;short ac3;unsigned short ac4;unsigned short ac5;unsigned short ac6;short b1;short b2;short mb;short mc;short md;};struct BMP085_PARAMETER bmp085_parameter;//起始信号void bmp085_start(void) //SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。 { gpio_set_value(SDA, 1); //拉高数据线 gpio_set_value(SCL, 1); //拉高时钟线 UDELAY; //延时 gpio_set_value(SDA, 0); //产生下降沿 UDELAY; //延时 gpio_set_value(SCL, 0); //拉低时钟线}//停止信号void bmp085_stop (void) //SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。 { gpio_set_value(SDA, 0); //拉低数据线 gpio_set_value(SCL, 1); //拉高时钟线 UDELAY; //延时 gpio_set_value(SDA, 1); //产生上升沿 UDELAY //延时} //发送应答信号 入口参数:ack (0x0:ACK 0x01:NAK)void bmp085_sendack(unsigned char ack){ if(ack) //写应答信号 gpio_set_value(SDA, 1); else gpio_set_value(SDA, 0); gpio_set_value(SCL, 1); //拉高时钟线 UDELAY; //延时 gpio_set_value(SCL, 0); //拉低时钟线 UDELAY; //延时}//接收应答信号unsigned char bmp085_recvack(void){ unsigned char cy; gpio_set_value(SCL, 1); //拉高时钟线 gpio_direction_input(SDA); UDELAY; //延时 cy=gpio_get_value(SDA); //读应答信号 gpio_set_value(SCL, 0); //拉低时钟线 UDELAY; //延时 gpio_direction_output(SDA,1); UDELAY; //延时 return cy; }//向IIC总线发送一个字节数据void bmp085_sendbyte(unsigned char dat){ unsigned char i; unsigned char cy[8]; unsigned char data; for (i=0; i<8; i++) //获取字节的每一位 { data=dat&0x80; if(data) cy[i]=ONE; else cy[i]=ZERO; dat<<=1; } for (i=0; i<8; i++) //8位计数器 { gpio_set_value(SDA,cy[i]); //送数据口 gpio_set_value(SCL, 1); //拉高时钟线 UDELAY; //延时 gpio_set_value(SCL, 0); //拉低时钟线 UDELAY; //延时 } bmp085_recvack();}//从IIC总线接收一个字节数据unsigned char bmp085_recvbyte(void){ unsigned char i; unsigned char dat = 0; gpio_set_value(SDA,1); //使能内部上拉,准备读取数据 gpio_direction_input(SDA); UDELAY; //延时 for (i=0; i<8; i++) //8位计数器 { dat <<= 1; gpio_set_value(SCL, 1); //拉高时钟线 UDELAY; //延时 dat |= gpio_get_value(SDA); //读数据 gpio_set_value(SCL, 0); //拉低时钟线 UDELAY; //延时 } gpio_direction_output(SDA,1); return dat;}short multiple_read(unsigned char ST_Address){ unsigned char msb, lsb; short data; bmp085_start(); //起始信号 bmp085_sendbyte(BMP085_SlaveAddress); //发送设备地址+写信号 bmp085_sendbyte(ST_Address); //发送存储单元地址 bmp085_start(); //起始信号 bmp085_sendbyte(BMP085_SlaveAddress+1); //发送设备地址+读信号 msb = bmp085_recvbyte(); //BUF[0]存储 bmp085_sendack(0x0); //回应ACK lsb = bmp085_recvbyte(); bmp085_sendack(0x01); //最后一个数据需要回NOACK bmp085_stop(); //停止信号 MDELAY; //延时 data = msb << 8; data |= lsb; return data;}void init_bmp085(void){ bmp085_parameter.ac1= multiple_read(0xAA); bmp085_parameter.ac2= multiple_read(0xAC); bmp085_parameter.ac3= multiple_read(0xAE); bmp085_parameter.ac4= multiple_read(0xB0); bmp085_parameter.ac5= multiple_read(0xB2); bmp085_parameter.ac6= multiple_read(0xB4); bmp085_parameter.b1 = multiple_read(0xB6); bmp085_parameter.b2 = multiple_read(0xB8); bmp085_parameter.mb = multiple_read(0xBA); bmp085_parameter.mc = multiple_read(0xBC); bmp085_parameter.md = multiple_read(0xBE); printk("the parameter ac1=%d\n",bmp085_parameter.ac1); printk("the parameter ac2=%d\n",bmp085_parameter.ac2); printk("the parameter ac3=%d\n",bmp085_parameter.ac3); printk("the parameter ac4=%d\n",bmp085_parameter.ac4); printk("the parameter ac5=%d\n",bmp085_parameter.ac5); printk("the parameter ac6=%d\n",bmp085_parameter.ac6); printk("the parameter b1=%d\n",bmp085_parameter.b1); printk("the parameter b2=%d\n",bmp085_parameter.b2); printk("the parameter mb=%d\n",bmp085_parameter.mb); printk("the parameter mc=%d\n",bmp085_parameter.mc); printk("the parameter md=%d\n",bmp085_parameter.md);}long bmp085_read_temp(void){ bmp085_start(); //起始信号 bmp085_sendbyte(BMP085_SlaveAddress); //发送设备地址+写信号 bmp085_sendbyte(0xF4); // write register address bmp085_sendbyte(0x2E); // write register data for temp bmp085_stop(); //发送停止信号 MDELAY; // max time is 4.5ms return (long) multiple_read(0xF6);}long bmp085_read_pressure(void){ long pressure = 0; bmp085_start(); //起始信号 bmp085_sendbyte(BMP085_SlaveAddress); //发送设备地址+写信号 bmp085_sendbyte(0xF4); // write register address bmp085_sendbyte(0x34); // write register data for pressure bmp085_stop(); //发送停止信号 MDELAY; // max time is 4.5ms pressure = multiple_read(0xF6); pressure &= 0x0000FFFF; return pressure; //return (long) bmp085ReadShort(0xF6);}void bmp085_get_data(void){ temperature = bmp085_read_temp(); temperature = bmp085_read_temp(); // 读取温度 pressure = bmp085_read_pressure(); pressure = bmp085_read_pressure(); // 读取压强}void bmp085_data_calculate(void){ long x1, x2, b5, b6, x3, b3, p; unsigned long b4, b7; x1 = ((long)temperature - bmp085_parameter.ac6) * bmp085_parameter.ac5 >> 15; x2 = ((long) bmp085_parameter.mc << 11) / (x1 +bmp085_parameter.md); b5 = x1 + x2; temperature = (b5 + 8) >> 4; b6 = b5 - 4000; x1 = (bmp085_parameter.b2 * (b6 * b6 >> 12)) >> 11; x2 = bmp085_parameter.ac2 * b6 >> 11; x3 = x1 + x2; b3 = (((long)bmp085_parameter.ac1 * 4 + x3) + 2)/4; x1 = bmp085_parameter.ac3 * b6 >> 13; x2 = (bmp085_parameter.b1 * (b6 * b6 >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; b4 = (bmp085_parameter.ac4 * (unsigned long) (x3 + 32768)) >> 15; b7 = ((unsigned long)pressure - b3) * (50000 >> OSS); if( b7 < 0x80000000) p = (b7 * 2) / b4 ; else p = (b7 / b4) * 2; x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; pressure = p + ((x1 + x2 + 3791) >> 4); }void conversion(long temp_data) { buf[0]=temp_data/100000 ; temp_data=temp_data%100000; //取余运算 buf[1]=temp_data/10000; temp_data=temp_data%10000; //取余运算 buf[2]=temp_data/1000; temp_data=temp_data%1000; //取余运算 buf[3]=temp_data/100; temp_data=temp_data%100; //取余运算 buf[4]=temp_data/10; temp_data=temp_data%10; //取余运算 buf[5]=temp_data; }static long bmp085_ioctl(struct file *filp, unsigned int cmd,unsigned long arg) { switch(cmd) { case GET_PARAMETE: init_bmp085(); break; case GET_TEMP: temperature=bmp085_read_temp(); conversion(temperature); break; case GET_PRESSURE: pressure=bmp085_read_pressure(); conversion(pressure); break; case GET_FINAL_START: bmp085_get_data(); bmp085_data_calculate(); break; case BMP085_FINAL_TEMP: conversion(temperature); read_falg=0x22; break; case BMP085_FINAL_PRESSURE: conversion(pressure); read_falg=0x88; break; default: printk("iotcl cmd no found!\n"); return -EINVAL; } return 0;}static ssize_t bmp085_read(struct file *file, char __user *buffer, size_t size, loff_t *pos){ int ret=0; long data; if(read_falg==0x22) data=temperature; if(read_falg==0x88) data=pressure; ret=copy_to_user(buffer,&data,sizeof(data)); if(ret<0){ printk("copy to user err!\n"); return -EFAULT; } return 0;}static int bmp085_open(struct inode *inode, struct file *file){ printk("open in kernel\n"); return 0;}static int bmp085_release(struct inode *inode, struct file *file){ printk("bmp085_release\n"); return 0;}static struct file_operations bmp085_dev_fops={ .owner = THIS_MODULE, .open = bmp085_open, .read = bmp085_read, .unlocked_ioctl = bmp085_ioctl, .release = bmp085_release,};static struct miscdevice bmp085_dev = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &bmp085_dev_fops,};static int __init bmp085_dev_init(void) { int ret; ret = gpio_request(SDA, "BMP085_SDA"); if (ret){ printk("%s: request GPIO %d for bmp085 failed, ret = %d\n", DEVICE_NAME,SDA, ret); return ret; } ret = gpio_request(SCL, "BMP085_SCL"); if (ret){ printk("%s: request GPIO %d for bmp085 failed, ret = %d\n", DEVICE_NAME,SCL, ret); return ret; } gpio_direction_output(SDA, 1); gpio_direction_output(SCL, 1); ret = misc_register(&bmp085_dev); printk(DEVICE_NAME"\tinitialized\n"); return ret;}static void __exit bmp085_dev_exit(void){ gpio_free(SDA); gpio_free(SCL); misc_deregister(&bmp085_dev);}module_init(bmp085_dev_init);module_exit(bmp085_dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("www");
应用层的测试app如下
#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <strings.h>#define GET_PARAMETE 0x10#define GET_TEMP 0x20#define GET_PRESSURE 0x30#define BMP085_FINAL_TEMP 0x40#define BMP085_FINAL_PRESSURE 0x50#define GET_FINAL_START 0x60int bmpfd;//bmp085文件描述符long data_covertion(char *buf){ long data; data+=buf[0]*100000; data+=buf[1]*10000; data+=buf[2]*1000; data+=buf[3]*100; data+=buf[4]*10; data+=buf[5]; return data;}int main(int argc,char **argv){ int ret; char buf[6]; long pressure; long temperature; int i; bmpfd=open("/dev/bmp085",O_RDWR); if(bmpfd<0) { printf("open bmp085 err!\n"); printf("please cheek!\n"); exit(-1); } printf("open bmp085 ok!\n"); ioctl(bmpfd,GET_PARAMETE,0); while(1) { ioctl(bmpfd,GET_FINAL_START,0); ioctl(bmpfd,BMP085_FINAL_PRESSURE,0); if(read(bmpfd,&pressure,sizeof(pressure))<0) printf("read bmp085 err!\n"); printf("the bmp085 pressure=%d\n",pressure); ioctl(bmpfd,BMP085_FINAL_TEMP ,0); if(read(bmpfd,&temperature,sizeof(temperature))<0) printf("read bmp085 err!\n"); printf("the bmp085 temperature=%d\n", temperature); sleep(2); } close(bmpfd); return 0;}
0 1
- 模拟IIC协议驱动气压传感器bmp085
- BMP085气压传感器驱动
- BMP085气压传感器驱动 &MS5611经验
- Arduino BMP085/BMP180气压传感器实验
- BMP085大气压传感器
- arduino 大气气压模块 BOSCH BMP085
- 模拟IIC协议
- 模拟IIC协议时序
- 关于温湿度SHT20传感器,用普通GPIO口来模拟IIC实现驱动
- BMP180气压传感器调试
- DHT12温湿度传感器STM32驱动IIC
- GD32 模拟IIC程序驱动
- STM32F4的I2C读取BMP085模块的温度和气压
- motorola气压传感器MPX5050DP、MPX5100DP
- MS5611气压传感器手册勘误
- 传感器系列之4.2气压传感器
- linux中bmp085驱动移植
- iic驱动(IO口模拟)
- git使用记录
- 【Java】String中插入指定字符
- 如何通过AIDL实现跨应用绑定Service
- LeetCode Reverse Integer
- 推荐
- 模拟IIC协议驱动气压传感器bmp085
- 秋招面试中常见题型以及知识点总结
- 11.1 python之webpy获取请求参数,把数据库结果放到List,Retrofit Post
- 2015-11-1日志
- 由点及面,一叶知秋——集合大家族
- java入门程序100例学习笔记(003杨辉三角)
- XP下配置IIS网站的过程
- PHP就业情况分析
- Selector 与 Action 与 NSObjectProtocol 问题