技术标签: linux模拟i2c时延时函数
一般相应的硬件都会连接到相应的硬件i2c上,但有时会用到模拟i2c(sda和scl引脚弄反,通
信异常,非标准i2c等),这里给出了相应的例子。
这里假设i2c的频率是100k(周期为10us),SCL对应的引脚号是pin11,SDA对应的引脚号是pin22,
#define UDELAY {udelay(5);}
#define MDELAY {mdelay(5);}
#define SCL pin11
#define SDA pin22
#define ONE 1
#define ZERO 0
#define USESOFTIIC
typedef u8 u8;
static struct i2c_client *i2c_client;
static void i2c_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);
}
static void i2c_stop (void){//停止信号 SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据
gpio_set_value(SDA, 0);
gpio_set_value(SCL, 1);
UDELAY;
gpio_set_value(SDA, 1);
UDELAY;
}
static void i2c_sendack(u8 ack){ //发送应答信号 入口参数:ack (0x0:ACK 0x01:NAK)
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;
}
static u8 i2c_recvack(void){//接收应答信号
u8 cy;
gpio_set_value(SDA, 1);
UDELAY;
gpio_direction_input(SDA);
gpio_set_value(SCL, 1);
UDELAY;
cy=gpio_get_value(SDA);
gpio_set_value(SCL, 0);
UDELAY;
gpio_direction_output(SDA,1);
UDELAY;
return cy;
}
static int i2c_sendbyte(u8 data){//向IIC总线发送一个字节数据
u8 i;
u8 ack;
u8 cy[8];
u8 bit;
for (i=0; i<8; i){
bit=data&0x80;
if(bit)
cy[i]=ONE;
else
cy[i]=ZERO;
data<<=1;
}
for (i=0; i<8; i){
gpio_set_value(SDA,cy[i]);
gpio_set_value(SCL, 1);
UDELAY;
gpio_set_value(SCL, 0);
UDELAY;
}
ack=i2c_recvack();
return ack;
}
static u8 i2c_recvbyte(void){//从IIC总线接收一个字节数据
u8 i;
u8 dat = 0;
gpio_set_value(SDA,1);
gpio_direction_input(SDA);
UDELAY;
for (i=0; i<8; i){
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;
}
static void i2c_init(void){
int ret;
ret = gpio_request(SDA, "I2C_SDA");
ret = gpio_request(SCL, "I2C_SCL");
gpio_direction_output(SCL, 1);
gpio_direction_output(SDA, 1);
}
相应的读写寄存器接口
static int i2c_write_reg(u8 reg,u8 value){
int ret1,ret2,ret3;
i2c_start();
ret1=i2c_sendbyte(i2c_client->addr<<1);
ret2=i2c_sendbyte(reg);
ret3=i2c_sendbyte(value);
i2c_stop();
if(ret1||ret2||ret3){
pr_err("i2c_write error ret1=%d,ret2=%d,ret3=%d",ret1,ret2,ret3);
return -ENXIO;
}
return 0;
}
static u8 i2c_read_reg(u8 reg){
int ret1,ret2,ret3,ret4;
i2c_start();
ret1=i2c_sendbyte(i2c_client->addr<<1);
ret2=i2c_sendbyte(reg);
i2c_stop();
i2c_start();
ret3=i2c_sendbyte((i2c_client->addr<<1)+1);
ret4=i2c_recvbyte();
i2c_sendack(0x1);
i2c_stop();
if(ret1||ret2||ret3){
pr_err("i2c_write error ret1=%d,ret2=%d,ret3=%d,ret4=%d",ret1,ret2,ret3,ret4);
return -ENXIO;
}
return ret4;
}
一般我们都有硬件的i2c驱动,我们在probe函数里将i2c设备的信息保存下(i2c_client=client,
主要是获取从机地址),然后调用下i2c_init拉高i2c信号的电平,然后替换相应的读写接口,
就可以实现驱动了模拟和硬件i2c驱动兼容了。
static int xxxx_probe(struct i2c_client *client,const struct i2c_device_id *id){
i2c_client=client;
i2c_init();
}
微信全新功能“小程序”在今天正式开放。不过不少网友对于小程序还是有不少的疑问,其中最让网友关心的问题就是小程序究竟占用多少手机内存空间呢?(ps. 为了让大众理解,这里说的手机“内存”是指手机内部的存储空间,也就是常说的32G、64G、128G等,专业人士勿喷)首先看看官方怎么说。从这里可以看出,小程序有点类似于一个网站的快捷方式,大家只要点开这个快捷方式,就可以进入到对应app的网站,并且使用其...
请实现一个算法,确定一个字符串的所有字符是否全都不同。在牛客网刷了一道题目,虽说简单,但自己解决的想法跟直接插入排序的想法类似,感觉挺有趣的,就写了下来。题目如下解决方法。 public boolean checkDifferent(String iniString) { //转为字符数组 char[] c = iniString.toCharArray(); //首先设置为true,假设字符串中的字符都不重复 boolean f_确定一个字符串的所有字符是否全都不同
首先,先了解下 PHP中的curl多线程函数:curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄curl_multi_close — 关闭一组cURL句柄curl_multi_exec — 运行当前 cURL 句柄的子连接curl_multi_getcontent — 如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流curl..._php curl堵塞
自学用,k8s虚拟机centos部署记录_minik8s
Python对Linux系统的管理一、OS模块常用功能1、os模块打开文件方法如下:os.open(filename, flag, [,mode])flag参数说明:os.O_CREAT # 创建文件os.O_RDONLY # 只读方式打开os.O_WRONLY # 只写方式打开os.O_RDWR # 读写方式打开2、os模块对文件进行操作常用方法如下:# 读取文件..._python系统管理
前些天写的MFC程序,每次程序运行后处理大任务时进度条都会出现无响应的情况,只由处理结束才会再次更新,并且是直接更新到进度条满的状态,十分不爽。今天再次运行MFC程序,实在不能忍受这种情况,在网上查找资料,得出解决方案,十分容易。参考http://blog.csdn.net/thinkhy/article/details/5777856MSG msg;while(Pee_mfc 大量循环内 进度条 卡死
我们经常用jquery的选择器,甚至为jquery写插件,今天来讨论一下jquery内部的实现原理。一、关于window.$和window.jQuery其实在jquery中这两个变量就是一个函数对象,即如下的形式window.$=window.jQuery=function(){....}二、关于jQuery.fn和jQuery.prototype其实在jquery中j_jquery的底层原理
每天,信息时代都会用大量数据轰炸我们。现在,专家估计存在的数据字节数是整个可观察宇宙中恒星数量的40倍。就像宇宙一样,我们的数据领域也在迅速扩展-每隔几年,实际上创建的新数据要比人类历史上所有前几年的总和还要多。搜索信号从实践的角度来看,无法渗透的数据的密集墙为投资者和决策者带来了诸多挑战:在那里处理所有可用信息是费力的数据过多会导致“分析瘫痪”,无法做出决定错误信息和媒体偏向为我们的大脑增加了另一层处理能力新闻算法和过滤器气泡强化了我们的个人偏见数据源,即使是高质量的数据源,有时也会._市场告诉我们未来方向
最近无意中发现了一个HHKB的双模替换主控,可以让有线版本的HHKB摇身一变变成蓝牙键盘,二话没说我就先抢了两套。最近刚安装完成,发现效果非常牛逼,连节能模式和手动开关都很齐全,可以说是我近几年来用过的完成度最高的HHKB蓝牙客制化产品了。而且整个改造过程只需要一把十字螺丝刀就可以了,不需要任何的焊接,非常的简单。目前这个产品支持的型号 有HHKB Pro2、HHKB Pro2 Type-S、H..._hhkb lite 已换hhkb pro2 hhkb_ble ydkb.com @yang http://help.ydkb.io/doku.php?id=kb-mods:hhkb
外部中断外部中断一般是由计算机外设发出的中断请指求,如:键盘中断、打印机中断、定时器中断等。外部中断一般指io高低电平来触发并响应io中断函数定时器中断定时器中断是指计数器在晶振的震荡下一直加数一直加到一定数值后溢出产生中断,并进入中断服务函数先把相关的寄存器放上去1:先说外部中断..._外部中断和定时器中断的区别
该系列为imooc Spring从入门到进阶笔记,跟随课程加入自己见解,同时也为项目中碰到一些问题做了解答大纲1、AOP的概述2、AOP的底层实现3、Spring的传统AOP3.1、不带切入点的切面3.2、带有切入点的切面4、Spring的传统AOP的自动代理4.1、基于Bean名称的自动代理4.2、基于切面信息的自动代理1、AOP的概述什么是AOPAspect Oriented Programing 面向切面编程AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码利用AOP可以对业务逻辑_第三章spring aop
How can i used Declare as well as set in my MYSQL WORKBENCH for checked my storeprocedure output in new Query window...It give error like Syntax error, unexpected Declare_sym...at first line with cros...