在线时间568 小时
UID3436040
注册时间2018-5-6
NXP金币3437
TA的每日心情 | 开心 17 分钟前 |
|---|
签到天数: 1315 天 连续签到: 27 天 [LV.10]以坛为家III
金牌会员
 
- 积分
- 17253
- 最后登录
- 2026-2-5
|
# NXP LPC800 I2C接口使用例程
# I2C从机地址定义
I2C_SLAVE_ADDR = 0x55
# I2C状态标志
I2C_STAT_BUSY = 1 << 0
I2C_STAT_TXF = 1 << 2
I2C_STAT_RXF = 1 << 3
I2C_STAT_NAK = 1 << 4
I2C_STAT_ARB = 1 << 5
# 模拟硬件寄存器
class LPC_I2C0:
def __init__(self):
self.CTRL = 0
self.STAT = 0
self.DATA = 0
self.FREQ = 0
self.ADR = 0
class LPC_SYSCON:
SYSAHBCLKCTRL = 0
class LPC_IOCON:
PIO0_10 = 0
PIO0_11 = 0
# 全局硬件实例
LPC_I2C0 = LPC_I2C0()
LPC_SYSCON = LPC_SYSCON()
LPC_IOCON = LPC_IOCON()
SystemCoreClock = 12000000 # 12MHz系统时钟
def i2c_init():
"""I2C初始化配置"""
# 使能I2C时钟
LPC_SYSCON.SYSAHBCLKCTRL |= (1 << 10)
# 配置PIO0_10(SDA)和PIO0_11(SCL)为I2C功能
LPC_IOCON.PIO0_10 = 0x01
LPC_IOCON.PIO0_11 = 0x01
# 设置I2C时钟频率(100KHz)
LPC_I2C0.FREQ = (SystemCoreClock // 100000) - 1
# 配置从机地址
LPC_I2C0.ADR = (I2C_SLAVE_ADDR << 1)
# 使能I2C模块
LPC_I2C0.CTRL = 0x40
def i2c_start():
"""I2C发送起始条件"""
# 发送起始条件
LPC_I2C0.CTRL |= (1 << 5)
# 等待起始条件完成
while not (LPC_I2C0.STAT & (1 << 3)):
pass
# 清除中断标志
LPC_I2C0.STAT = (1 << 3)
def i2c_stop():
"""I2C发送停止条件"""
# 发送停止条件
LPC_I2C0.CTRL |= (1 << 6)
# 等待停止条件完成
while not (LPC_I2C0.STAT & (1 << 4)):
pass
# 清除中断标志
LPC_I2C0.STAT = (1 << 4)
def i2c_send_byte(data):
"""I2C发送一个字节"""
# 等待TX FIFO空
while not (LPC_I2C0.STAT & I2C_STAT_TXF):
pass
# 写入数据
LPC_I2C0.DATA = data
# 等待ACK
while not (LPC_I2C0.STAT & (1 << 0)):
pass
# 检查ACK状态
if LPC_I2C0.STAT & (1 << 1):
return 1 # NACK错误
return 0
def i2c_read_byte(ack):
"""I2C读取一个字节"""
# 等待RX FIFO非空
while not (LPC_I2C0.STAT & I2C_STAT_RXF):
pass
# 读取数据
data = LPC_I2C0.DATA
# 设置ACK状态
if ack:
LPC_I2C0.DATA = 0x00 # ACK
else:
LPC_I2C0.DATA = 0x01 # NACK
return data
def i2c_master_transmit(slave_addr, data, length):
"""主模式发送数据"""
# 发送起始条件
i2c_start()
# 发送从机地址+写命令
if i2c_send_byte((slave_addr << 1) | 0x00):
i2c_stop()
return 1 # 地址应答失败
# 发送数据
for i in range(length):
if i2c_send_byte(data):
i2c_stop()
return 2 # 数据发送失败
# 发送停止条件
i2c_stop()
return 0
def i2c_master_receive(slave_addr, data, length):
"""主模式接收数据"""
# 发送起始条件
i2c_start()
# 发送从机地址+读命令
if i2c_send_byte((slave_addr << 1) | 0x01):
i2c_stop()
return 1 # 地址应答失败
# 接收数据
for i in range(length):
# 最后一个字节前发送ACK
ack = 1 if i < length-1 else 0
data = i2c_read_byte(ack)
# 发送停止条件
i2c_stop()
return 0
# 主函数示例
def main():
tx_data = [0x01, 0x02, 0x03]
rx_data = [0] * 3
# 初始化I2C
i2c_init()
# 发送数据示例
print("发送数据中...")
result = i2c_master_transmit(I2C_SLAVE_ADDR, tx_data, 3)
if result == 0:
print("发送成功")
else:
print(f"发送失败,错误码: {result}")
# 接收数据示例
print("接收数据中...")
result = i2c_master_receive(I2C_SLAVE_ADDR, rx_data, 3)
if result == 0:
print(f"接收成功: {rx_data}")
else:
print(f"接收失败,错误码: {result}")
# 执行主函数
if __name__ == "__main__":
main()```
|
|