STC8系列单片机硬件I2C使用教程(二)

硬件I2C(中断方式)

以STC8F2K08S2单片机为例

一、I2C相关的寄存器

STC8系列单片机硬件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);
}

⑤ BMP085 读写例程

STC8系列单片机硬件I2C使用教程(一)

⑥ 串口代码

STC8系列单片机硬件I2C使用教程(一)

猜你喜欢

转载自blog.csdn.net/baidu_25117757/article/details/108915391