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



一、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使用教程(一)

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
### 回答1: STC8G1K08A是深圳曙光微电子有限公司推出的一款8051系列单片机,它内置了I2C总线控制器,可以实现与其他I2C设备的通信。下面是一个关于STC8G1K08A的I2C范例程序的回答: STC8G1K08A的I2C范例程序主要是为了帮助开发者快速上手使用I2C总线功能。I2C是一种串行通信协议,适用于系统内部芯片之间的通信。范例程序通常包含了初始化I2C控制器、设置相关参数、发送和接收数据的代码片段。 在STC8G1K08A的I2C范例程序中,你可以找到以下内容: 1. 引入相关头文件和宏定义:范例程序中可能会引入一些与I2C相关的头文件,以及定义一些宏、常量等。 2. I2C初始化:范例程序会调用相关函数对I2C控制器进行初始化,设置相关的时钟、波特率等参数。 3. 数据发送和接收:范例程序通常会包含数据发送和接收的代码,用来测试与其他I2C设备的通信。 4. 错误处理:范例程序可能会加入一些错误处理机制,以确保程序的健壮性和稳定性。 5. 示例代码:范例程序中可能会包含一些示例代码,以演示如何使用I2C总线控制器进行读写操作等。 通过阅读这个范例程序,你可以了解到如何在STC8G1K08A上配置和使用I2C总线控制器,并了解到一些常见的操作和注意事项。但需要注意的是,范例程序通常只是给出一个基本的示例,实际使用时可能需要根据具体的应用场景进行适当的修改和优化。 ### 回答2: STC8G1K08A是一款单片机芯片,支持I2C通信协议。以下是一个I2C通信的范例程序: ```c #include <reg52.h> #include <intrins.h> sbit SDA = P2^0; // I2C数据线 sbit SCL = P2^1; // I2C时钟线 void I2C_Start() { SDA = 1; _nop_(); // 延时一个时钟周期 SCL = 1; _nop_(); SDA = 0; _nop_(); SCL = 0; } void I2C_Stop() { SDA = 0; _nop_(); SCL = 1; _nop_(); SDA = 1; _nop_(); } void I2C_SendByte(unsigned char byte) { unsigned char i; for (i = 0; i < 8; i++) { SDA = (byte & 0x80) ? 1 : 0; byte <<= 1; _nop_(); SCL = 1; _nop_(); SCL = 0; } // 等待从设备的应答 SDA = 1; _nop_(); SCL = 1; _nop_(); if (SDA == 1) { // 应答错误 } SCL = 0; } unsigned char I2C_ReceiveByte() { unsigned char byte = 0x00; unsigned char i; SDA = 1; _nop_(); for (i = 0; i < 8; i++) { SCL = 1; _nop_(); byte = (byte << 1) | SDA; SCL = 0; _nop_(); } return byte; } void I2C_Ack() { SDA = 0; _nop_(); SCL = 1; _nop_(); SCL = 0; _nop_(); SDA = 1; } void I2C_Nack() { SDA = 1; _nop_(); SCL = 1; _nop_(); SCL = 0; } void main() { unsigned char dataToSend = 0x55; unsigned char receivedData = 0x00; I2C_Start(); I2C_SendByte(0xA0); // 设备地址 + 写命令 I2C_Ack(); I2C_SendByte(0x00); // 写入数据的地址 I2C_Ack(); I2C_SendByte(dataToSend); // 写入数据 I2C_Ack(); I2C_Stop(); _nop_(); _nop_(); I2C_Start(); I2C_SendByte(0xA0); // 设备地址 + 写命令 I2C_Ack(); I2C_SendByte(0x00); // 读取数据的地址 I2C_Ack(); I2C_Start(); I2C_SendByte(0xA1); // 设备地址 + 读命令 I2C_Ack(); receivedData = I2C_ReceiveByte(); // 读取数据 I2C_Nack(); I2C_Stop(); while (1) { // 循环执行其他任务 } } ``` 以上是一个简单的I2C通信范例程序,主要实现了单片机向从设备写入字节数据,并读取从设备返回的数据。请根据具体的硬件电路和设备的I2C协议规范进行相应的修改和调试。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝蚊鸭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值