该代码片段展示了使用 DALI(Digital Addressable Lighting Interface)协议的示例代码,主要包括初始化系统时钟、中断处理程序及电源管理的部分实现。以下是各部分代码的详细说明:
初始化系统时钟 SYS_Init()
该函数用于初始化系统时钟,包括:
- 解锁受保护的寄存器。
- 启用内部RC振荡器(HIRC)。
- 等待HIRC时钟稳定。
- 选择HIRC作为系统时钟,并将HCLK的分频系数设置为1。
- 更新系统核心时钟。
- 设置向量表地址到SRAM。
- 初始化电源检测(BOD)。
- 锁定受保护的寄存器。
电源检测中断处理程序 BOD_IRQHandler()
该函数用于处理BOD(Brown Out Detector)中断,当检测到电压过低时,将标志位 F_powerOff
置为真。
定时器1中断处理程序 TMR1_IRQHandler()
该函数是定时器1的中断处理程序,主要实现以下功能:
- 清除定时器中断标志。
- 更新OLED显示(如果启用)。
- 处理初始化状态计时。
- 检查系统故障标志,并采取相应措施。
- 处理发送两次命令计时。
- 检查电源循环标志,并在必要时更新灯光状态。
- 实现灯具故障检测和处理。
- 控制灯具的渐变过程。
检查灯具故障 checkLampFailure()
该函数用于检测灯具是否发生故障。如果检测到故障(例如灯具短路或开路),则将灯具状态设置为故障状态,并关闭灯具。
电源管理 checkPowerDown()
该函数用于在满足特定条件时进入低功耗模式,包括:
- 系统没有处于电源循环状态。
- 没有接收或发送数据。
- 灯具未打开且没有渐变活动。
- 没有灯具故障。
- 没有系统故障。
如果所有条件满足,将系统配置为进入低功耗模式,并在必要时重新配置I/O引脚。
Type 6状态检查 type6StatusCheck()
该函数根据硬件特性检测各种故障情况,包括:
- 短路检测。
- 开路检测。
- 负载减少检测。
- 负载增加检测。
- 电流保护功能检测。
每种检测功能根据相应的硬件条件判断故障情况,并更新故障状态标志。
其他功能
代码还包括其他功能的实现,如灯具识别、命令计时及处理、渐变控制、低功耗测试等。
以上是代码的主要功能和实现逻辑,如果有更多具体问题或需要详细解释的部分,请告知。
/**************************************************************************//**
* @file main.c
* @version V1.00
* @brief Demonstrate the DALI protocol.
*
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "NuMicro.h"
/* DALI Library */
#include "dali_cg_app.h"
#include "board_init.h"
volatile uint8_t F_powerDown = FALSE;
volatile uint8_t F_powerOff = FALSE;
#if(SSD1306_ENABLE)
#include "hal_tick_control.h"
volatile uint8_t F_updateOLED = 0, SSD1306_page = 0;
volatile uint8_t CG_206_Old = 10;
volatile uint8_t CG_207_Old = 254;
volatile uint8_t CG_208_Old = 1;
volatile uint8_t CG_209_Old = 1;
extern uint8_t OLEDi2cNoPullHigh;
#endif
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable HIRC clock (Internal RC 22.1184MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
/* Wait for HIRC clock ready */
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
/* Select HCLK clock source as HIRC and and HCLK source divider as 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
CLK_SetCoreClock(48000000);
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock and CycylesPerUs automatically. */
SystemCoreClockUpdate();
setVECTORtoSRAM();
BOD_Init(); //Enable BOD interrupt
/* Lock protected registers */
SYS_LockReg();
}
void BOD_IRQHandler(void)
{
SYS_CLEAR_BOD_INT_FLAG();
F_powerOff = F_write | F_writeBank;
}
void TMR1_IRQHandler(void)
{
volatile uint32_t tmpColourLevel, i;
volatile uint8_t state = 0;
// clear timer interrupt flag
TIMER_ClearIntFlag(TIMER1);
#if(SSD1306_ENABLE)
if ((F_OLEDStart) && (OLEDi2cNoPullHigh != 1))
{
uwTick++;
}
#endif
if (var_timeSlide == 0)
{
/*-----------------------------------------------------------------------------------------------------*/
/* Initialisation state timer */
/*-----------------------------------------------------------------------------------------------------*/
if (var_initialisationState != DISABLE)
{
if (g_parameter.initCounter >= INIT_TIME) //15 mins
{
g_parameter.initCounter = 0;
var_initialisationState = DISABLE;
}
else
{
g_parameter.initCounter++;
}
}
/*-----------------------------------------------------------------------------------------------------*/
/* F_checkSystemFailure will be set in the library when abnormal DALI bus situation happened. */
/*-----------------------------------------------------------------------------------------------------*/
if (F_checkSystemFailure)
{
if (g_parameter.systemFailureCounter == SYSTEM_FAILURE_TIME)
{
if (var_systemFailureLevel != MASK_u8)
{
var_targetLevel = setTargetLevel(var_systemFailureLevel);
var_actualLevel = var_targetLevel;
F_checkPowerCycle = FALSE;
}
#if(USE_TYPE8)
if (var_systemFailureColourType != MASK_u8)
{
var_temporaryColourType = var_systemFailureColourType;
gotoSystemFailureColour();
setColoutStatus(var_temporaryColourType);
clearTemporaryColourValuesBut(MASK_u8);
}
#endif
updateLight(var_actualLevel);
g_parameter.systemFailureCounter = 0;
F_checkSystemFailure = FALSE;
}
else
{
g_parameter.systemFailureCounter++;
}
}
/*-----------------------------------------------------------------------------------------------------*/
/* After receiving the first send-twice command, F_checkSendTwice will be set in the library */
/*---------------------------------------------------------------------------------------------