查看: 2265|回复: 6
|
如何让两颗IC用I2C来沟通?
[复制链接]
|
|
我是MMU的学生,有一个功课需要用到I2C来让两颗IC来沟通,可是我没用过这功能。我写了各种各样的程序,可是都没有进展。我用的IC 是PIC16F887. 可否请各位老师帮忙看看我的程序到底哪里出现了问题。谢谢!
这是发送DATA的程序:
#include <16F887.h>
#fuses INTRC
#use delay(clock = 4000000)
#define EEPROM_SDA PIN_D0
#define EEPROM_SCL PIN_D1
#use I2C(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 32768
BYTE data;
void init_ext_eeprom()
{
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
void write_ext_eeprom(BYTE address, BYTE datarom)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_write(datarom);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
}
void main(){
setup_oscillator(OSC_4MHZ);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
enable_interrupts(INT_RB0);
enable_interrupts(INT_RB);
enable_interrupts(INT_SSP);
output_low(PIN_C4);
init_ext_eeprom();
write_ext_eeprom(0x01,0x01);
}
这是接收DATA的程序(用在另一颗IC):
#include <16F887.h>
#fuses INTRC
#use delay(clock = 4000000)
#define EEPROM_SDA PIN_D0
#define EEPROM_SCL PIN_D1
#use I2C(SLAVE, sda=EEPROM_SDA, scl=EEPROM_SCL, address=0xa0)
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 32768
BYTE data;
BYTE datarom;
BYTE ext_address;
BYTE address[10];
void init_ext_eeprom()
{
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
void read_ext_eeprom() {
i2c_start();
i2c_write(0xa1);
ext_address=i2c_read(0);
datarom=i2c_read(0);
i2c_stop();
address[ext_address]=datarom;
}
#INT_SSP
void ssp_interupt ()
{
read_ext_eeprom();
}
void main(){
setup_oscillator(OSC_4MHZ);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
output_low(PIN_C4);
init_ext_eeprom();
while(true){
if(address[0x01]==0x01){
output_high(PIN_C4);
}
}
} |
|
|
|
|
|
|
|
发表于 24-8-2009 06:56 PM
|
显示全部楼层
可以讲一下是什么应用吗?
然后是什么IC 和 什么IC 要用I2C? 然后为什么? |
|
|
|
|
|
|
|
发表于 24-8-2009 11:59 PM
|
显示全部楼层
刚好手上有讲到I2C的书。。
完全看不懂。。。 |
|
|
|
|
|
|
|
楼主 |
发表于 26-8-2009 02:23 PM
|
显示全部楼层
回复 2# pic 的帖子
我想用其中一颗IC来送DATA,另一颗IC来接收DATA。它们的沟通是必须用I2C FUNCTION, 两颗是IC都是16F877。 |
|
|
|
|
|
|
|
楼主 |
发表于 26-8-2009 02:31 PM
|
显示全部楼层
回复 4# xiao1987 的帖子
对不起,我刚刚写错了,两颗 IC 是16F887. |
|
|
|
|
|
|
|
发表于 27-8-2009 09:50 PM
|
显示全部楼层
以下代码希望对楼主你有所帮助。
我用的是16F677,slave接收的。Compiler是用CCS。
#include "C:\MCU_Project\main.h"
void Configuration(void);
void Reset(void);
void SSP_Command(void);
void VADC_Conversion(void);
unsigned char Run;
unsigned char ADDR;
int16 Conversion;
unsigned char Tdata[3];
//------------------------------------------------------------------------------
//--------------------------- Basic Function -----------------------------------
//------------------------------------------------------------------------------
//*****************************************************************************//
//* Configuration *//
//*---------------------------------------------------------------------------*//
//* Description : Initilaze Device Setting *//
//* *//
//* Supported Devices : PIC16F677/PIC16F687/PIC16F689/PIC16F690 *//
//* *//
//* Prototype : void Configuration(void) *//
//* *//
//* Parameters : Nothing *//
//* *//
//* Return Value : Nothing *//
//* *//
//* Create Date : 12/07/2008 *//
//* Re-create Date : 15/11/2008 *//
//*****************************************************************************//
void Configuration(void)
{
// Clear All ports to active low
OUTPUT_A(0x00);
OUTPUT_B(0x00);
OUTPUT_C(0x00);
SET_TRIS_A(0xFF); // BIT 5:0 Input
SET_TRIS_B(0xFF); // BIT 7:4 Input
SET_TRIS_C(0xFF); // BIT 7:0 Input
ADDR = 0xF0;
i2c_SlaveAddr(ADDR);
}
//------------------------------------------------------------------------------
//----------------------------- Slave Function----------------------------------
//------------------------------------------------------------------------------
//*****************************************************************************//
//* Reset *//
//*---------------------------------------------------------------------------*//
//* Description : Receive command from SMBus Master to Reset all *//
//* buffer and Status. *//
//* *//
//* Supported Devices : /PIC16F677/PIC16F687/PIC16F689/PIC16F690 *//
//* *//
//* Prototype : void Reset(void) *//
//* *//
//* Parameters : Nothing *//
//* *//
//* Return Value : Nothing *//
//* *//
//* Create Date : 14/7/2008 *//
//* Re-create Date : 15/11/2008 *//
//*****************************************************************************//
void Reset(void)
{
unsigned char i;
Run = 0X00;
for(i=0;i<3;i++) Tdata = 0x00;
}
//*****************************************************************************//
//* SSP_Command *//
//*---------------------------------------------------------------------------*//
//* Description : This function will manage I2C slave function *//
//* header procedure. *//
//* *//
//* Supported Devices : /PIC16F677/PIC16F687/PIC16F689/PIC16F690 *//
//* *//
//* Prototype : void SSP_Command(void) *//
//* *//
//* Parameters : Nothing *//
//* *//
//* Return Value : Nothing *//
//* *//
//* Create Date : 16/7/2008 *//
//* Re-create Date : 15/11/2008 *//
//*****************************************************************************//
void SSP_Command(void)
{
if((CMD&0xF0)==0x00) Reset();
// Voltage Measurement
if((CMD&0xF0)==0x30)
{
Conversion = 0;
Run = 0x08;
}
}
//*****************************************************************************//
//* ADC_Conversion *//
//*---------------------------------------------------------------------------*//
//* Description : Start doing voltage measurement *//
//* *//
//* Supported Devices : /PIC16F677/PIC16F687/PIC16F689/PIC16F690 *//
//* *//
//* Prototype : void ADC_Conversion(unsigned char TP,unsigned *//
//* char Unsage,unsigned char Usage) *//
//* *//
//* Parameters : Unse -- conversion data counter for no save *//
// Use -- Conversion data counter for save *//
//* *//
//* Return Value : Nothing *//
//* *//
//* Create Date : 14/7/2008 *//
//* Re-create Date : 15/11/2008 *//
//*****************************************************************************//
void VADC_Conversion(void)
{
SET_ADC_CHANNEL(0x00);
Conversion += READ_ADC();
Tdata[2] = (Conversion & 0xFF00) >> 8;
Tdata[1] = Conversion & 0x00FF;
Conversion = 0;
Run = 0x00;
Tdata[0] = ADDR;
}
// SSP-I2C Interrupt
#int_SSP
void SSP_isr(void)
{
int state;
state = i2c_isr_state();
if(state >= 0x80)
{
if(Run==0x08)
{
// In busy
i2c_write(0x00);
}
else
i2c_write(Tdata[state-0x80]);
}
else if(state>0)
{
CMD = i2c_read();
SSP_Command();
}
}
void main()
{
setup_oscillator(OSC_4MHZ);
setup_adc_ports(sAN0|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
//setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the
PICWizard
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
// TODO: USER CODE!!
Configuration();
while(TRUE)
{
if((Run==0x08)&& ((CMD&0xF0)==0x30)) VADC_Conversion();
}
}
一下是“main.h”代码。
#include <16F677.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOPUT //No Power Up Timer
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#use delay(clock=4000000)
#use I2C(slave,sda=PIN_B4,scl=PIN_B6,FAST,FORCE_HW) |
评分
-
查看全部评分
|
|
|
|
|
|
|
发表于 28-8-2009 08:54 AM
|
显示全部楼层
原帖由 xiao1987 于 26-8-2009 02:23 PM 发表
我想用其中一颗IC来送DATA,另一颗IC来接收DATA。它们的沟通是必须用I2C FUNCTION, 两颗是IC都是16F877。
你上面的是PIC MCU 和EEprom 的I2C。
为什么一定要用I2C 来连 2 颗PIC MCU?
对新手, 建议你用USART(RS232) 来连, 比较容易, 要debug 也容易, 也可以用电脑监听。 |
|
|
|
|
|
|
| |
本周最热论坛帖子
|