导航:首页 > 程序命令 > i2c命令

i2c命令

发布时间:2022-08-09 03:21:29

1. EEPROM中读过程中用I2C先发写器件地址再发数据地址再发读器件地址,问题见补充,请用自己的理解讲一下

其实每次有出现”开始位“时,就相当于进行一次命令,每次命令开始都是要发I2C设备的器件地址的,

而其实读是建立在写的基础上的,相当进行两次操作,所以发了2次I2C器件地址

2. 单片机IO上挂很多个I2C接口,I2C0~I2C3,我现在想给I2C1所接的从设备写入命令,程序应该如何实现

IIC上的每个从器件都要一个地址,很多器件都是通过硬件来确定地址的,有的在出厂时地址就设置好了,用户不可以更改;有的确定了几位,剩下几位由硬件确定(比如有三位由用户确定,就留有3个控制地址的引脚),此类较多。

通信时主机往总线上发送地址(这个地址是某个从机的),所有的从机都能接收到主机发出的地址,然后每个从机都将主机发出的地址与自己的地址比较,如果匹配上了,这个从机就会向主机发出一个响应信号。主机收到响应信号后,开始向总线上发送数据,与这个从机的通讯就建立起来了。如果主机没有收到响应信号,则表示寻址失败。

3. 51单片机I2C总线问题,郭天祥51的188页,有3个问题不懂,第一,这个write是个啥,为啥用

bit和uchar 之类的差不多,只不过uchar=8位, bit=1位而已。都是变量,编译器在编译过程中分配地址。除非你指定,否则这个地址是随机的。这个地址是整个可寻址空间,RAM+FLASH+
扩展空间。
bit只有0和1两种值。uchar有256种值。

code是存储在单片机的flash里面,不是存在内存里面了。所以一般固定意义的数据,比如数码管的段码,一个图片的数据信息,都是用code定义,让这些数据放在flash里面,节省内存空间。因为51单片机的RAM很少,只有128(或者256)字节,要是定义的数据(而且是在使用时不做改变的)太多,RAM肯存不下。所以定义code,放在flash里面。要知道52单片机的flash有8K字节!远比256字节的RAM多。

4. I2C协议怎么写

void delay_scl()
{
unsigned data i=10;
do
{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(--i);
}
void delay(unsigned char data k)//精确延时k*0.1us
{
unsigned char data i=250;
do{do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}//执行一个nop为1个时钟周期
while(--i);}
while(--k);//执行一个while为2个时钟周期
}

void i2c_init() //I2C的初始化:SDA和SCL都为高电平
{
sda=1;
delay_scl();
scl=1;
delay_scl();
}
void i2c_start() //开始信号
{
i2c_init();
sda=0;
delay_scl();
}
void i2c_stop() //停止信号
{
sda=0;
delay_scl();
scl=1;
delay_scl();
sda=1;
delay_scl();
}
void i2c_response() //应答信号
{
unsigned char xdata i;
scl=1;
delay_scl();
while((sda==1)&&(i<250))i++;
scl=0;
delay_scl();
}
void i2cwrite_byte(unsigned char data dat) //写1个字节
{unsigned char xdata i,temp;
temp=dat;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay_scl();
sda=CY;
delay_scl();
scl=1;
delay_scl();
}
scl=0;
delay_scl();
sda=1;
delay_scl();
}
unsigned char i2cread_byte() //读1个字节
{
unsigned char xdata i,k;
scl=0;
delay_scl();
sda=1;
delay_scl();
for(i=0;i<8;i++)
{
scl=1;
delay_scl();
k=(k<<1)|sda;
scl=0;
delay_scl();
}
return k;
}
void i2cwrite_add(unsigned char data address,unsigned char data dat) //写数据,1个字节地址位,1个字节数据
{
i2c_start();
i2cwrite_byte(0xEE); // 16进制Oxa0转成8bit二进制数:前7位是设备号,末位"0"表示向设备写入。
i2c_response();
i2cwrite_byte(address); //写地址
i2c_response();
i2cwrite_byte(dat); //写数据
i2c_response();
i2c_stop();
delay(100); //收到stop命令后,需twr时间来写数据,此期间不接收任何信息
}
unsigned char I2Cread_add(unsigned char data address) //读数据,1个字节地址位,函数返回数据值
{
unsigned char xdata dat;
i2c_start();
i2cwrite_byte(0xEE); //16进制Oxa0转成8bit二进制数:前7位是设备号,末位"0"表示向设备写入。
i2c_response();
i2cwrite_byte(address); //向设备写入需要查找的地址(移动设备内指针)
i2c_response();
i2c_start(); //刷新,再次查找设备
i2cwrite_byte(0xEF); // 16进制Oxa0转成8bit二进制数:前7位是设备号,末位"1"表示从设备读取。
i2c_response();
dat=i2cread_byte(); //读取数据
i2c_stop(); //读完后主机返回"非应答"(高电平),并直接发出终止信号
delay(10);
return dat;
}

5. I2C读写问题

你说的RAM不能读写是指单片机上的用来存储数据的RAM不能读写吗?有没有对RAM的使用情况进行检查?包括堆栈的使用,是否有RAM溢出?

有点明白了,你想做的是利用IIC通信发送命令,把1043的RAM数据写到ROM上,目的是通过ROM数据更新来控制1043的输出。但是ROM数据写进去了(说明IIC通信没有问题)却没有实现输出控制,是这样吧?

我分析是这样,ROM数据写入成功了,说明IIC通信部分没有问题,建议你别在这上面花费时间调查了,1043这个芯片我也没用过,但是一般进行过ROM的更新后会有其他的时序要求才能使更新的数据起作用,比如进行芯片的RESET,或重启启动时序,或写某个寄存器等等,建议你好好看一下1043的芯片手册,从这方面展开调查,真想帮你,不过嵌入式开发没有仿真环境真的很难调查问题。希望我的提示能有帮助。

6. #define I2C0CONSET (*((volatile unsigned char *) 0xE001C000))是什么意思

#define是预处理命令, 用来对关键字进行文本替换, 这里是不带参数的简单替换
把代码中I2C0CONSET替换为(*((volatile unsigned char *) 0xE001C000))

(volatile unsigned char *)括号里是类型, 是强制类型转换
把0xE001C000转换为这个类型的指针
指针除了要有地址,还要有地址里数据的类型, 没有类型的话计算机不知道是要读2个字节还是4个字节,也不知道是无符号还是有符号等等

volatile 是告诉编译器变量的值可能在不知道的情况下改变,防止编译器自动优化

再前面的*是指针解引用, 指针是unsigned char*的, 地址是0xE001C000, 解引用后就是0xE001C000里存的unsigned char值

7. i2c的数据线只是传输控制命令吗

都需要的
写完数据之后释放数据线是为了等待从机相应(即拉低sda)
而读的时候主机释放数据线的道理也很简单
毕竟此时是从机往数据线写数据
而主机要做的就是当从机写完一个字节后拉低数据线产生一个相应(当然可以不响应)

8. 如何通过设备节点查看i2c设备

linux下生成驱动设备节点文件的方法有3个:1、手动mknod;2、利用devfs;3、利用udev
在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点。
在2.6.17以前,在/dev目录下生成设备文件很容易,
devfs_mk_bdev
devfs_mk_cdev
devfs_mk_symlink
devfs_mk_dir
devfs_remove
这几个是纯devfs的api,2.6.17以前可用,但后来devfs被sysfs+udev的形式取代,同时期sysfs文件系统可以用的api:
class_device_create_file,在2.6.26以后也不行了,现在,使用的是device_create ,从2.6.18开始可用
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, const char *fmt, …)
从2.6.26起又多了一个参数drvdata: the data to be added to the device for callbacks
不会用可以给此参数赋NULL
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, …)
下面着重讲解第三种方法udev
在驱动用加入对udev的支持主要做的就是:在驱动初始化的代码里调用class_create(…)为该设备创建一个class,再为每个设备调用device_create(…)( 在2.6较早的内核中用class_device_create)创建对应的设备。
内核中定义的struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
struct class和class_create(…) 以及device_create(…)都包含在在/include/linux/device.h中,使用的时候一定要包含这个头文件,否则编译器会报错。
struct class定义在头文件include/linux/device.h中
class_create(…)在/drivers/base/class.c中实现
device_create(…)函数在/drivers/base/core.c中实现
class_destroy(…),device_destroy(…)也在/drivers/base/core.c中实现调用过程类似如下:
static struct class *spidev_class;
/*-------------------------------------------------------------------------*/
static int __devinit spidev_probe(struct spi_device *spi)
{

dev =device_create(spidev_class, &spi->dev, spidev->devt,
spidev, “spidev%d.%d”,
spi->master->bus_num, spi->chip_select);

}
static int __devexit spidev_remove(struct spi_device *spi)
{
……
device_destroy(spidev_class, spidev->devt);
……
return 0;
}
static struct spi_driver spidev_spi = {
.driver = {
.name = “spidev”,
.owner = THIS_MODULE,
},
.probe = spidev_probe,
.remove = __devexit_p(spidev_remove),
};
/*-------------------------------------------------------------------------*/
static int __init spidev_init(void)
{

spidev_class =class_create(THIS_MODULE, “spidev”);
if (IS_ERR(spidev_class)) {
unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
return PTR_ERR(spidev_class);
}

}
mole_init(spidev_init);
static void __exit spidev_exit(void)
{
……
class_destroy(spidev_class);
……
}
mole_exit(spidev_exit);
MODULE_DESCRIPTION(“User mode SPI device interface”);
MODULE_LICENSE(“GPL”);
下面以一个简单字符设备驱动来展示如何使用这几个函数
#include <linux/mole.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
int HELLO_MAJOR = 0;
int HELLO_MINOR = 0;
int NUMBER_OF_DEVICES = 2;
struct class *my_class;
//struct cdev cdev;
//dev_t devno;
struct hello_dev {
struct device *dev;
dev_t chrdev;
struct cdev cdev;
};
static struct hello_dev *my_hello_dev = NULL;
struct file_operations hello_fops = {
.owner = THIS_MODULE
};
static int __init hello_init (void)
{
int err = 0;
struct device *dev;
my_hello_dev = kzalloc(sizeof(struct hello_dev), GFP_KERNEL);
if (NULL == my_hello_dev) {
printk(“%s kzalloc failed!\n”,__func__);
return -ENOMEM;
}
devno = MKDEV(HELLO_MAJOR, HELLO_MINOR);
if (HELLO_MAJOR)
err= register_chrdev_region(my_hello_dev->chrdev, 2, “memdev”);
else
{
err = alloc_chrdev_region(&my_hello_dev->chrdev, 0, 2, “memdev”);
HELLO_MAJOR = MAJOR(devno);
}
if (err) {
printk(“%s alloc_chrdev_region failed!\n”,__func__);
goto alloc_chrdev_err;
}
printk(“MAJOR IS %d\n”,HELLO_MAJOR);
cdev_init(&(my_hello_dev->cdev), &hello_fops);
my_hello_dev->cdev.owner = THIS_MODULE;
err = cdev_add(&(my_hello_dev->cdev), my_hello_dev->chrdev, 1);
if (err) {
printk(“%s cdev_add failed!\n”,__func__);
goto cdev_add_err;
}
printk (KERN_INFO “Character driver Registered\n”);
my_class =class_create(THIS_MODULE,“hello_char_class”); //类名为hello_char_class
if(IS_ERR(my_class))
{
err = PTR_ERR(my_class);
printk(“%s class_create failed!\n”,__func__);
goto class_err;
}
dev = device_create(my_class,NULL,my_hello_dev->chrdev,NULL,“memdev%d”,0); //设备名为memdev
if (IS_ERR(dev)) {
err = PTR_ERR(dev);
gyro_err(“%s device_create failed!\n”,__func__);
goto device_err;
}
printk(“hello mole initialization\n”);
return 0;
device_err:
device_destroy(my_class, my_hello_dev->chrdev);
class_err:
cdev_del(my_hello_dev->chrdev);
cdev_add_err:
unregister_chrdev_region(my_hello_dev->chrdev, 1);
alloc_chrdev_err:
kfree(my_hello_dev);
return err;
}
static void __exit hello_exit (void)
{
cdev_del (&(my_hello_dev->cdev));
unregister_chrdev_region (my_hello_dev->chrdev,1);
device_destroy(my_class, devno); //delete device node under /dev//必须先删除设备,再删除class类
class_destroy(my_class); //delete class created by us
printk (KERN_INFO “char driver cleaned up\n”);
}
mole_init (hello_init);
mole_exit (hello_exit);
MODULE_LICENSE (“GPL”);
这样,模块加载后,就能在/dev目录下找到memdev这个设备节点了。
例2:内核中的drivers/i2c/i2c-dev.c
在i2cdev_attach_adapter中调用device_create(i2c_dev_class, &adap->dev,
MKDEV(I2C_MAJOR, adap->nr), NULL,
“i2c-%d”, adap->nr);
这样在dev目录就产生i2c-0 或i2c-1节点
接下来就是udev应用,udev是应用层的东西,udev需要内核sysfs和tmpfs的支持,sysfs为udev提供设备入口和uevent通道,tmpfs为udev设备文件提供存放空间
udev的源码可以在去相关网站下载,然后就是对其在运行环境下的移植,指定交叉编译环境,修改Makefile下的CROSS_COMPILE,如为mipsel-linux-,DESTDIR=xxx,或直接make CROSS_COMPILE=mipsel-linux-,DESTDIR=xxx 并install
把主要生成的udevd、udevstart拷贝rootfs下的/sbin/目录内,udev的配置文件udev.conf和rules.d下的rules文件拷贝到rootfs下的/etc/目录内
并在rootfs/etc/init.d/rcS中添加以下几行:
echo “Starting udevd…”
/sbin/udevd --daemon
/sbin/udevstart
(原rcS内容如下:
# mount filesystems
/bin/mount -t proc /proc /proc
/bin/mount -t sysfs sysfs /sys
/bin/mount -t tmpfs tmpfs /dev
# create necessary devices
/bin/mknod /dev/null c 1 3
/bin/mkdir /dev/pts
/bin/mount -t devpts devpts /dev/pts
/bin/mknod /dev/audio c 14 4
/bin/mknod /dev/ts c 10 16

这样当系统启动后,udevd和udevstart就会解析配置文件,并自动在/dev下创建设备节点文件

9. i2c-tools 操作风扇转速

需要装个debian chroot,加载内核模块,然后把 /dev挂载到chroot环境的/dev,在chroot里边装软件控制就行,网速慢的话可以改成国内的源。i2cset -y 0 0x54 0xf0 xxx
上面这个命令就是改风扇转速的,xxx就是转速。

阅读全文

与i2c命令相关的资料

热点内容
php开发客户端 浏览:998
theisle测试服怎么搜服务器 浏览:447
广播PDF 浏览:218
单片机编程300例汇编百度 浏览:35
腾讯云连接不上服务器 浏览:223
不能用来表示算法的是 浏览:861
6轴机器人算法 浏览:890
手机主题照片在哪个文件夹 浏览:294
安卓手机后期用什么软件调色 浏览:628
cad修改快捷键的命令 浏览:242
好钱包app怎么登录不了 浏览:859
树莓派都用python不用c 浏览:757
access文件夹树的构造 浏览:662
安卓多指操作怎么设置 浏览:658
linux树形目录 浏览:727
平方根的简单算法 浏览:898
千牛订单页面信息加密取消 浏览:558
单片机自制红外遥控灯 浏览:719
服务器最小配置怎么弄 浏览:853
ibm服务器硬件如何升级 浏览:923