PHP Callback / Callable 类型 学习笔记

本文通过一个具体的PHP类实例,展示了如何使用回调函数和闭包。文章详细解释了如何定义类和对象,设置回调方法,并利用回调函数直接调用对象方法的过程。此外,还给出了一段静态方法作为回调函数的例子。

实例:

class Test {
    protected $items = array();
    protected $obj;
    public function __construct()
    {
        $this->obj = new Obj();
        $this->items[] = array($this, 'callBackOne');
        $this->items[] = array($this, 'callBackTwo');
        $this->items[] = array($this->obj, 'callObjOne');
        $this->items[] = array($this->obj, 'callObjTwo');
    }

    public function callBackOne()
    {
        echo __METHOD__ . ' has been called as a callback.';
    }

    public function callBackTwo()
    {
        echo __METHOD__ . ' has been called as a callback.';
    }

    public function getItems()
    {
        return $this->items;
    }
}

class Obj{
    public function callObjOne(){
        echo __METHOD__ . ' has been called as a callback.';;
    }
    public function callObjTwo(){
        echo __METHOD__ . ' has been called as a callback.';;
    }
}

$o = new Test();
$itemLists = $o->getItems();

foreach ($itemLists as $itemList) {
    echo '<pre>';
    echo "==========++++++++++=============";
    print_r($itemList);
    print_r($itemList());
    echo '</pre><br>';
}
结果:
==========++++++++++=============Array
(
    [0] => Test Object
        (
            [items:protected] => Array
                (
                    [0] => Array
 *RECURSION*
                    [1] => Array
                        (
                            [0] => Test Object
 *RECURSION*
                            [1] => callBackTwo
                        )

                    [2] => Array
                        (
                            [0] => Obj Object
                                (
                                )

                            [1] => callObjOne
                        )

                    [3] => Array
                        (
                            [0] => Obj Object
                                (
                                )

                            [1] => callObjTwo
                        )

                )

            [obj:protected] => Obj Object
                (
                )

        )

    [1] => callBackOne
)
Test::callBackOne has been called as a callback.

==========++++++++++=============Array
(
    [0] => Test Object
        (
            [items:protected] => Array
                (
                    [0] => Array
                        (
                            [0] => Test Object
 *RECURSION*
                            [1] => callBackOne
                        )

                    [1] => Array
 *RECURSION*
                    [2] => Array
                        (
                            [0] => Obj Object
                                (
                                )

                            [1] => callObjOne
                        )

                    [3] => Array
                        (
                            [0] => Obj Object
                                (
                                )

                            [1] => callObjTwo
                        )

                )

            [obj:protected] => Obj Object
                (
                )

        )

    [1] => callBackTwo
)
Test::callBackTwo has been called as a callback.

==========++++++++++=============Array
(
    [0] => Obj Object
        (
        )

    [1] => callObjOne
)
Obj::callObjOne has been called as a callback.

==========++++++++++=============Array
(
    [0] => Obj Object
        (
        )

    [1] => callObjTwo
)
Obj::callObjTwo has been called as a callback.
综上示例:array($object,$object方法名)()可以直接调用$object方法中对应的方法


class Foo {
    public static function doAwesomeThings() {
        FunctionCaller::callIt(self::class . '::someAwesomeMethod');
    }

    public static function someAwesomeMethod() {
        echo "静态方法Callback/callable类型的调用";
    }
}

class FunctionCaller {
    public static function callIt(callable $func) {
        call_user_func($func);
    }
}

Foo::doAwesomeThings();
执行结果:静态方法Callback/callable类型的调用
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) void (* Base_MspInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Base Msp Init Callback / void ( Base_MspDeInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Base Msp DeInit Callback / void ( IC_MspInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM IC Msp Init Callback / void ( IC_MspDeInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM IC Msp DeInit Callback / void ( OC_MspInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM OC Msp Init Callback / void ( OC_MspDeInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM OC Msp DeInit Callback / void ( PWM_MspInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM PWM Msp Init Callback / void ( PWM_MspDeInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM PWM Msp DeInit Callback / void ( OnePulse_MspInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM One Pulse Msp Init Callback / void ( OnePulse_MspDeInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM One Pulse Msp DeInit Callback / void ( Encoder_MspInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Encoder Msp Init Callback / void ( Encoder_MspDeInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Encoder Msp DeInit Callback / void ( HallSensor_MspInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Hall Sensor Msp Init Callback / void ( HallSensor_MspDeInitCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Hall Sensor Msp DeInit Callback / void ( PeriodElapsedCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Period Elapsed Callback / void ( PeriodElapsedHalfCpltCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Period Elapsed half complete Callback / void ( TriggerCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Trigger Callback / void ( TriggerHalfCpltCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Trigger half complete Callback / void ( IC_CaptureCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Input Capture Callback / void ( IC_CaptureHalfCpltCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Input Capture half complete Callback / void ( OC_DelayElapsedCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Output Compare Delay Elapsed Callback / void ( PWM_PulseFinishedCallback)(struct __TIM_HandleTypeDef htim); /!< TIM PWM Pulse Finished Callback / void ( PWM_PulseFinishedHalfCpltCallback)(struct __TIM_HandleTypeDef htim); /!< TIM PWM Pulse Finished half complete Callback / void ( ErrorCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Error Callback / void ( CommutationCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Commutation Callback / void ( CommutationHalfCpltCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Commutation half complete Callback / void ( BreakCallback)(struct __TIM_HandleTypeDef htim); /!< TIM Break Callback / #endif / USE_HAL_TIM_REGISTER_CALLBACKS */ } TIM_HandleTypeDef 这里面如果要用htim1怎么用
最新发布
07-05
在 STM32 HAL 库中,如果要在 `TIM_HandleTypeDef` 中使用 **TIM1**(高级定时器),需要正确初始化 `TIM_HandleTypeDef` 结构体,并注册相应的回调函数(如果启用了 `USE_HAL_TIM_REGISTER_CALLBACKS`)。以下是详细步骤: --- ### **1. 定义 `TIM_HandleTypeDef` 结构体** 首先,定义一个 `TIM_HandleTypeDef` 变量(如 `htim1`),并配置其参数: ```c TIM_HandleTypeDef htim1; ``` --- ### **2. 初始化 TIM1** 在 `main.c` 或初始化函数中配置 TIM1 的参数(如预分频器、计数模式、周期等): ```c void MX_TIM1_Init(void) { htim1.Instance = TIM1; // 指定 TIM1 htim1.Init.Prescaler = 15999; // 16MHz / (15999+1) = 1kHz htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; // 1kHz / 1000 = 1Hz (1秒中断一次) htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; // 高级定时器专用 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); // 初始化失败处理 } // 如果需要 PWM、输入捕获等功能,额外调用 HAL_TIM_XXX_Init() // 例如:HAL_TIM_PWM_Init(&htim1); } ``` --- ### **3. 注册回调函数(可选)** 如果 `USE_HAL_TIM_REGISTER_CALLBACKS == 1`,可以注册自定义回调函数: ```c void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM1) { // 判断是否是 TIM1 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 翻转 LED } } void MX_TIM1_Init(void) { // ... 初始化代码 ... htim1.PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; // 注册回调 } ``` --- ### **4. 启动 TIM1** 根据需求启动定时器(中断模式或普通模式): ```c // 启动定时器中断 HAL_TIM_Base_Start_IT(&htim1); // 或者启动 PWM 输出 // HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); ``` --- ### **5. 配置中断(如果使用中断)** 在 `stm32xxxx_it.c` 中实现 TIM1 的中断处理函数(HAL 库会自动调用回调): ```c void TIM1_UP_TIM10_IRQHandler(void) { HAL_TIM_IRQHandler(&htim1); // 内部会调用注册的回调函数 } ``` --- ### **6. 完整示例** #### **(1) 初始化代码** ```c TIM_HandleTypeDef htim1; void MX_TIM1_Init(void) { htim1.Instance = TIM1; htim1.Init.Prescaler = 15999; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } // 注册回调(可选) htim1.PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; // 启动中断 HAL_TIM_Base_Start_IT(&htim1); } ``` #### **(2) 回调函数** ```c void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 每秒翻转 LED } } ``` #### **(3) 中断处理** ```c void TIM1_UP_TIM10_IRQHandler(void) { HAL_TIM_IRQHandler(&htim1); } ``` --- ### **7. 注意事项** 1. **高级定时器(TIM1/TIM8)的特殊性** - TIM1 是高级定时器,支持刹车功能(Break)、重复计数器(RepetitionCounter)等。 - 如果需要 PWM 互补输出或死区控制,需额外配置 `HAL_TIMEx_ConfigBreakDeadTime()`。 2. **中断优先级** - 在 `HAL_NVIC_SetPriority()` 和 `HAL_NVIC_EnableIRQ()` 中设置 TIM1 中断优先级(如 `TIM1_UP_TIM10_IRQn`)。 3. **时钟配置** - 确保 TIM1 的时钟已启用(在 `SystemClock_Config()` 中配置 APB2 时钟)。 4. **GPIO 配置** - 如果使用 PWM 或输入捕获,需配置对应的 GPIO(如 `TIM1_CH1` 对应 `PA8`)。 --- ### **8. 扩展功能** - **PWM 输出** ```c TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 500; // 50% 占空比 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); ``` - **输入捕获** ```c TIM_IC_InitTypeDef sConfigIC = {0}; sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); ``` --- ### **总结** 1. **定义 `TIM_HandleTypeDef htim1`** 并配置参数。 2. **初始化 TIM1**(`HAL_TIM_Base_Init()` 或其他功能初始化)。 3. **注册回调函数**(如果需要自定义中断处理)。 4. **启动定时器**(中断模式或 PWM/输入捕获模式)。 5. **实现中断处理函数**(如 `TIM1_UP_TIM10_IRQHandler`)。 通过以上步骤,可以灵活使用 TIM1 的各种功能(定时中断、PWM、输入捕获等)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值