임계값 설정했으니 이제 Alert 핀 처리. 알람 발생하면 Alert 핀이 Low로 떨어진다.
Alert 핀 특성
- Open Drain 출력
- Active Low
- 여러 디바이스 Alert를 Wired-OR로 연결 가능
외부에 풀업 저항 필요:
VDD (3.3V)
│
[10kΩ]
│
├──── MCU GPIO (PB0)
│
└──── AD7280A Alert (모든 디바이스)
4개 디바이스 Alert를 한 핀에 연결. 어느 하나라도 알람 나면 Low.
STM32 EXTI 설정
CubeMX에서:
- PB0: GPIO_EXTI0
- Mode: External Interrupt Mode with Falling edge trigger
- Pull-up: Enable
// EXTI 콜백
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == ALERT_PIN) {
g_alert_flag = true;
}
}
디바운싱
노이즈 때문에 가짜 인터럽트가 뜰 수 있다. 디바운싱 필요.
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == ALERT_PIN) {
// 실제 Low인지 다시 확인
if (HAL_GPIO_ReadPin(ALERT_GPIO, ALERT_PIN) == GPIO_PIN_RESET) {
g_alert_flag = true;
}
}
}
ISR에서는 플래그만 세우고, 메인 루프에서 처리:
void BMS_Task(void) {
if (g_alert_flag) {
g_alert_flag = false;
// 50ms 후에도 Low면 진짜 알람
HAL_Delay(50);
if (HAL_GPIO_ReadPin(ALERT_GPIO, ALERT_PIN) == GPIO_PIN_RESET) {
BMS_HandleAlert();
}
}
}
어떤 디바이스인지 확인
Alert가 떴는데 4개 중 어디서 난 건지 알아야 한다.
각 디바이스의 Alert 레지스터 읽기:
void BMS_HandleAlert(void) {
for (int dev = 0; dev < 4; dev++) {
uint8_t alert = AD7280A_ReadRegister(dev, AD7280A_ALERT);
if (alert & 0x3F) { // 셀 알람 비트
printf("Dev %d Alert: 0x%02X\n", dev, alert);
BMS_ProcessAlert(dev, alert);
}
}
// Alert 클리어
AD7280A_Write(0x1F, AD7280A_ALERT, 0x00);
}
Alert 비트 해석
Alert 레지스터(0x18) 비트맵:
Bit 5: Cell 6 알람
Bit 4: Cell 5 알람
Bit 3: Cell 4 알람
Bit 2: Cell 3 알람
Bit 1: Cell 2 알람
Bit 0: Cell 1 알람
OV인지 UV인지는 실제 전압 읽어서 판단:
void BMS_ProcessAlert(uint8_t dev, uint8_t alert) {
for (int cell = 0; cell < 6; cell++) {
if (alert & (1 << cell)) {
uint16_t mv = AD7280A_ReadCellMillivolt(dev, cell);
if (mv > OV_THRESHOLD_MV) {
BMS_SetFault(FAULT_OVERVOLTAGE, dev * 6 + cell);
} else if (mv < UV_THRESHOLD_MV) {
BMS_SetFault(FAULT_UNDERVOLTAGE, dev * 6 + cell);
}
}
}
}
문제: Alert가 안 클리어됨
처음에 Alert 클리어가 안 됐다. 계속 Low 상태.
이유: 알람 조건이 해제 안 됐다. OV 상태에서 Alert 클리어해봤자 바로 다시 뜬다.
void BMS_HandleAlert(void) {
// 알람 원인 확인 및 조치
BMS_ProcessAlert();
// 조치 후에도 조건 유지되면 클리어 안 함
if (BMS_IsAlarmConditionCleared()) {
AD7280A_Write(0x1F, AD7280A_ALERT, 0x00);
}
}
정리
- Alert: Open Drain, Active Low
- Wired-OR로 4개 연결 가능
- EXTI 인터럽트로 빠르게 감지
- 디바운싱 필요
- 클리어 전에 조건 해제 확인
다음은 Alert 레지스터 상세 분석.