日韩在线免费播放-日韩在线免费av-日韩在线免费-日韩在线毛片-国产高清不卡视频-国产高清不卡

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > IIC裸機(jī)開發(fā)過程

IIC裸機(jī)開發(fā)過程 時間:2017-11-07      來源:未知

IIC是一種電路板級的半雙工多組通信總線

   IIC 即Inter-Integrated Circuit

在同一塊電路板上用于芯片和芯片之間通信(用于多芯片之間的通信)

半雙工:

由于通信介質(zhì)的限制

兩根線:一根線用來傳數(shù)據(jù),另一根線用來同步時鐘(SDA:數(shù)據(jù)總線,SCL:時鐘總線)

兩兩之間都可以進(jìn)行通信,但是必須要由一個芯片開始發(fā)起

 

板級:

在同一塊電路板上用于芯片和芯片之間通信(用于多芯片之間的通信)

半雙工:

由于通信介質(zhì)的限制

兩根線:一根線用來傳數(shù)據(jù),另一根線用來同步時鐘(SDA:數(shù)據(jù)總線,SCL:時鐘總線)

兩兩之間都可以進(jìn)行通信,但是必須要由一個芯片開始發(fā)起

 

IIC串行總線的組成和工作原理

1.采用串行總線技術(shù)可以使系統(tǒng)硬件設(shè)計大大簡化,系統(tǒng)的體積減小,可靠性提高。

同時,系統(tǒng)的更改和擴(kuò)充極為容易。

用于板級的通信(芯片和芯片之間的通信)

用于板級和設(shè)備之間的通信可以用rs232,485,can總線等等來通信

板級通信距離不會太長

 

下面來介紹下IIC的通信原理

1. 通信的發(fā)起和結(jié)束都由主機(jī)控制

2. 每個從設(shè)備都有一個地址

3. 傳輸數(shù)據(jù)的時候,sda對應(yīng)的數(shù)據(jù)信號的寬度 要比scl的高電平的寬度要寬,

sda跳變只能在scl處于低電平的時候 

4. 在scl處于高電平的時候,如果sda產(chǎn)生了高->低的跳變,一次通信開始,低->高的跳變,一次通信結(jié)束

5. 數(shù)據(jù)發(fā)送,一次只發(fā)1個字節(jié),沒法送一個byte打的數(shù)據(jù)的時候,都要回一個ack數(shù)據(jù)位

 

《MPU-6050_DataSheet_V3 4.pdf》描述 從設(shè)備

 

查找從設(shè)備地址



所以AD0值是0。

從設(shè)備地址是0x68











內(nèi)部寄存器地址可以參考《上課用資料\i2c\mpu6050寄存器.doc》

從上圖可以看出,4412提供4個寄存器來完成所有的IIC操作。SDA線上的數(shù)據(jù)從IICDS寄存器經(jīng)過移位寄存器發(fā)出,或通過移位寄存器傳入IICDS寄存器;IICADD寄存器中保存4412當(dāng)做從機(jī)時的地址;IICCON、IICSTAT兩個寄存器用來控制或標(biāo)識各種狀態(tài),比如選擇工作工作模式,發(fā)出S信號、P信號,決定是否發(fā)出ACK信號,檢測是否接收到ACK信號。

主機(jī)是初始化總線的數(shù)據(jù)傳輸并產(chǎn)生允許傳輸?shù)臅r鐘信號

的器件此時任何被尋址的器件都被認(rèn)為是從機(jī)

 

Exynos4412精簡指令集微處理器支持4個IIC總線控制器。為了能使連接在總線上的主和從設(shè)備之間傳輸數(shù)據(jù),專用的數(shù)據(jù)線SDA和時鐘信號線SCL被使用,他們都是雙向的。

如果工作在多主機(jī)的IIC總線模式,多個4412處理器將從從機(jī)那接收數(shù)據(jù)或發(fā)送數(shù)據(jù)給從機(jī)。在IIC總線上的主機(jī)端4412會啟動或終止一個數(shù)據(jù)傳輸。4412的IIC總線控制器會用一個標(biāo)準(zhǔn)的IIC總線仲裁機(jī)制去實現(xiàn)多主機(jī)和多從機(jī)傳輸數(shù)據(jù)。

通過控制如下寄存器以實現(xiàn)IIC總線上的多主機(jī)操作:

控制寄存器: I2CCON

狀態(tài)寄存器: I2CSTAT

Tx/Rx數(shù)據(jù)偏移寄存器: I2CDS

地址寄存器: I2CADD

如果I2C總線空閑,那么SCL和SDA信號線將都為高電平。在SCL為高電平期間,如果SDA有由高到低電平的跳變,那么將啟動一個起始信號,如果SDA有由低到高電平的跳變,將啟動一個結(jié)束信號。

主機(jī)端的設(shè)備總是提供起始和停止信號的一端。在起始信號被發(fā)出后,一個數(shù)據(jù)字節(jié)的前7位被當(dāng)作地址通過SDA線被傳輸。這個地制值決定了總線上的主設(shè)備將要選擇那個從設(shè)備作為傳輸對象,bit8決定傳輸數(shù)據(jù)的方向(是讀還是寫)。

I2C總線上的數(shù)據(jù)(即在SDA上傳輸?shù)臄?shù)據(jù))都是以8位字節(jié)傳輸?shù)模诳偩上傳輸操作的過程中,對發(fā)送或接收的數(shù)據(jù)字節(jié)數(shù)是沒有限制的。I2C總線上的主/從設(shè)備發(fā)送數(shù)據(jù)總是以一個數(shù)據(jù)的高位開始傳輸(即MSB方式),傳輸完一個字節(jié)后,應(yīng)答信號緊接其后。

1. 開始和停止條件

當(dāng)4412的I2C接口空閑時,它往往工作在從機(jī)模式。或者說,4412的的i2c接口在SDA線上察覺到一個起始信號之前它應(yīng)該工作在從機(jī)模式。當(dāng)控制器改變4412的i2c接口的工作模式為主機(jī)模式后,SDA線上發(fā)起數(shù)據(jù)傳輸并且控制器會產(chǎn)生SCL時鐘信號。

開始條件通過SDA線進(jìn)行串行的字節(jié)傳輸,一個停止信號終止數(shù)據(jù)傳輸,停止信號是指SCL在高電平器件SDA線有從低到高電平的跳變,主機(jī)端產(chǎn)生起始和停止條件。當(dāng)主、從設(shè)備產(chǎn)生一個起始信號后,I2C總線將進(jìn)入忙狀態(tài)。這里需要說明的是上述主從設(shè)備都有可能作為主機(jī)端。

當(dāng)一個主機(jī)發(fā)送了一個起始信號后,它也應(yīng)該發(fā)送一個從機(jī)地址以通知總線上的從設(shè)備。這個地址字節(jié)的低7位表示從設(shè)備地址,高位表示傳輸數(shù)據(jù)的方向,即主機(jī)將要進(jìn)行讀還是寫。當(dāng)高位是0時,它將發(fā)起一個寫操作(發(fā)送操作);當(dāng)高位是1時,它將發(fā)起一個讀數(shù)據(jù)的請求(接收操作)。

主機(jī)端發(fā)起一個結(jié)束信號以完成傳輸操作,如果主機(jī)端想在總線上繼續(xù)進(jìn)行數(shù)據(jù)的傳輸,它將發(fā)出另外一個起始信號和從設(shè)備地址。用這樣的方式,它們可以用各種各樣的格式進(jìn)行讀寫操作。



【7】是否回ack

發(fā)送模式下,都是 1

接受模式下,再等待接受data之前,要這個位置0,表示不會回復(fù)ack,

【5】使能中斷

【4】寫0 清中斷,寫1 無效,

每次數(shù)據(jù)傳輸完畢,都要通過判斷該位 ,如果是1 表示中斷被添加,表示對方接受成功





【5】

置1 就發(fā)start信號 s

置0 發(fā)送stop信號 p

【4】長期置1

 

從設(shè)備地址

讀寫的數(shù)據(jù) 緩沖寄存器







父節(jié)點GPX3 27

typedef struct 

{

unsigned int I2CCON;

unsigned int I2CSTAT;

unsigned int I2CADD;

unsigned int I2CDS;

unsigned int I2CLC;

}i2c5;

#define I2C5 (*(volatile i2c5 *)0x138B0000 )

 

#include "exynos_4412.h"

//#include "led.h"

// MPU6050內(nèi)部地址

#define SMPLRT_DIV 0x19 //陀螺儀采樣率,典型值:0x07(125Hz)

#define CONFIG 0x1A //低通濾波頻率,典型值:0x06(5Hz)

#define GYRO_CONFIG 0x1B //陀螺儀自檢及測量范圍,典型值:0x18(不自檢,2000deg/s)

#define ACCEL_CONFIG 0x1C //加速計自檢、測量范圍及高通濾波頻率,典型值:0x01(不自檢,2G,5Hz)

#define ACCEL_XOUT_H 0x3B

#define ACCEL_XOUT_L 0x3C

#define ACCEL_YOUT_H 0x3D

#define ACCEL_YOUT_L 0x3E

#define ACCEL_ZOUT_H 0x3F

#define ACCEL_ZOUT_L 0x40

#define TEMP_OUT_H 0x41

#define TEMP_OUT_L 0x42

#define GYRO_XOUT_H 0x43

#define GYRO_XOUT_L 0x44

#define GYRO_YOUT_H 0x45

#define GYRO_YOUT_L 0x46

#define GYRO_ZOUT_H 0x47

#define GYRO_ZOUT_L 0x48

#define PWR_MGMT_1 0x6B //電源管理,典型值:0x00(正常啟用)

#define WHO_AM_I 0x75 //IIC地址寄存器(默認(rèn)數(shù)值0x68,只讀)

#define SlaveAddress 0xD0 //IIC寫入時的地址字節(jié)數(shù)據(jù),+1為讀取

 

int adc_num;

 

void delay_ms(unsigned int time)

{

int i, j;

while(time--)

{

for (i = 0; i < 5; i++)

for (j = 0; j < 514; j++);

}

}

 

void mydelay_ms(int time)

{

int i, j;

while(time--)

{

for (i = 0; i < 5; i++)

for (j = 0; j < 514; j++);

}

}

 

 

void do_irq()

{

static int a = 1;

int irq_num;

irq_num = CPU0.ICCIAR&0x3ff; //獲取中斷號

switch(irq_num)

{

case 57:

printf("in the irq_handler\n");

if(a)

led_on(1);

else

led_off(1);

a = !a;

EXT_INT41_PEND = EXT_INT41_PEND |((0x1 << 1)); //清GPIO中斷標(biāo)志位

ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 | (0x1 << 25); //清GIC中斷標(biāo)志位

break;

case 75:

printf("in the wdt interrupt\n");

WDT.WTCNT = 180000;

WDT.WTCLRINT = 0;

ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (1 << 11);

break;

case 42:

//printf("in the adc interrupt!\n");

adc_num = ADCDAT&0xfff;

printf("adc = %d\n",adc_num);

CLRINTADC = 0;

IECR2 = IECR2 | (1 << 19);

//42/32

ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 | (1 << 10);

break;

case 76:

printf("in the alarm interrupt!\n");

RTCINTP = RTCINTP | (1 << 1);

ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 12); //清GIC中斷標(biāo)志位

break;

case 77:

printf("in the tic interrupt!\n");

RTCINTP = RTCINTP | (1 << 0);

ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 13); //清GIC中斷標(biāo)志位

break;

}

 

CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num; //清cpu中斷標(biāo)志位

}

 

 

@brief iic read a byte program body

@param[in] slave_addr, addr, &data

@return None

 

void iic_read(unsigned char slave_addr, unsigned char addr, unsigned char *data)

{

I2C5.I2CDS = slave_addr; //將從機(jī)地址寫入I2CDS寄存器中

I2C5.I2CCON = (1 << 7)|(1 << 6)|(1 << 5); //設(shè)置時鐘并使能中斷

I2C5.I2CSTAT = 0xf0; //[7:6]設(shè)置為0b11,主機(jī)發(fā)送模式;

//往[5:4]位寫0b11,即產(chǎn)生啟動信號,發(fā)出IICDS寄存器中的地址

while(!(I2C5.I2CCON & (1 << 4))); // 等待傳輸結(jié)束,傳輸結(jié)束后,I2CCON [4]位為1,標(biāo)識有中斷發(fā)生;

// 此位為1時,SCL線被拉低,此時I2C傳輸停止;

I2C5.I2CDS = addr; //寫命令值

I2C5.I2CCON = I2C5.I2CCON & (~(1 << 4));// I2CCON [4]位清0,繼續(xù)傳輸

while(!(I2C5.I2CCON & (1 << 4)));// 等待傳輸結(jié)束

I2C5.I2CSTAT = 0xD0; // I2CSTAT[5:4]位寫0b01,發(fā)出停止信號

I2C5.I2CDS = slave_addr | 1; //表示要讀出數(shù)據(jù)

I2C5.I2CCON = (1 << 7)|(1 << 6) |(1 << 5) ; //設(shè)置時鐘并使能中斷

I2C5.I2CSTAT = 0xb0;//[7:6]位0b10,主機(jī)接收模式;

//往[5:4]位寫0b11,即產(chǎn)生啟動信號,發(fā)出IICDS寄存器中的地址

I2C5.I2CCON = I2C5.I2CCON & (~(1 << 4));

while(!(I2C5.I2CCON & (1 << 4)));//等待傳輸結(jié)束,接收數(shù)據(jù)

I2C5.I2CCON &= ~((1<<7)|(1 << 4));/* Resume the operation & no ack*/

// I2CCON [4]位清0,繼續(xù)傳輸,接收數(shù)據(jù),

// 主機(jī)接收器接收到后一字節(jié)數(shù)據(jù)后,不發(fā)出應(yīng)答信號 no ack

// 從機(jī)發(fā)送器釋放SDA線,以允許主機(jī)發(fā)出P信號,停止傳輸;

while(!(I2C5.I2CCON & (1 << 4)));// 等待傳輸結(jié)束

I2C5.I2CSTAT = 0x90;

*data = I2C5.I2CDS;

I2C5.I2CCON &= ~(1<<4); /*clean interrupt pending bit */

mydelay_ms(10);

*data = I2C5.I2CDS;

}

 

 @brief iic write a byte program body

 @param[in] slave_addr, addr, data

 @return None

 

void iic_write (unsigned char slave_addr, unsigned char addr, unsigned char data)

{

I2C5.I2CDS = slave_addr;

I2C5.I2CCON = (1 << 7)|(1 << 6)|(1 << 5) ;

I2C5.I2CSTAT = 0xf0;

while(!(I2C5.I2CCON & (1 << 4)));

I2C5.I2CDS = addr;

I2C5.I2CCON = I2C5.I2CCON & (~(1 << 4));

while(!(I2C5.I2CCON & (1 << 4)));

I2C5.I2CDS = data;

I2C5.I2CCON = I2C5.I2CCON & (~(1 << 4));

while(!(I2C5.I2CCON & (1 << 4)));

I2C5.I2CSTAT = 0xd0;

I2C5.I2CCON = I2C5.I2CCON & (~(1 << 4));

mydelay_ms(10);

}

 

void MPU6050_Init ()

{

iic_write(SlaveAddress, PWR_MGMT_1, 0x00);

iic_write(SlaveAddress, SMPLRT_DIV, 0x07);

iic_write(SlaveAddress, CONFIG, 0x06);

iic_write(SlaveAddress, GYRO_CONFIG, 0x18);

iic_write(SlaveAddress, ACCEL_CONFIG, 0x01);

}

 

int get_data(unsigned char addr)

{

char data_h, data_l;

iic_read(SlaveAddress, addr, &data_h);

iic_read(SlaveAddress, addr+1, &data_l);

return (data_h<<8)|data_l;

}

 

/*

* 裸機(jī)代碼,不同于LINUX 應(yīng)用層, 一定加循環(huán)控制

*/

 

int main()

{

int data;

unsigned char zvalue;

GPB.CON = (GPB.CON & ~(0xff<<8)) | 0x33<<8; // GPBCON[3], I2C_5_SCL GPBCON[2], I2C_5_SDAn

mydelay_ms(100);

uart_init();

 

I2C5.I2CSTAT = 0xD0;

I2C5.I2CCON &= ~(1<<4); /*clean interrupt pending bit */

 

mydelay_ms(100);

MPU6050_Init();

mydelay_ms(100);

printf("\n********** I2C test!! ***********\n");

while(1)

{

//Turn on

data = get_data(GYRO_ZOUT_H);

printf(" GYRO --> Z <---:Hex: %x", data);

data = get_data(GYRO_XOUT_H);

printf(" GYRO --> X <---:Hex: %x", data);

printf("\n");

mydelay_ms(1000);

}

return 0;

}

上一篇:第一人稱視角移動問題

下一篇:C++中的static關(guān)鍵字的總結(jié)

熱點文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗分享
熱點新聞推薦
前臺專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部

主站蜘蛛池模板: 住院吸氧是一天24小时算钱吗| 电影在线观看网址| 希比·布拉奇克| 女生宿舍2在线| 腰带之下| 春香传在线观看| 李姝| 一个国家的诞生| 黄老汉| 傅首尔个人资料| 日本十大歌姬排名| 美女的逼逼视频| 黄柳霜| 杨佑宁个人简历| 四查四看自我剖析材料| 路易·德·菲奈斯| 廖凡演的电影| 王岗个人简历| 故都的秋ppt| 吉泽明步 番号| free hd xxxx moms movie777| 浙江卫视全天节目表| 小敏家演员表| 楚青丝完美人生免费阅读| 不毛地带| 石灰和碱的6种配方| 蒋昌义| 即便是爸爸也想恋爱| 老男人电影完整版高清在线观看| 在线观看韩国电影| 跳墙| 巴霍巴利王2国语版免费中文版 | 液氨化学性质| 北京1号线地铁站点线路图| 黄昏光影| bb88| 十大名茶排名顺序| 河南卫视直播| 寡妇 电影| 蓝燕3d电影《极乐宝鉴》在线观看| cctv6电影节目表|