Giao tiếp I2C cho vi điều khiển

Một phần của tài liệu Giáo trình vi điều khiển cơ bản dùng c++ (Trang 47 - 49)

- Các bit TI và R

Giao tiếp I2C cho vi điều khiển

Giao tiếp I2C cho vi điều khiển 8051

Cũng như giao tiếp UART, I2C là chuẩn giao tiếp nối tiếp sử dụng 2 dây phát triển bởi Philips... cái này có thể tra google để biết thêm, mình sẽ ko giới thiệu về lịch sử phát triển mà hương dẫn bạn code luôn :)

I2C được ứng dụng rất nhiều trong tất cả các thiết bị do lường, cảm biến, module, VDK, IC thời gian thực, EEPROM 24Cxx ... nên khi học VDK bạn sẽ ko thể bỏ qua nó vì các ứng dụng sau này sẽ phải cần đến nó.

Để giao tiếp được với các thiết bị trên ta phải kết nối chúng với nhau qua 2 dây là SDA (dữ liệu 2 chiều) và SCL (xung nhịp). I2C cho phép tất cả các thiết bị có I2C nối chung đường giao tiếp tức là VD có 3 thiết bị có I2C thì có thể dùng chung 2 dây giao tiếp SDA và SCL, tại sao có thể chung như vậy dc là vì tất cả các thiết bị I2C đều phải có 1 địa chỉ riêng(như là mỗi ng có 1 tên vậy - gọi tới ai thì ng đó mới dc giao tiếp) đây là mối quan hệ Chủ-Tớ (Master-Slave)

Khác với PIC và AVR dc tích hợp sẵn 1 cổng I2C thì 8051 hơi thiệt thòi một chút nhưng ko sao ta vẫn có thể giao tiếp bình thường khi xây dựng Hàm thư viện viết sẵn.

/****************Khai báo chân giao tiep I2C***************************/ #define SCL P0_3

#define SDA P0_2

/****************Cac ham giao tiep I2C***************************/ void I2C_time_start(){ SCL = 1; SDA = 1; SDA = 0; SCL = 0; } void I2C_time_stop(){ SCL = 1; SDA = 0; SDA=1; SCL=1; }

unsigned char I2C_write(unsigned char dat){ unsigned char i;

for (i=0;i<8;i++){

SDA = (dat & 0x80); ///? 1:0; SCL=1; SCL=0; dat<<=1; } SCL = 1; SCL = 0; return dat; }

unsigned char I2C_read(void){ bit rd_bit;

unsigned char i, dat; dat = 0x00;

for(i=0;i<8;i++){ /* For loop read data 1 byte */ SCL = 1;

rd_bit = SDA; /* Keep for check acknowledge */ dat = dat<<1;

dat = dat | rd_bit; /* Keep bit data in dat */ SCL = 0; /* Clear SCL */

}

return dat; }

Như code trên ta chỉ cần viết I2C_write(dữ liệu); để gửi dữ liệu đi và I2C_read(); để lấy dữ liệu về Code I2C giao tiếp IC thời gian thực DS1307:

/***************Dia chi giao tiep DS1307*********************/ #define DS1307_SEC 0x00 //Giay

#define DS1307_HOUR 0x02 //Gio #define DS1307_DAY 0x03 //Thu #define DS1307_DATE 0x04 //Ngay #define DS1307_MONTH 0x05 //Thang #define DS1307_YEAR 0x06 //Nam

void DS1307_Write(unsigned char addr,unsigned char dat){ unsigned int temp;

temp = dat ; /*HEX to BCD*/

dat = (((dat/10)*16)|(temp %10)); /*for Led 7seg*/ I2C_time_start(); /* time_start i2c bus */

I2C_write(0XD0); /* Connect to DS1307 */

I2C_write(addr); /* Requetime_5 RAM address on DS1307 */ I2C_write(dat);

I2C_time_stop(); }

unsigned char DS1307_Read(unsigned char addr){ unsigned int tm,ret;

I2C_time_start(); /* time_start i2c bus */ I2C_write(0xD0); /* Connect to DS1307 */

I2C_write(addr); /* Requetime_5 RAM address on DS1307 */ I2C_time_start(); /* time_start i2c bus */

I2C_write(0XD1); /* Connect to DS1307 for Read */ ret = I2C_read(); /* Receive data */ (adsbygoogle = window.adsbygoogle || []).push({});

I2C_time_stop();

Một phần của tài liệu Giáo trình vi điều khiển cơ bản dùng c++ (Trang 47 - 49)