em đang tìm hiểu cái giao tiếp i2c master mode, về cơ bản thì hiểu được cách làm việc của i2c master mode rồi và quy trình truyền nhận dữ liệu thông qua i2c master mode. sau đó em viết một đoạn code để ghi dữ liệu vào rom sau đó đọc dữ liệu vừa ghi và xuất ra port B nhưng kỳ lạ là em làm mãi mà nó ko chạy, thậm chí xài code mẫu của cả MikroC nó cũng ko chạy luôn. các anh chỉ dùm coi em sai chỗ nào với ah???
code của các hàm sử dụng trong chương trình
chương trình chính:
code mẫu của MikroC
và chả cái nào chịu chạy, em mô phỏng bằng proteus, và cả mạch thực tế
code của các hàm sử dụng trong chương trình
Code:
#include <htc.h>
#include "i2c_887.h"
void i2c_init()
{
// config IO port
TRISC3=1; //pin SCL is input
TRISC4=1; //pin SDA is input
// config SSPCON register
SSPCON=0x28; //SSPEN=1; enable MSSP module
//SMP<3:0> = 1000 I2C master mode Baudrate=Fosc/(4*(SSPADD+1))
SSPCON2=0x00;
// config frequency clock at SCL pin
SSPADD=9; //100Khz with 4Mhz Xtal
//Baudrate=Fosc/(4*(SSPADD+1))
SMP=1; //slew rate control disable for 100khz baudrate
SSPIF=0; //clear Master Synchronous Serial Port (MSSP) Interrupt Flag bit
}
//---------------------------------------------------------
void i2c_waitforidle()
{
while((SSPCON2 & 0x1F)|R_W); //waiting for idle and writing
}
//---------------------------------------------------------
void i2c_start()
{
i2c_waitforidle(); //waiting for idle and writing
SEN=1; //initilazing start condition
while(SEN); //waiting for start condition generated
}
//---------------------------------------------------------
void i2c_stop()
{
i2c_waitforidle(); //waiting for idle and writing
PEN=1; //initilazing stop condition
while(PEN); //waiting for stop condition generated
}
//---------------------------------------------------------
void i2c_restart()
{
i2c_waitforidle(); //waiting for idle and writing
RSEN=1; //initilazing Repeat start condition
while(RSEN); //waiting for Restart condition generated
}
//---------------------------------------------------------
unsigned char i2c_write(unsigned char data)
{
i2c_waitforidle(); //waiting for idle and writing
WCOL=0; //not transmit data when transmission mode not ready
SSPBUF=data; //send data to SSPBUFF
asm("nop"); //waiting for data transmission is completed
asm("nop");
asm("nop");
return (!ACKSTAT); //return '1' if transmission is acknowledge, everything is ok
}
//---------------------------------------------------------
unsigned char i2c_read(unsigned char ack)
{
unsigned char data;
i2c_waitforidle(); //waiting for idle and writing
SSPOV=0; //not allowed to receive new data while old data is not being read
RCEN=1; //enable receive data
while(RCEN); //waiting for data receiving
data=SSPBUF; //read data
ACKDT=ack; //ack = 1: Not ACK; ack = 0: ACK
ACKEN=1; //acknowledge sequence enable
while(ACKEN); //waiting for ACK signal generated
return data;
}
chương trình chính:
Code:
//*********************************************************
#include <htc.h>
#include "i2c_887.h"
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & LVP_OFF & DEBUG_OFF &
BOREN_OFF & CP_ON & CPD_ON & FCMEN_OFF & IESO_OFF); //1st config. word
__CONFIG(BOR4V_BOR21V); //2nd config. word
#define _XTAL_FREQ 4000000 // XTAL 4MHz
/******************************************************************************************/
void main()
{
unsigned char data=0;
ANSEL=0;
ANSELH=0;
TRISB=0;
PORTB=0;
i2c_init();
i2c_start();
i2c_write(0xa0); //truyen dia chi eeprom: 7-bit address + w(0)
i2c_write(0x00); //truyen dia chi thanh ghi cua eeprom
i2c_write(0xAA); //ghi du lieu 0xAA vao eeprom
i2c_stop();
__delay_ms(100);
__delay_ms(100);
i2c_start();
i2c_write(0xa0); //truyen dia chi eeprom: 7-bit address + w(0)
i2c_write(0x00); //truyen dia chi thanh ghi cua eeprom
i2c_restart(); //tao dieu kien restart
i2c_write(0xa1); //truyen dia chi eeprom: 7-bit address + R(1)
data=i2c_read(1); //doc du lieu tu eeprom
i2c_stop();
while(1)
{
PORTB=data;
}
}
code mẫu của MikroC
Code:
void main(){
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
PORTB = 0;
TRISB = 0; // Configure PORTB as output
I2C1_Init(100000); // initialize I2C communication
I2C1_Start(); // issue I2C start signal
I2C1_Wr(0xA0); // send byte via I2C (device address + W)
I2C1_Wr(2); // send byte (address of EEPROM location)
I2C1_Wr(0xAA); // send data (data to be written)
I2C1_Stop(); // issue I2C stop signal
Delay_100ms();
I2C1_Start(); // issue I2C start signal
I2C1_Wr(0xA0); // send byte via I2C (device address + W)
I2C1_Wr(2); // send byte (data address)
I2C1_Repeated_Start(); // issue I2C signal repeated start
I2C1_Wr(0xA1); // send byte (device address + R)
PORTB = I2C1_Rd(0u); // Read the data (NO acknowledge)
I2C1_Stop(); // issue I2C stop signal
}

Comment