语法: state=i2c_isr_state( );

I2C_ISR_STATE()是PIC CCS编译器中PIC单片机的专有函数。

语法:   state=i2c_isr_state( );

参数:   没有.

返回值: 返回值是一个8位整型.

        0---接收地址匹配,R/W位被清除;

        1~0x7F---主机已写数据;i2c_read()将立即返回这个数据;

        0x80---接收地址匹配,R/W位被置1;同i2c_write()响应;

        0x81~0xff---发送完成; i2c_write()响应应答.

功能:   在一个SSP中断之后,在i2c的从机方式里,该函数返回的是i2c通讯的状态,该返回值在每次发送或接收一个字节时,都会产生中断.

有效性: 适合带有i2c硬件的设备.

要求:   必须使用#use i2c,才可使能i2c_isr_state( );

例子:   #INT_SSP          //SPI口或I2C被激活,指出下面的函数是一个中断服务函数

           void i2c_isr(){

state=i2c_isr_state();

if(state>=0x80)

   i2c_write( send_buffer[state-0x80] );

else if(state>0)

   rcv_buffer[state-1]=i2c_read();

           }

例子文件: ex_slave.c

文件ex_slave.c如下:

#if defined(__PCM__)  //若使用了PCM编译器,则defined( __PCM__)返回值为1

#include <16F877.h>   //包含16F877.h头文件

#fuses HS, NOWDT, NOPROTECT, NOLVP  //HS:高速晶振/谐振器, NOWDT:不使用WDT

                                      // NOPROTECT:程序存储器代码不保护

#use delay(clock=20000000)  //使能内置函数的功能:delay_ms()和delay_us()

                         //#USE DELAY()必须在#use rs232()使用之前出现.

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

//使用波特率为9600,

//发送脚为PIN_ C6

//接收脚为PIN_ C7

//使能内置函数:GETC,PUTCPRINTF, kbhit();

#elif defined(__PCH__)

#include <18F452.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#endif    //结束if定义

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0) 

     // SLAVE指定本机为从机方式

     //除非指定了FORCE_HW,否则会产生模拟I2C的软件函数.

//使能I2C_START,  I2C_STOP直到下一个#USE  I2C的出现为止.

//使能I2C_READ,  I2C_WRITE直到下一个#USE  I2C的出现为止.

//使能I2C_POLL直到下一个#USE  I2C的出现为止.

     //指定SDA脚为PIN_C4, 指定SCL脚为PIN_C3;

     // address指定从机方式的地址为0xa0;

typedef enum {NOTHING, CONTROL_READ,

              ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;

I2C_STATE  fState;

BYTE address, buffer[0x10];  //声明字节变量address,数组buffer[0x10]

#INT_SSP          //SPI口或I2C被激活,指出下面的函数是一个中断服务函数

void ssp_interupt ()

{

   BYTE incoming;  //声明字节变量incoming;

   if (i2c_poll() == FALSE) { //若主机读本从机时, i2c_poll()返回FALSE值,执行下面的语句

      if (fState == ADDRESS_READ) {  //若已读到数据的地址, 则执行下面的语句

         i2c_write (buffer[address]);     //将指定地址(address)处的数据发给主机

         fState = NOTHING;          //为接收下一个数据的地址做准备

      }

   }

   else { // 若SSP缓冲器接收到一个字节,i2c_poll()的返回值为TRUE,执行下面的语句

incoming = i2c_read();  

//通过i2c口读一个字节(该字节可能是器件的地址,数据的地址或数据,也可能什么都不是)

      if (fState == NOTHING){

         fState = CONTROL_READ;

      }

      else if (fState == CONTROL_READ) {

         address = incoming;         //接收存放数据的地址

         fState = ADDRESS_READ;

      }

      else if (fState == ADDRESS_READ) {

         buffer[address] = incoming;   //向address地址处写数据

         fState = NOTHING;

      }

   }

}

void main ()

{

   int i;   //声明整型变量i;

   fState = NOTHING;  //给fState赋初值

   address = 0x00;      //给address赋初值

   for (i=0;i<0x10;i++)

      buffer[i] = 0x00;  //给数组buffer[0x10] 赋初值

   enable_interrupts(GLOBAL);   //开总中断允许

   enable_interrupts(INT_SSP);   //SPI口或I2C中断允许位置1

   while (TRUE) {}  //循环等待中断

}

上面的程序用PIC从机方式来模拟EEPROM(24C01),只能向地址0x00~0x10写数据.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值