分步请求控制器

在操作网络请求的时候,我们一般在start的时候我们会showProgress,然后在请求完成的时候dismissProgress,这样可以保证同步请求数据。但是我们一般还会遇到这样的情况,需要一次请求两个接口,请求完第一个接口之后操作UI,然后再请求另一个接口,这两个接口要同步进行,如果我们还按照前面的方法来操作进度条就会出现连续两个进度条显示的情况,所以写了一个分步处理任务的方法。


首先是步骤轴/事件轴类

import java.util.concurrent.TimeUnit;

import android.text.TextUtils;

/**
 * 步骤轴,事件轴,用于记录同步状态下不同步骤的运行情况
 * 
 * 
 */
public class StepLine {

	/**
	 * 重复步骤最小间隔定义(ms)
	 */
	private static final int MIN_REPEAT_INTERVAL = 500;
	/**
	 * 最后一次步骤的标识/时间戳(ns)
	 */
	private String mLastStep = null;
	private long mLastStepTimeStamp = 0;

	/**
	 * stepline创建器
	 * 
	 */
	private static class StepHolder {
		public static StepLine instance = new StepLine();
	}

	public static StepLine getInstance() {
		return StepHolder.instance;
	}

	private StepLine() {
	}

	/**
	 * 向步骤轴添加一个步骤
	 * 
	 * @return true - 添加步骤成功并记录时间; false - 由于重复等原因添加失败
	 */
	public synchronized boolean add(String step) {
		// 纳秒
		long currTime = System.nanoTime();

		if (!TextUtils.isEmpty(mLastStep) && mLastStep.equals(step)) {
			if (currTime - mLastStepTimeStamp <= TimeUnit.MILLISECONDS
					.toNanos(MIN_REPEAT_INTERVAL)) {
				return false;
			}
		}

		mLastStep = step;
		mLastStepTimeStamp = currTime;

		return true;
	}

}

然后是分步处理任务类,因为遇到情况所限,最多支持3步处理

import android.text.TextUtils;

/**
 * 分步处理的任务 最多支持3步处理
 * 
 * 
 */
public abstract class StepTask {

	/**
	 * 步骤数量
	 */
	private int mStepCount = 0;
	/**
	 * 当前步骤(1为起始值)
	 */
	private int mCurrStep = 1;
	/**
	 * 在完成的时候需要执行下一个步骤
	 */
	private boolean mExecuteNext = false;
	/**
	 * 任务名称
	 */
	private String mTaskName = null;

	/**
	 * 任务开始
	 * 
	 */
	protected abstract boolean onStart();

	/**
	 * 任务完成
	 * 
	 */
	protected abstract void onFinish();

	/**
	 * 步骤1
	 */
	protected abstract void onStep1Start();

	/**
	 * 步骤2
	 */
	protected abstract void onStep2Start();

	/**
	 * 步骤3
	 */
	protected void onStep3Start() {
	}

	/**
	 * constructor
	 * 
	 * @param stepCount
	 *            步骤数量
	 */
	public StepTask() {
		init(2);
	}

	/**
	 * constructor
	 * 
	 * @param taskName
	 *            任务名称
	 */
	public StepTask(String taskName) {
		init(2);
		mTaskName = taskName;
	}

	/**
	 * constructor
	 * 
	 * @param stepCount
	 *            步骤数量
	 */
	public StepTask(int stepCount) {
		init(stepCount);
	}

	/**
	 * constructor
	 * 
	 * @param taskName
	 *            任务名称
	 * @param stepCount
	 *            步骤数量
	 */
	public StepTask(int stepCount, String taskName) {
		init(stepCount);
		mTaskName = taskName;
	}

	/**
	 * 初始化方法
	 * 
	 * @param stepCount
	 */
	private void init(int stepCount) {
		if (stepCount > 3) {
			throw new IllegalArgumentException(
					"The count of step must be less than or equal 3.");
		}
		mStepCount = stepCount;
		mCurrStep = 1;
		if (TextUtils.isEmpty(mTaskName)) {
			// 外部没有设置任务名,使用默认
			mTaskName = StepTask.class.getCanonicalName();
		}
	}

	/**
	 * 下一个步骤
	 */
	public void nextStep() {
		mExecuteNext = true;
	}

	/**
	 * 步骤结束
	 */
	public void finishStep() {

		if (!mExecuteNext) {
			finish();
			return;
		}

		if (mCurrStep >= mStepCount) {
			finish();
			return;
		}

		mCurrStep++;
		mExecuteNext = false;
		switch (mCurrStep) {
		case 1:
			onStep1Start();
			break;
		case 2:
			onStep2Start();
			break;
		case 3:
			onStep3Start();
			break;
		default:
			finish();
			break;
		}
	}

	/**
	 * 开始执行
	 */
	public void execute() {
		// 确认步骤不重复
		if (!StepLine.getInstance().add(mTaskName)) {
			return;
		}

		if (!onStart()) {
			finish();
			return;
		}
		onStep1Start();
	}

	/**
	 * 结束所有步骤
	 */
	private void finish() {
		// 清空步骤轴
		StepLine.getInstance().add("");
		onFinish();
	}
}

实际应用中可以这么写:

new StepTask() {
			@Override
			protected boolean onStart() {
				if (!checkNetWork || !showProgress()) {
					// 没有网或者没有显示进度条
					return false;
				}
				return true;
			}

			@Override
			protected void onFinish() {
				dismissProgress();// 隐藏进度条
			}

			@Override
			protected void onStep1Start() {
				// 第一步开始,操作第一步,成功之后可以操作UI,如果要进行第二步,调用nextStep就可以,结束的时候调用finishStep
				// 如果不调用nextStep和finishStep就不会进行第二步了
			}

			@Override
			protected void onStep2Start() {
				// 第二步开始,操作成功后如果要调用第三步就和上面一样,然后复写onStep3Start,结束的时候调用finishStep

			}

		}.execute();


这样,两次网络请求就只会出现一次进度条,并且还可以通过Handler来操作UI,第一次请求成功了,后面的UI就可以更新。增强了应用的用户体验。

<think>好的,用户让我介绍一下电机控制器中断。首先,我需要明确电机控制器中断的基本概念。中断在计算机系统中很常见,但在电机控制中有其特殊性。应该先解释中断是什么,然后结合电机控制器的应用场景。 接下来,用户可能想知道为什么中断在电机控制器中重要。需要说明实时性的需求,比如电机控制需要快速响应传感器信号、故障检测等,中断能够及时处理这些事件,保证系统安全和性能。 然后,可能需要介绍中断的类型。常见的包括定时器中断、外部信号中断、故障保护中断、通信中断等。每种类型的具体例子和应用场景需要详细说明,比如PWM生成用定时器中断,过流保护用故障中断。 另外,处理流程也是一个重点。从中断触发到服务程序执行,再到退出恢复主程序,这个流程需要清晰描述。同时,要考虑优先级和嵌套处理,这对系统的实时性影响很大。 还要注意设计中的关键点,比如响应时间、服务程序的简洁性、优先级设置、资源共享问题(如使用临界区或信号量)以及错误处理机制。这些是确保中断系统稳定运行的重要因素。 最后,应用场景的举例能帮助用户更好地理解,比如无人机、工业机器人、电动汽车中的具体应用。可能用户有特定领域的需求,但如果没有明确说明,保持一般性的例子即可。 需要检查是否遵循了系统级指令:行内公式用$...$,独立公式用$$...$$,结构清晰,使用中文。确保LaTeX语法正确,比如积分符号、上下标等。可能用户是工程师或学生,需要技术细节但也要易于理解。避免使用过于专业的术语而不解释,保持口语化但准确。</think>电机控制器中断是实时控制系统中保证快速响应外部事件的核心机制。下面从原理、类型、处理流程和设计要点分步说明: 一、中断基本原理 在电机控制中,中断是处理器暂停当前任务,优先执行特定子程序的机制。其核心特征包括: - 实时响应:中断延迟通常<1μs(如Cortex-M4内核) - 硬件触发:通过NVIC(嵌套向量中断控制器)管理 - 事件驱动:响应如$V_{bus}$过压、$I_{phase}$过流等紧急事件 二、典型中断类型 1. 定时器中断(周期控制核心) $$f_{PWM} = \frac{1}{T_{ARR}+1} \times f_{CLK}$$ 用于PWM生成、SVPWM调制、电流采样同步 2. 外部信号中断 - 编码器Z脉冲($θ_{elec}=0°$定位) - 急停按钮触发 - 霍尔传感器边沿检测 3. 故障保护中断(最高优先级) | 故障类型 | 触发条件 | 响应动作 | |------------|------------------------|-------------------| | 过流保护 | $I_{peak} > 50A$ | 硬件闭锁PWM输出 | | 过温保护 | $T_{IGBT} > 150℃$ | 降频运行 | | 欠压保护 | $V_{DC} < 200V$ | 软关机 | 4. 通信中断 - CAN总线报文接收(如扭矩指令更新) - RS485参数修改请求 三、中断处理流程 1. 中断触发 → 2. 现场保护(压栈) → 3. 服务程序执行 → 4. 恢复现场 → 5. 返回主程序 关键时序要求举例: - 电流环中断:从ADC采样到PWM更新需在$T_{PWM}/2$内完成(如10kHz PWM需<50μs) - 故障保护中断:从检测到PWM闭锁应<500ns 四、设计要点 1. 中断嵌套管理 使用抢占优先级和子优先级分级: ```c NVIC_SetPriority(TIM1_UP_IRQn, 0x0); // 电流环最高优先级 NVIC_SetPriority(EXTI9_5_IRQn, 0x1); // 编码器中优先级 NVIC_SetPriority(USART1_IRQn, 0x3); // 通信最低优先级 ``` 2. 临界区处理 使用__disable_irq()和__enable_irq()保护共享资源: ```c void Speed_Update(void) { __disable_irq(); // 进入临界区 g_motor.rpm = Encoder_GetSpeed(); __enable_irq(); // 退出临界区 } ``` 3. 服务程序优化 - 执行时间<中断间隔的20% - 避免浮点运算(使用Q格式定点数) - DMA配合减少CPU负载(如ADC采样组通过DMA传输) 五、典型应用场景 1. 无人机电调:20kHz中断执行FOC算法 2. 工业机器人:多轴同步中断协调 3. 电动汽车:故障保护中断响应时间<2μs 实际开发中需通过示波器抓取中断响应波形(如使用GPIO引脚翻转法测量),并配合RTOS实现复杂任务调度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值