導航:首頁 > 程序命令 > 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命令相關的資料

熱點內容
linux樹形目錄 瀏覽:727
平方根的簡單演算法 瀏覽:898
千牛訂單頁面信息加密取消 瀏覽:558
單片機自製紅外遙控燈 瀏覽:719
伺服器最小配置怎麼弄 瀏覽:853
ibm伺服器硬體如何升級 瀏覽:923
全球程序員節點贊 瀏覽:986
php函數傳遞數組 瀏覽:631
人工峰群演算法的目標函數 瀏覽:468
如何刪加密文檔 瀏覽:105
塗鴉app一鍵執行如何刪除 瀏覽:756
安卓手機如何打開fr3文件 瀏覽:743
壓縮袋8絲和14絲是什麼意思 瀏覽:647
程序員大咖java 瀏覽:70
蘋果手機文檔安卓上怎麼打開 瀏覽:527
如何做淘寶代理伺服器 瀏覽:672
gz壓縮文件夾 瀏覽:179
字母h從右往左跑的c語言編程 瀏覽:137
安卓手機如何擁有蘋果手機橫條 瀏覽:771
業余編程語言哪個好學 瀏覽:151