[XMC™] 使用英飞凌XMC1100 MCU和二极管中断实现LED触发的完整代码解析

[复制链接]
2535|10
 楼主| Bblythe 发表于 2024-10-4 12:02 | 显示全部楼层 |阅读模式
最近我在研究英飞凌的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口。

  1. #include <DAVE.h>  // DAVE工具生成的头文件
  2. #include "xmc_gpio.h"

  3. // LED引脚定义,连接到开发板上的P1.0口
  4. #define LED_PIN P1_0

  5. int main(void) {
  6.     // 初始化DAVE APPs
  7.     DAVE_Init();

  8.     // 初始化GPIO,P1_0作为输出
  9.     XMC_GPIO_CONFIG_t gpio_config;
  10.     gpio_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
  11.     gpio_config.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW;
  12.     XMC_GPIO_Init(LED_PIN, &gpio_config);

  13.     // 初始化定时器,启动计时
  14.     XMC_CCU4_EnableModule(CCU40);
  15.     XMC_CCU4_SLICE_CompareInit(CCU40_CC40, &slice_config);
  16.     XMC_CCU4_SLICE_StartTimer(CCU40_CC40);

  17.     while (1) {
  18.         // 主循环,不需要处理逻辑,LED闪烁在中断中处理
  19.     }
  20. }
2. 定时器配置
接下来,我们手动配置计时器以每秒产生一个中断,并在中断中切换 LED 的状态。

  1. // 定时器初始化配置
  2. XMC_CCU4_SLICE_COMPARE_CONFIG_t slice_config = {
  3.     .timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
  4.     .monoshot = false,
  5.     .shadow_xfer_clear = 0U,
  6.     .dither_timer_period = 0U,
  7.     .dither_duty_cycle = 0U,
  8.     .prescaler_mode = XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
  9.     .mcm_ch1_enable = 0U,
  10.     .mcm_ch2_enable = 0U,
  11.     .prescaler_initval = XMC_CCU4_SLICE_PRESCALER_64,
  12.     .float_limit = 0U,
  13.     .dither_limit = 0U,
  14.     .passive_level_out0 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
  15.     .passive_level_out1 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
  16.     .timer_concatenation = 0U
  17. };

  18. // 定时器周期为1秒 (假设CCU4的时钟频率为64kHz, prescaler为64)
  19. #define TIMER_PERIOD 1000

  20. void timer_init(void) {
  21.     // 初始化定时器CCU4_SLICE,并设置周期为1秒
  22.     XMC_CCU4_EnableModule(CCU40);
  23.     XMC_CCU4_SLICE_CompareInit(CCU40_CC40, &slice_config);
  24.     XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU40_CC40, TIMER_PERIOD);
  25.     XMC_CCU4_SLICE_SetTimerCompareMatch(CCU40_CC40, TIMER_PERIOD / 2);  // 用于占空比
  26.     XMC_CCU4_EnableClock(CCU40, 0);
  27.    
  28.     // 启动定时器
  29.     XMC_CCU4_SLICE_StartTimer(CCU40_CC40);
  30. }

3.中断处理函数
我们需要配置一个定时器中断函数来控制LED的开关。在定时器中断发生时,调用XMC_GPIO_ToggleOutput切换LED状态。

  1. // 定时器中断处理函数,切换LED状态
  2. void CCU40_0_IRQHandler(void) {
  3.     // 切换LED状态
  4.     XMC_GPIO_ToggleOutput(LED_PIN);
  5.    
  6.     // 清除定时器的中断标志
  7.     XMC_CCU4_SLICE_ClearEvent(CCU40_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
  8. }

4. 总结代码结构
  1. #include <DAVE.h>
  2. #include "xmc_gpio.h"

  3. #define LED_PIN P1_0
  4. #define TIMER_PERIOD 1000

  5. XMC_CCU4_SLICE_COMPARE_CONFIG_t slice_config = {
  6.     .timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
  7.     .monoshot = false,
  8.     .shadow_xfer_clear = 0U,
  9.     .dither_timer_period = 0U,
  10.     .dither_duty_cycle = 0U,
  11.     .prescaler_mode = XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
  12.     .mcm_ch1_enable = 0U,
  13.     .mcm_ch2_enable = 0U,
  14.     .prescaler_initval = XMC_CCU4_SLICE_PRESCALER_64,
  15.     .float_limit = 0U,
  16.     .dither_limit = 0U,
  17.     .passive_level_out0 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
  18.     .passive_level_out1 = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
  19.     .timer_concatenation = 0U
  20. };

  21. void timer_init(void) {
  22.     XMC_CCU4_EnableModule(CCU40);
  23.     XMC_CCU4_SLICE_CompareInit(CCU40_CC40, &slice_config);
  24.     XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU40_CC40, TIMER_PERIOD);
  25.     XMC_CCU4_SLICE_SetTimerCompareMatch(CCU40_CC40, TIMER_PERIOD / 2);
  26.     XMC_CCU4_EnableClock(CCU40, 0);
  27.     XMC_CCU4_SLICE_StartTimer(CCU40_CC40);
  28. }

  29. void CCU40_0_IRQHandler(void) {
  30.     XMC_GPIO_ToggleOutput(LED_PIN);
  31.     XMC_CCU4_SLICE_ClearEvent(CCU40_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
  32. }

  33. int main(void) {
  34.     DAVE_Init();

  35.     XMC_GPIO_CONFIG_t gpio_config;
  36.     gpio_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
  37.     gpio_config.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW;
  38.     XMC_GPIO_Init(LED_PIN, &gpio_config);

  39.     timer_init();

  40.     while (1) {
  41.         // 主循环
  42.     }
  43. }

总结:
简单的代码演示了如何使用英飞凌XMC1100 MCU的CCU4定时器来控制LED的点亮。整个过程主要包括:
  • 配置GPIO以控制LED。
  • 配置定时器以产生1秒的周期中断。
  • 在中断服务实例中切换LED的状态。

英飞凌的XMC系列MCU具有强大的定时器和中断系统,适用于各种嵌入式项目。通过DAVE工具,我们可以很轻松地配置外部设置,大大减轻了项目开发的难度。


公羊子丹 发表于 2024-10-4 12:03 | 显示全部楼层
哇,这个代码真不错!定时器顺序控制LED太实用了,学习了!
周半梅 发表于 2024-10-4 12:03 | 显示全部楼层
正好手头有块 XMC1100 开发板,打算试试你可能的代码。感谢分享!
帛灿灿 发表于 2024-10-4 12:04 | 显示全部楼层
之前一直用STM32,看了这个帖子,准备转战XMC了,配置好简单啊!
童雨竹 发表于 2024-10-4 12:04 | 显示全部楼层
这个教程很详细,尤其是楼梯部分,给新手非常友好。赞一个!
万图 发表于 2024-10-4 12:05 | 显示全部楼层
关于中断处理这块,讲得很清楚,明天就上手尝试。
Wordsworth 发表于 2024-10-4 12:05 | 显示全部楼层
我还没开始头疼,这下终于搞明白了!谢谢!
Pulitzer 发表于 2024-10-4 12:05 | 显示全部楼层
我也用XMC1100,看到你的例子对计时器配置更有信心了!
Uriah 发表于 2024-10-4 12:06 | 显示全部楼层
想问一下,大概代码能直接移植到XMC1400吗?我刚开始学英飞凌的MCU。
Clyde011 发表于 2024-10-4 12:06 | 显示全部楼层
写得很棒,尤其是用 DAVE 工具生成基础代码,省得惊人!
Amazingxixixi 发表于 2024-10-30 15:45 | 显示全部楼层
LED触发?是光学转换么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

166

主题

6125

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部