多路分发

何为多路分发:

java只持单路分发,即如果要执行的操作包含不止一个类型未知的对象时,

那么动态绑定机制只能处理处中的一个类型,

如果需要处理两个类型,可以使用多路分发,

如果想使用两路分发,就必须要有两个方法调用:

第一个方法调用决定第一个未知类型,

第二个方法调用决定第二个未知类型


基于接口实现


Item

package com.demo.multiple;

/**
 * @author wobendiankun
 *2014-10-29 下午09:52:42
 */
public interface Item {
	ResultCode compete(Item item);
	ResultCode eval(AA aa);
	ResultCode eval(BB bb);
	ResultCode eval(CC cc);
}

AA

package com.demo.multiple;

/**
 * @author wobendiankun
 *2014-10-29 下午09:51:57
 */
public class AA implements Item {

	@Override
	public ResultCode compete(Item item) {
		return item.eval(this);
	}

	@Override
	public ResultCode eval(AA aa) {
		System.out.print("AA vs AA :");
		return ResultCode.EQ;
	}

	@Override
	public ResultCode eval(BB bb) {
		System.out.print("AA vs BB :");
		return ResultCode.GT;
	}

	@Override
	public ResultCode eval(CC cc) {
		System.out.print("AA vs CC :");
		return ResultCode.LT;
	}

}

BB

package com.demo.multiple;


/**
 * @author wobendiankun
 *2014-10-29 下午09:52:09
 */
public class BB implements Item {
	@Override
	public ResultCode compete(Item item) {
		return item.eval(this);
	}

	@Override
	public ResultCode eval(AA aa) {
		System.out.print("BB vs AA :");
		return ResultCode.LT;
	}

	@Override
	public ResultCode eval(BB bb) {
		System.out.print("BB vs BB :");
		return ResultCode.EQ;
	}

	@Override
	public ResultCode eval(CC cc) {
		System.out.print("BB vs CC :");
		return ResultCode.LT;
	}
}

CC

package com.demo.multiple;


/**
 * @author wobendiankun
 *2014-10-29 下午09:52:28
 */
public class CC implements Item {
	@Override
	public ResultCode compete(Item item) {
		return item.eval(this);
	}

	@Override
	public ResultCode eval(AA aa) {
		System.out.print("CC vs AA :");
		return ResultCode.GT;
	}

	@Override
	public ResultCode eval(BB bb) {
		System.out.print("CC vs BB :");
		return ResultCode.GT;
	}

	@Override
	public ResultCode eval(CC cc) {
		System.out.print("CC vs CC :");
		return ResultCode.EQ;
	}
}

ResultCode

package com.demo.multiple;
/**
 * @author wobendiankun
 *2014-10-29 下午09:51:19
 */
public enum ResultCode {
	GT,EQ,LT
}

MultiDispTest

package com.demo.multiple;

/**
 * @author wobendiankun
 *2014-10-29 下午09:50:22
 */
public class MultiDispTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Item item1=new BB();
		Item item2=new AA();
		ResultCode result=item1.compete(item2);
		System.out.println("\t"+result);
	}

}

运行结果:

AA vs BB :	GT

当执行 item1.compete(item2); 这段代码时,确定了第一个对象item1类型为BB,

BB类的compete中又执行 item.eval(this)  ,确定了第二个对象item的类型 为AA,

利用重载方法找到了AA的方法:

@Override
	public ResultCode eval(BB bb) {
		System.out.print("AA vs BB :");
		return ResultCode.GT;
	}



基于枚举实现:




Item2

package com.demo.multiple.enums;

import com.demo.multiple.Item;
import com.demo.multiple.ResultCode;
import com.demo.multiple.enums.ItemComparator.ItemCode;

/**
 * @author wobendiankun
 *2014-10-29 下午09:53:15
 * @param <T>
 */
public interface Item2<T extends Item2<T>> {
	ResultCode compete(T code);
}

ItemComparator

package com.demo.multiple.enums;

import com.demo.multiple.Item;
import com.demo.multiple.ResultCode;
import static com.demo.multiple.ResultCode.*;
/**
 * @author wobendiankun
 *2014-10-29 下午09:53:26
 */
public class ItemComparator {
	enum ItemCode implements Item2<ItemCode>{
		AA(EQ,GT,LT),
		BB(LT,EQ,LT),
		CC(GT,GT,EQ);
		private ResultCode item1;
		private ResultCode item2;
		private ResultCode item3;
		
		private ItemCode(ResultCode item1, ResultCode item2, ResultCode item3) {
			this.item1 = item1;
			this.item2 = item2;
			this.item3 = item3;
		}

		/* (non-Javadoc)
		 * @see com.demo.multiple.enums.Item2#compete(com.demo.multiple.Item)
		 */
		@Override
		public ResultCode compete(ItemCode code) {
			switch (code) {
				case AA:
					return item1;
				case BB:
					return item2;
				case CC:
					return item3;
			}
			return null;
		}
	}
	public static void main(String[] args) {
		Item2 item1=ItemCode.AA;
		Item2 item2=ItemCode.CC;
		System.out.println("AA vs CC :"+item1.compete(item2));
	}
}

运行结果:

AA vs CC :LT

枚举实例创建时新建一条记录,compete()方法执行时:

@Override
		public ResultCode compete(ItemCode code) {
			switch (code) {
				case AA:
					return item1;
				case BB:
					return item2;
				case CC:
					return item3;
			}
			return null;
		}

相当于查询一条记录的内容:

字段AA--->item1

字段BB-->item2

字段CC-->item3

实例初始化,创建了对应的记录

AA(EQ,GT,LT),
BB(LT,EQ,LT),
CC(GT,GT,EQ)



在实现 I2C 信号通过 CPLD 进行透传并分发到多路的设计方案中,需要综合考虑硬件设计、CPLD 编程以及 I2C 协议的特性。以下是完整的实现方案: ### 3.1 I2C 协议基础 I2C(Inter-Integrated Circuit)是一种半双工同步串行通信协议,通常用于连接低速外围设备。I2C 总线由两根信号线组成:SDA(数据线)和 SCL(时钟线),支持多主从架构,最多可连接 128 个设备(7 位地址模式)或 1024 个设备(10 位地址模式)[^2]。 I2C 的典型速率包括: - 标准模式:100 kbps - 快速模式:400 kbps - 高速模式:3.4 Mbps 在进行 CPLD 透传设计时,需确保时序符合 I2C 规范,尤其是建立时间、保持时间和时钟同步。 ### 3.2 系统架构设计 实现 I2C 信号的多路分发可以通过以下架构: - **输入端口**:一路 I2C 主设备输入信号(SDA 和 SCL) - **CPLD 模块**:负责解析主设备的 I2C 地址,并根据地址选择目标从设备 - **输出端口**:多路 I2C 从设备接口,每路可独立控制 ### 3.3 CPLD 功能模块设计 CPLD 在此设计中主要完成以下功能: - **地址解码**:读取 I2C 传输中的从设备地址字段,并根据地址选择对应的输出通道。 - **总线仲裁**:确保多个从设备不会同时响应,避免总线冲突。 - **电平转换与缓冲**:如果主从设备之间存在电压差异,CPLD 可集成电平转换逻辑。 - **多路复用控制**:将主设备的 SDA/SCL 信号路由到对应的从设备接口。 ### 3.4 硬件设计要点 - **I2C 上拉电阻**:每个 I2C 总线段应配置合适的上拉电阻,通常为 4.7kΩ 或 10kΩ。 - **CPLD 引脚分配**:SDA 和 SCL 信号应使用具有双向缓冲能力的引脚,以支持 I2C 的双向通信特性。 - **电源与地设计**:确保电源去耦和良好的接地设计,以减少噪声干扰。 ### 3.5 CPLD 编程实现 使用硬件描述语言(如 Verilog 或 VHDL)实现 I2C 信号的解析与路由逻辑。以下是一个简化的 Verilog 示例代码: ```verilog module i2c_multiplexer ( input i2c_scl_in, input i2c_sda_in, output reg [1:0] channel_select, output reg [1:0] sda_out, output reg [1:0] scl_out ); reg [7:0] address; always @(posedge i2c_scl_in or negedge i2c_sda_in) begin if (!i2c_sda_in) begin // Start condition detected address <= 8'h00; end else begin address <= {address[6:0], i2c_sda_in}; end end always @(address) begin case (address[7:4]) 4'b0001: channel_select = 2'b00; 4'b0010: channel_select = 2'b01; 4'b0011: channel_select = 2'b10; default: channel_select = 2'b11; endcase end always @(channel_select) begin case (channel_select) 2'b00: begin sda_out = {i2c_sda_in, 1'b0, 1'b0}; scl_out = {i2c_scl_in, 1'b0, 1'b0}; end 2'b01: begin sda_out = {1'b0, i2c_sda_in, 1'b0}; scl_out = {1'b0, i2c_scl_in, 1'b0}; end 2'b10: begin sda_out = {1'b0, 1'b0, i2c_sda_in}; scl_out = {1'b0, 1'b0, i2c_scl_in}; end default: begin sda_out = 3'b111; scl_out = 3'b111; end endcase end endmodule ``` ### 3.6 测试与验证 - **功能仿真**:使用仿真工具验证地址解码和通道选择逻辑是否正确。 - **时序分析**:确保 I2C 时序满足建立和保持时间要求。 - **板级测试**:连接实际 I2C 设备进行通信测试,验证 CPLD 的多路分发功能。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值