congtri91
14-09-2012, 04:31 PM
Em đang tìm hiểu về giao tiếp I2C của PIC và thử cho nó giao tiếp giữa pic16f887 và eeprom 24c04. chương trình đơn giản chỉ thực hiện việc ghi một byte vào thanh ghi của eeprom và sau đó đọc ngược giá trị vừa ghi để xuất ra portB. tuy nhiên em làm thế nào nó cũng ko thể giao tiếp được. Nguyên tuần vừa rồi em ngồi google, đọc các bài viết trên 4rum nhưng ko thể nào làm cho nó chạy được. mong các bác giúp em.
em dùng htpic v9.83
đây là thư viện cho nó
/************************************************** ********
* Hardware I2C for PIC16F887 in master mode
*
* Compier: HT PIC
* Author: Truong Cong Tri
* Modified from example of Michael Alon on microchipc.com
************************************************** *********
* LIST FUNCTIONS
*
* i2c_init() - initilazing i2c master mode
* i2c_start() - issue start condition
* i2c_stop() - issue stop condition
* i2c_restart() - issue re-start condition
* i2c_write() - send 1-byte data
* i2c_read(ack) - read 1-byte data: ack=1 -> NACK, ack=0 -> ACK
*
* i2c_waitforidle() - waiting for idle and writing
*---------------------------------------------------------*/
#include <htc.h>
#include "hardware_i2c.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
while(R_W) //waiting for data transmission is completed
return (!ACKSTAT); //return '1' if transmission is acknowledge
}
//---------------------------------------------------------
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;
}
còn đây là chương trình ghi và đọc 1 byte từ eeprom
/************************************************** ********
* I2C communicate protocol PIC16F887 and 24CXX eeprom
*
* Complier: Hitech PIC C V9.83
* MCU: PIC16F887
* Xtal: 4Mhz
* Author: Truong Cong Tri
************************************************** ********/
#include <htc.h>
#include "hardware_i2c.h"
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & LVP_OFF & DEBUG_OFF &
BOREN_OFF & CP_OFF & CPD_OFF & FCMEN_OFF & IESO_OFF); //1st config. word
__CONFIG(BOR4V_BOR21V); //2nd config. word
#define _XTAL_FREQ 4000000 // XTAL 4MHz
//************************************************** *******
//================================================== =======
// MAIN
//================================================== =======
void main()
{
ANSEL =0;
ANSELH=0;
TRISB=0;
PORTB=0;
i2c_init(); //initilazing I2C
//write 1-byte to eeprom
i2c_start(); //send start condition
i2c_write(0xA0); //send eeprom address + W
i2c_write(0x00); //send address register of eeprom
i2c_write(0xAA); //send 1-byte to eeprom
i2c_stop(); //send stop condition
__delay_ms(150);
//read 1-byte from eeprom
i2c_start(); //send start condition
i2c_write(0xA0); //send eeprom address + W
i2c_write(0x00); //send address register of eeprom
i2c_restart(); //send Repeat Start condition
i2c_write(0xA1); //send eeprom address + R
PORTB=i2c_read(1); //read 1-byte form eeprom
i2c_stop(); //send stop condition
while(1); //stop at here
}
em dùng htpic v9.83
đây là thư viện cho nó
/************************************************** ********
* Hardware I2C for PIC16F887 in master mode
*
* Compier: HT PIC
* Author: Truong Cong Tri
* Modified from example of Michael Alon on microchipc.com
************************************************** *********
* LIST FUNCTIONS
*
* i2c_init() - initilazing i2c master mode
* i2c_start() - issue start condition
* i2c_stop() - issue stop condition
* i2c_restart() - issue re-start condition
* i2c_write() - send 1-byte data
* i2c_read(ack) - read 1-byte data: ack=1 -> NACK, ack=0 -> ACK
*
* i2c_waitforidle() - waiting for idle and writing
*---------------------------------------------------------*/
#include <htc.h>
#include "hardware_i2c.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
while(R_W) //waiting for data transmission is completed
return (!ACKSTAT); //return '1' if transmission is acknowledge
}
//---------------------------------------------------------
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;
}
còn đây là chương trình ghi và đọc 1 byte từ eeprom
/************************************************** ********
* I2C communicate protocol PIC16F887 and 24CXX eeprom
*
* Complier: Hitech PIC C V9.83
* MCU: PIC16F887
* Xtal: 4Mhz
* Author: Truong Cong Tri
************************************************** ********/
#include <htc.h>
#include "hardware_i2c.h"
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & LVP_OFF & DEBUG_OFF &
BOREN_OFF & CP_OFF & CPD_OFF & FCMEN_OFF & IESO_OFF); //1st config. word
__CONFIG(BOR4V_BOR21V); //2nd config. word
#define _XTAL_FREQ 4000000 // XTAL 4MHz
//************************************************** *******
//================================================== =======
// MAIN
//================================================== =======
void main()
{
ANSEL =0;
ANSELH=0;
TRISB=0;
PORTB=0;
i2c_init(); //initilazing I2C
//write 1-byte to eeprom
i2c_start(); //send start condition
i2c_write(0xA0); //send eeprom address + W
i2c_write(0x00); //send address register of eeprom
i2c_write(0xAA); //send 1-byte to eeprom
i2c_stop(); //send stop condition
__delay_ms(150);
//read 1-byte from eeprom
i2c_start(); //send start condition
i2c_write(0xA0); //send eeprom address + W
i2c_write(0x00); //send address register of eeprom
i2c_restart(); //send Repeat Start condition
i2c_write(0xA1); //send eeprom address + R
PORTB=i2c_read(1); //read 1-byte form eeprom
i2c_stop(); //send stop condition
while(1); //stop at here
}