最近我在研究英飞凌的XMC1100 MCU,写了一个通过计时器来控制LED闪烁的小项目。这个项目展示了如何通过计时器来控制LED,每个消防员闪烁一次。代码简单但易于理解定时器和中断的基本操作很有帮助。这里会提供完整的代码示例和详细的讲解。
硬件需求:- 英飞凌XMC1100 Boot Kit开发板
- 板载LED,一般接在P1.0引脚上
项目的思路:
我们将使用英飞凌的DAVE工具来配置定时器,定时器每秒一次触发,进入中断后LED的状态,实现LED的定时触发。本项目主要占用了定时器和GPIO的外部设置,接下来我们逐步实现。
步骤一:初始化DAVE工具并生成基础代码
- 打开DAVE工具,选择新建项目,选中XMC1100 Boot Kit。
- 在项目资源管理器中,添加CCU4定时器和GPIO APP:
- CCU4时钟:配置时钟周期为1秒(1000ms)。
- GPIO:用于控制板加载LED的状态。
步骤二:代码实现
接下来,我们将在 DAVE 工具生成的基础代码上进行补充,手动控制按钮来切换 LED。
1.包含头文件和初始化函数
首先,在main.c文件中,包含DAVE生成的头文件,初始化MCU系统,并设置LED控制的GPIO口。
#include <DAVE.h> // DAVE工具生成的头文件
#include "xmc_gpio.h"
// LED引脚定义,连接到开发板上的P1.0口
#define LED_PIN P1_0
int main(void) {
// 初始化DAVE APPs
DAVE_Init();
// 初始化GPIO,P1_0作为输出
XMC_GPIO_CONFIG_t gpio_config;
gpio_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
gpio_config.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW;
XMC_GPIO_Init(LED_PIN, &gpio_config);
// 初始化定时器,启动计时
XMC_CCU4_EnableModule(CCU40);
XMC_CCU4_SLICE_CompareInit(CCU40_CC40, &slice_config);
XMC_CCU4_SLICE_StartTimer(CCU40_CC40);
while (1) {
// 主循环,不需要处理逻辑,LED闪烁在中断中处理
}
}
2. 定时器配置
接下来,我们手动配置计时器以每秒产生一个中断,并在中断中切换 LED 的状态。
// 定时器初始化配置
XMC_CCU4_SLICE_COMPARE_CONFIG_t slice_config = {
.timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
.monoshot = false,
.shadow_xfer_clear = 0U,
.dither_timer_period = 0U,
.dither_duty_cycle = 0U,
.prescaler_mode = XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
.mcm_ch1_enable = 0U,
.mcm_ch2_enable = 0U,
.prescaler_initval = XMC_CCU4_SLICE_PRESCALER_64,
.float_limit = 0U,
.dither_limit = 0U,
.passive_level_out0 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.passive_level_out1 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.timer_concatenation = 0U
};
// 定时器周期为1秒 (假设CCU4的时钟频率为64kHz, prescaler为64)
#define TIMER_PERIOD 1000
void timer_init(void) {
// 初始化定时器CCU4_SLICE,并设置周期为1秒
XMC_CCU4_EnableModule(CCU40);
XMC_CCU4_SLICE_CompareInit(CCU40_CC40, &slice_config);
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU40_CC40, TIMER_PERIOD);
XMC_CCU4_SLICE_SetTimerCompareMatch(CCU40_CC40, TIMER_PERIOD / 2); // 用于占空比
XMC_CCU4_EnableClock(CCU40, 0);
// 启动定时器
XMC_CCU4_SLICE_StartTimer(CCU40_CC40);
}
3.中断处理函数
我们需要配置一个定时器中断函数来控制LED的开关。在定时器中断发生时,调用XMC_GPIO_ToggleOutput切换LED状态。
// 定时器中断处理函数,切换LED状态
void CCU40_0_IRQHandler(void) {
// 切换LED状态
XMC_GPIO_ToggleOutput(LED_PIN);
// 清除定时器的中断标志
XMC_CCU4_SLICE_ClearEvent(CCU40_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
}
4. 总结代码结构
#include <DAVE.h>
#include "xmc_gpio.h"
#define LED_PIN P1_0
#define TIMER_PERIOD 1000
XMC_CCU4_SLICE_COMPARE_CONFIG_t slice_config = {
.timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
.monoshot = false,
.shadow_xfer_clear = 0U,
.dither_timer_period = 0U,
.dither_duty_cycle = 0U,
.prescaler_mode = XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
.mcm_ch1_enable = 0U,
.mcm_ch2_enable = 0U,
.prescaler_initval = XMC_CCU4_SLICE_PRESCALER_64,
.float_limit = 0U,
.dither_limit = 0U,
.passive_level_out0 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.passive_level_out1 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.timer_concatenation = 0U
};
void timer_init(void) {
XMC_CCU4_EnableModule(CCU40);
XMC_CCU4_SLICE_CompareInit(CCU40_CC40, &slice_config);
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU40_CC40, TIMER_PERIOD);
XMC_CCU4_SLICE_SetTimerCompareMatch(CCU40_CC40, TIMER_PERIOD / 2);
XMC_CCU4_EnableClock(CCU40, 0);
XMC_CCU4_SLICE_StartTimer(CCU40_CC40);
}
void CCU40_0_IRQHandler(void) {
XMC_GPIO_ToggleOutput(LED_PIN);
XMC_CCU4_SLICE_ClearEvent(CCU40_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
}
int main(void) {
DAVE_Init();
XMC_GPIO_CONFIG_t gpio_config;
gpio_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
gpio_config.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW;
XMC_GPIO_Init(LED_PIN, &gpio_config);
timer_init();
while (1) {
// 主循环
}
}
总结:
简单的代码演示了如何使用英飞凌XMC1100 MCU的CCU4定时器来控制LED的点亮。整个过程主要包括:
- 配置GPIO以控制LED。
- 配置定时器以产生1秒的周期中断。
- 在中断服务实例中切换LED的状态。
英飞凌的XMC系列MCU具有强大的定时器和中断系统,适用于各种嵌入式项目。通过DAVE工具,我们可以很轻松地配置外部设置,大大减轻了项目开发的难度。
|