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