硬件I2C(中断方式)
以STC8F2K08S2单片机为例
一、I2C相关的寄存器
二、I2C中断相关的寄存器
① I2C中断源
② I2C中断允许位
③ I2C中断标志位
三、程序编写
① 寄存器和相关宏定义
sfr P_SW2 = 0xBA; //外设端口切换寄存器 2
#define I2CCFG (*(unsigned char volatile xdata *)0xfe80)
#define I2CMSCR (*(unsigned char volatile xdata *)0xfe81)
#define I2CMSST (*(unsigned char volatile xdata *)0xfe82)
#define I2CTXD (*(unsigned char volatile xdata *)0xfe86)
#define I2CRXD (*(unsigned char volatile xdata *)0xfe87)
bit i2c_busy; //I2C工作状态
sbit SDA = P3^3;
sbit SCL = P3^2;
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
② 硬件I2C中断服务程序
//I2C中断服务程序
void I2C_Isr() interrupt 24 using 1
{
_push_(P_SW2); //intrins.h 压一个sfr入栈。栈:先进后出,后进先出
P_SW2 |= 0x80;
if(I2CMSST & 0x40){
I2CMSST &= ~0x40; //清中断标志
i2c_busy = 0;
}
_pop_(P_SW2); //intrins.h 一个sfr出栈。栈:先进后出,后进先出
}
③ 硬件I2C初始化
void init_i2c(void)
{
uchar temp = 0x00;
// //切换到第一组I2C
// temp &= ~(I2C_S0 | I2C_S1); //I2C_S0=0 I2C_S1=0
// //(P1.5/SCL, P1.4/SDA)
// //切换到第二组I2C
// temp &= ~(I2C_S0 | I2C_S1); //I2C_S0=1 I2C_S1=0
// temp |= I2C_S0; //(P2.5/SCL, P2.4/SDA)
// //切换到第三组I2C
// temp &= ~(I2C_S0 | I2C_S1); //I2C_S0=0 I2C_S1=1
// temp |= I2C_S1; //(P7.7/SCL, P7.6/SDA)
//切换到第四组I2C
temp |= (I2C_S0 | I2C_S1); //I2C_S0=1 I2C_S1=1
//(P3.2/SCL, P3.3/SDA)
temp |= EAXFR; //I2C功能寄存器为扩展 SFR,逻辑地址位于 XDATA 区域,访问前需要将 P_SW2(BAH)寄存器的最高位(EAXFR)置 1
P_SW2 = temp;
I2CCFG = 0xE0; //使能I2C主机模式
I2CMSST = 0x00;
}
④ 硬件I2C操作代码
void start()
{
i2c_busy = 1;
I2CMSCR = 0x81; //发送START命令
while(i2c_busy);
}
void send_data(uchar dat)
{
I2CTXD = dat; //写数据到数据缓冲区
i2c_busy = 1;
I2CMSCR = 0x82; //发送SEND命令
while(i2c_busy);
}
void recv_ack()
{
i2c_busy = 1;
I2CMSCR = 0x83; //发送读ACK命令
while(i2c_busy);
}
uchar recv_data()
{
i2c_busy = 1;
I2CMSCR = 0x84; //发送RECV命令
while(i2c_busy);
return I2CRXD;
}
void send_ack()
{
I2CMSST = 0x00; //设置ACK信号
i2c_busy = 1;
I2CMSCR = 0x85; //发送ACK命令
while(i2c_busy);
}
void send_nack()
{
I2CMSST = 0x01; //设置NAK信号
i2c_busy = 1;
I2CMSCR = 0x85; //发送ACK命令
while(i2c_busy);
}
void stop()
{
i2c_busy = 1;
I2CMSCR = 0x86; //发送STOP命令
while(i2c_busy);
}