简介
STC8G系列单片机拥有一个I2C接口。它支持主机模式和从机模式。本文主要介绍主机模式。
I2C相关寄存器

引脚重映射
I2C接口所使用的SDA和SCL引脚可以在多组引脚中切换。方便PCB布线。
通过P_SW2[5:4]来选择I2C接口使用的引脚组。例如对于STC8G1K08-20PIN来说,有如下两种选择:
| P_SW2[5:4] | SCL | SDA |
| 00 | P15 | P14 |
| 11 | P32 | P33 |
主机模式
主机模式配置:通过I2CCFG寄存器来配置为主机模式。
- I2CCFG.bit7:置1,使能I2C接口
- I2CCFG.bit6:置1,设置为主机模式
主机总线速度设置 : ,其中Sysclk为CPU工作频率,MSSPEED为I2CCFG寄存器的B5:B0位段。例如Sysclk=12MHz,MSSPEED=28,那么I2C总线速度Speed=100KHz。
工作原理:I2C通信由多个动作组成,如发送起始位,发送停止位,发送8位数据,接收从机响应的ACK等。对于STC8G的I2C接口的主机模式,每个动作都有一个4位的命令编码来代表,将这个命令编码写入到I2CMSCR[3:0]中即可触发I2C接口开始执行对应的动作,当命令执行完成后,I2CMSST.bit6硬件置1,因此主机写入命令后需要等待I2CMSST.bit6硬件置1,软件清除此标志后,然后才可以执行下一个命令。
| I2CMSCR[3:0] | 主机命令 | 备注 |
| 0001 | 发送起始信号 | |
| 0110 | 发送结束信号 | |
| 0010 | 发送1字节数据 | |
| 0011 | 接收ACK信号 | |
| 0100 | 接收1字节数据 | |
| ... | ... | ... |
注意:
- 主机最近一次接收到的ACK信号存储在I2CMSST.bit1位中,如果I2CMSST.bit1=1则代表收到了NACK信号,如果I2CMSST.bit1=0则代表收到了ACK信号。
- 当使用0101(发送ACK/NACK)命令时,具体是发送ACK还是NACK取决于I2CMSST.bit0的值,如果I2CMSST.bit0=0则会发送ACK,I2CMSST.bit0=1则会发送NACK。当使用1011(接收1字节数据+发送ACK信号)命令时,主机会从总线读取1字节数据并固定发送ACK信号,与I2CMSST.bit0无关。同理当使用1100(接收1字节数据+发送NACK信号)命令时,主机会从总线读取1字节数据并固定发送NACK信号与I2CMSST.bit0无关。推荐使用这种组合命令,简洁方便。
- 主机模式时,寄存器I2CTXD为发送缓冲寄存器,I2CRXD为接收缓冲寄存器。
主机模式相关标志位:
- I2CMSST.bit6(MSIF):主机模式的中断标志位。当处于主机模式的I2C执行完成寄存器。
- I2CMSCR[3:0]:代表的命令后硬件自动将此位1,如果使能了主机模式中断还会触发中断。MSIF位必须用软件清零。
示例代码
描述:使用STC8G1K08-20PIN的I2C接口驱动AT24C02,硬件I2C使用查询法编写,SCL引脚为P15,SDA引脚为P14。

#include <STC8G.H>
#include <intrins.h>
/*
sysclk=12M,28,100Khz
*/
//配置I2C主机接口
void I2C_config(void)
{
//P_SW2&= B1100_1111; //选择引脚组
GPIO_MODE_OD(1,5); //配置SCL引脚为开漏输出模式
GPIO_MODE_OD(1,4); //配置SDA引脚为开漏输出模式
P15=1; //释放SCL
P14=1; //释放SDA
I2CMSAUX = 0; //不启用数据自动发送功能
I2CMSST = 0; //清除主机状态和标志
I2CCFG = B1100_0000 | 28 ; //启用I2C接口,设置为主机模式,设置总线速度
}
//作用:主机发送起始信号
void I2C_start(void)
{
I2CMSCR = B0000_0001; //发送起始信号
while(!(I2CMSST&B0100_0000)); //等待指令执行完成
I2CMSST &= B1011_1111; //清除I2CMSST.bit6 //清除指令完成标志
}
//作用:主机发送停止信号
void I2C_stop(void)
{
I2CMSCR = B0000_0110; //发送结束信号
while(!(I2CMSST&B0100_0000)); //等待指令执行完成
I2CMSST &= B1011_1111; //清除I2CMSST.bit6 //清除指令完成标志
}
//作用:写1字节数据到I2C总线并读取从机响应的ACK信号
//参数为要发送的字节数据
//返回1代表收到了NACK,返回0代表收到了ACK
unsigned char I2C_write_byte(unsigned char dat)
{
I2CTXD = dat; //设置要发送的数据
I2CMSCR = B0000_1010; //发送1字节数据并接收ACK信号
while(!(I2CMSST&B0100_0000)); //等待指令执行完成
I2CMSST &= B1011_1111; //清除I2CMSST.bit6 //清除指令完成标志
//读取从机响应的ACK信号
if(I2CMSST & B0000_0010) //当收到NACK时,I2CMSST.bit1=1
{
return 1;
}
else //当收到ACK时,I2CMSST.bit1=0
{
return 0;
}
}
//作用:从总线读取1字节数据返回并根据参数发送ACK或者NACK信号
//参数为0则代表读1字节并发送ACK
//参数为1则代表读1字节并发送NACK
//返回读取到的字节数据
unsigned char I2C_read_byte(unsigned char nack)
{
if(nack)
I2CMSCR = B0000_1100; //接收1字节数据并发送NACK信号
else
I2CMSCR = B0000_1011; //接收1字节数据并发送ACK信号
while(!(I2CMSST&B0100_0000)); //等待指令执行完成
I2CMSST &= B1011_1111; //清除I2CMSST.bit6 //清除指令完成标志
return I2CRXD; //返回主机收到的字节数据
}
void Delay100ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 7;
j = 23;
k = 105;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main(void)
{
unsigned char dat;
P_SW2 |= B1000_0000; /*打开XSFR的访问权*/
I2C_config(); //配置I2C接口
while(1)
{
Delay100ms();
Delay100ms();
Delay100ms();
Delay100ms();
Delay100ms();
Delay100ms();
//向AT24C02的0x02地址单元写入字节数据0x89
I2C_start();
I2C_write_byte(0xA0);
I2C_write_byte(0x02);
I2C_write_byte(0x89);
I2C_stop();
Delay100ms();
//从AT24C02的0x02地址单元读出字节数据
I2C_start();
I2C_write_byte(0xA0);
I2C_write_byte(0x02);
I2C_start();
I2C_write_byte(0xA1);
dat=I2C_read_byte(1);
I2C_stop();
}
}
本文介绍了STC8G系列单片机如何配置硬件I2C接口为主机模式,包括相关寄存器、引脚重映射、主机模式配置以及工作原理。内容涵盖I2C通信的动作、中断标志位和示例代码,用于驱动AT24C02芯片。
721






