再议IIC协议与设计【2】--使用GPIO实现IIC从机通讯源码分析与测试

本文介绍了使用GPIO模拟I2C从机的工程设计,详细解析了从机通信设计框图、硬件平台的寄存器配置、接收数据的核心代码,以及遇到的时钟占空比和数据变化问题。通过分析和测试,提出了对程序的改进思路。
摘要由CSDN通过智能技术生成

概述

在本阶段的工作中,需要实现一个由GPIO模拟的I2C从机工程设计,以前只使用GPIO模拟I2C设计过主机,对于从机的设计,还是首次。下面就对本次工作中从机设计思想做详细记录。


开发平台

THK88


从机通信设计框图


图 1

程序设计与分析

硬件平台的寄存器配置

#define WAIT_IIC_SCL_HIGH   while ( !GET_SCL_DAT )  
#define WAIT_IIC_SCL_LOW    while ( GET_SCL_DAT )  
#define WAIT_IIC_SDA_HIGH   while ( !GET_SDA_DAT )  
#define WAIT_IIC_SDA_LOW    while ( GET_SDA_DAT )  
  
  
#define IIC_WAIT_START      WAIT_IIC_SCL_HIGH;  WAIT_IIC_SDA_LOW      
#define IIC_WAIT_STOP       WAIT_IIC_SCL_LOW; SDA_IN; WAIT_IIC_SCL_HIGH; WAIT_IIC_SDA_HIGH   
  
  
#define IIC_SLAVE_SEND_LOW  WAIT_IIC_SCL_LOW; SDA_OUT; SET_SDA_LOW; WAIT_IIC_SCL_HIGH        
#define IIC_SLAVE_SEND_HIGH WAIT_IIC_SCL_LOW; SDA_OUT; SET_SDA_HIGH; WAIT_IIC_SCL_HIGH  
  
  
#define IIC_SLAVE_SEND_ACK  IIC_SLAVE_SEND_LOW  
#define IIC_SLAVE_SEND_NAK  IIC_SLAVE_SEND_HIGH  

初始化

void iic_init(void)  // 完成GPIO作为I2C的初始化 
完成GPIO时钟寄存机配置等功能。


接收地址以及读写命令模块

for(bitcount = 0; bitcount < 7; bitcount ++)  
{  
    WAIT_IIC_SCL_LOW;                     
    WAIT_IIC_SCL_HIGH;  
    iic_slv
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
使用GPIO实现IIC SLAVE之前,需要先了解IIC SLAVE的工作原理。IIC SLAVE是指设备作为IIC总线上的从设备,需要响应主设备的读写请求。 GPIO是通用输入输出引脚,可以通过软件控制引脚的电平状态。在实现IIC SLAVE时,可以使用GPIO模拟IIC总线上的时钟线(SCL)和数据线(SDA)。 以下是使用GPIO实现IIC SLAVE的简单流程: 1. 初始化GPIO引脚,将SCL和SDA引脚设置为输入或输出模式。 2. 等待主设备发送起始信号(S)。 3. 接收主设备发送的设备地址和读写标志(R/W)。 4. 判断接收到的地址是否与当前设备地址匹配,如果匹配则发送应答信号(ACK)。 5. 根据读写标志,执行读或写操作。如果是写操作,接收主设备发送的数据并进行处理;如果是读操作,发送需要读取的数据。 6. 等待主设备发送停止信号(P)。 以下是使用Python代码实现IIC SLAVE的简单示例: ```python import RPi.GPIO as GPIO # IIC SLAVE地址 SLAVE_ADDR = 0x50 # GPIO引脚初始化 GPIO.setmode(GPIO.BOARD) GPIO.setup(SCL_PIN, GPIO.OUT) GPIO.setup(SDA_PIN, GPIO.OUT) # 等待主设备发送起始信号 def wait_start(): GPIO.setup(SDA_PIN, GPIO.IN) while GPIO.input(SDA_PIN) == GPIO.LOW: pass GPIO.setup(SDA_PIN, GPIO.OUT) # 判断起始信号是否合法 if GPIO.input(SCL_PIN) == GPIO.LOW: return True else: return False # 接收设备地址和读写标志 def receive_addr(): addr = 0 for i in range(7): GPIO.setup(SCL_PIN, GPIO.IN) addr = (addr << 1) | GPIO.input(SDA_PIN) GPIO.setup(SCL_PIN, GPIO.OUT) rw = GPIO.input(SDA_PIN) return (addr, rw) # 发送应答信号 def send_ack(): GPIO.output(SDA_PIN, GPIO.LOW) GPIO.setup(SCL_PIN, GPIO.IN) GPIO.setup(SCL_PIN, GPIO.OUT) GPIO.output(SDA_PIN, GPIO.HIGH) # 接收数据 def receive_data(): data = 0 for i in range(8): GPIO.setup(SCL_PIN, GPIO.IN) data = (data << 1) | GPIO.input(SDA_PIN) GPIO.setup(SCL_PIN, GPIO.OUT) return data # 发送数据 def send_data(data): for i in range(8): GPIO.setup(SCL_PIN, GPIO.OUT) GPIO.output(SDA_PIN, (data & 0x80) >> 7) data = data << 1 GPIO.setup(SCL_PIN, GPIO.IN) # 等待主设备发送停止信号 def wait_stop(): GPIO.setup(SDA_PIN, GPIO.IN) while GPIO.input(SDA_PIN) == GPIO.HIGH: pass GPIO.setup(SDA_PIN, GPIO.OUT) # 主函数 def main(): # 等待起始信号 if wait_start() == False: return # 接收设备地址和读写标志 addr, rw = receive_addr() # 判断地址是否匹配 if addr != SLAVE_ADDR: return # 发送应答信号 send_ack() # 根据读写标志执行操作 if rw == 0: # 接收主设备发送的数据并进行处理 data = receive_data() # 处理数据 ... else: # 发送需要读取的数据 send_data(data) # 等待停止信号 wait_stop() # 主程序入口 if __name__ == '__main__': main() ``` 注意:以上示例仅为演示实现IIC SLAVE的基本原理,具体实现还需要根据具体应用场景进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值