
一、设计概述
本设计以 ATMEGA168 单片机为核心,针对公共场所 / 家庭场景的消毒需求,实现一款集定时消毒、人体感应防护、多模式消毒、状态显示 于一体的智能消毒机系统。系统支持紫外线 / 臭氧两种主流消毒方式(可按需选配),通过人体红外传感器实现 "有人即停" 的安全防护,同时提供按键设置消毒时长、蜂鸣器报警、LED 状态指示等功能,兼顾实用性与安全性。
核心功能
- 消毒模式控制:支持紫外线消毒、臭氧消毒、组合消毒三种模式,可通过按键切换;
- 定时功能:0~60 分钟可调消毒时长,到达设定时间自动停止消毒;
- 安全防护:人体红外感应(PIR)检测到有人时,立即停止消毒并报警,防止紫外线 / 臭氧伤害;
- 状态指示:LED 灯显示当前工作模式、消毒倒计时、异常状态;
- 报警提示:人体闯入、超时工作、设备故障时蜂鸣器报警;
- 手动控制:按键启停消毒、调整时长 / 模式,紧急停止按键(急停)。
二、硬件选型与电路设计
1. 核心硬件清单
| 模块 | 型号 / 规格 | 作用 |
|---|---|---|
| 主控单片机 | ATMEGA168PA-AU(8 位 AVR) | 数据处理、逻辑控制 |
| 消毒模块 | 紫外线灯(12V)/ 臭氧发生器(5V) | 执行消毒动作 |
| 人体感应传感器 | HC-SR501(PIR) | 检测人体靠近 |
| 驱动模块 | 继电器模块(5V/2 路) | 驱动紫外线灯 / 臭氧发生器 |
| 显示模块 | 四位数码管(共阴 / 共阳) | 显示消毒时长 / 倒计时 |
| 按键 | 轻触按键 ×4(模式 / 加 / 减 / 启停) | 手动设置参数、控制设备 |
| 蜂鸣器 | 无源蜂鸣器(5V) | 报警提示 |
| 状态 LED | 红 / 绿 / 蓝 LED×3 | 指示模式 / 异常状态 |
| 电源模块 | 220V 转 12V/5V 适配器 | 为系统供电 |
| 保险丝 | 500mA 保险丝 | 过流保护 |
2. 核心电路设计
ATMEGA168 核心资源:14 路数字 I/O、8 路 10 位 ADC、3 路定时器 / 计数器,满足系统需求。
(1)主控电路(最小系统)
- 电源:5V 直流供电,VCC 接 5V,GND 共地;
- 晶振:16MHz 外部晶振(XTAL1/XTAL2),搭配 22pF 电容接地,保证时钟稳定;
- 复位:RESET 引脚接 10K 上拉电阻,并联轻触按键(按下接地),实现手动复位;
- ISP 下载:PC0~PC3(SPI 接口),用于程序烧录。
(2)外设连接电路
| 外设 | 连接引脚(ATMEGA168) | 备注 |
|---|---|---|
| PIR 传感器 | 数字引脚 D2(INT0) | 中断触发,有人时立即响应 |
| 紫外线继电器 | 数字引脚 D3 | 高电平吸合,驱动 12V 紫外灯 |
| 臭氧继电器 | 数字引脚 D4 | 高电平吸合,驱动 5V 臭氧发生器 |
| 数码管段选 | D5~D11(a~g + 小数点) | 7 段 + 小数点,共 8 路 |
| 数码管位选 | A0~A3(PC0~PC3) | 四位数码管独立控制 |
| 模式按键 | D12 | 下拉电阻,按下接 5V |
| 加键 | D13 | 下拉电阻,按下接 5V |
| 减键 | A4(PC4) | 下拉电阻,按下接 5V |
| 启停 / 急停键 | A5(PC5) | 下拉电阻,按下接 5V |
| 蜂鸣器 | A6(PC6) | 三极管驱动,PWM 发声 |
| 状态 LED(红) | A7(PC7) | 串联 220Ω 限流电阻 |
| 状态 LED(绿) | D0 | 串联 220Ω 限流电阻 |
| 状态 LED(蓝) | D1 | 串联 220Ω 限流电阻 |
(3)关键防护电路
- 紫外线 / 臭氧继电器:触点并联 1N4007 续流二极管,防止感性负载反向电动势损坏继电器;
- 电源输入端:串联保险丝,并联 0.1μF 滤波电容,降低电压波动;
- PIR 传感器:输出端串联 1K 限流电阻,防止过流损坏单片机 I/O 口。
3. 电路原理图(简化框架)
plaintext
ATMEGA168最小系统
|-- 16MHz晶振(XTAL1/XTAL2)+ 22pF电容
|-- RESET(上拉10K + 复位按键)
|-- ISP下载(PC0~PC3)
|-- D2 → HC-SR501输出(INT0中断)
|-- D3 → 紫外线继电器控制端 → 12V紫外灯
|-- D4 → 臭氧继电器控制端 → 5V臭氧发生器
|-- D5~D11 → 数码管段选(a~g+dp)
|-- PC0~PC3 → 数码管位选(四位)
|-- D12/D13/PC4/PC5 → 模式/加/减/启停按键
|-- PC6 → 蜂鸣器(NPN三极管驱动)
|-- PC7/D0/D1 → 红/绿/蓝状态LED
|-- VCC → 5V电源,GND → 共地
220V→12V适配器 → 12V紫外灯 + 12V转5V模块 → 单片机/传感器供电
三、软件设计
1. 开发环境与核心资源
- 开发环境:Atmel Studio 7.0(或 Arduino IDE,需安装 ATMEGA168 支持);
- 编程语言:C 语言(AVR-GCC 编译器);
- 核心资源:
- 定时器:Timer0(8 位)实现 1ms 系统时钟,Timer1(16 位)实现倒计时;
- 外部中断:INT0(D2)响应 PIR 人体感应;
- GPIO:数字 I/O 控制继电器、按键、LED;
- SPI:可选扩展(本设计暂未使用)。
2. 程序架构
plaintext
主程序流程:
1. 初始化:
a. 端口初始化(I/O方向、上拉/下拉);
b. 定时器初始化(1ms中断、倒计时计时);
c. 外部中断初始化(INT0下降沿触发,PIR检测);
d. 数码管/LED初始化(默认显示00:00,绿灯常亮);
e. 变量初始化(默认模式:紫外线,时长:15分钟,状态:待机)。
2. 主循环:
a. 按键扫描:检测模式/加/减/启停键,更新消毒模式/时长;
b. 状态机处理:
- 待机状态:响应按键,修改参数,数码管显示设定时长;
- 运行状态:启动继电器,数码管倒计时,检测剩余时间;
- 报警状态:人体闯入/故障,停止消毒,蜂鸣器报警,红灯闪烁;
c. 倒计时更新:每秒刷新数码管显示;
d. 状态LED更新:不同模式对应不同LED颜色(紫外-蓝,臭氧-绿,组合-紫);
3. 中断服务函数:
a. INT0中断(PIR触发):立即停止消毒,进入报警状态;
b. 定时器中断:1ms计时,实现秒级倒计时、按键消抖。
3. 核心代码示例(AVR C)
c
运行
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// 引脚定义
#define PIR_PIN PD2 // INT0,PIR传感器
#define UV_RELAY PD3 // 紫外线继电器
#define OZONE_RELAY PD4 // 臭氧继电器
#define BUZZER PC6 // 蜂鸣器
// 数码管段选(a~g+dp):D5~D11对应PORTD5~D7 + PORTB0~B3
#define SEG_PORT_D PORTD
#define SEG_PORT_B PORTB
// 数码管位选:PC0~PC3
#define BIT_PORT PORTC
// 按键引脚
#define KEY_MODE PD12 // 模式键
#define KEY_ADD PD13 // 加键
#define KEY_SUB PC4 // 减键
#define KEY_START PC5 // 启停键
// 全局变量
typedef enum {
MODE_STANDBY, // 待机
MODE_UV, // 紫外线消毒
MODE_OZONE, // 臭氧消毒
MODE_COMBO, // 组合消毒
MODE_ALARM // 报警
} WorkMode;
WorkMode currentMode = MODE_STANDBY;
uint16_t setTime = 15; // 默认消毒时长(分钟)
uint16_t remainTime = 0; // 剩余时间(秒)
bool isRunning = false; // 运行状态
bool pirDetect = false; // 人体感应标志
// 数码管段码表(共阴,0~9,带小数点)
uint8_t segCode[16] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
// 延时函数(简易)
void delay_ms(uint16_t ms) {
while(ms--) _delay_ms(1);
}
// 端口初始化
void port_init() {
// 输出端口:继电器、蜂鸣器、数码管、LED
DDRD |= (1<<UV_RELAY)|(1<<OZONE_RELAY)|0xF8; // D3-D4输出,D5-D7输出(段选)
DDRB |= 0x0F; // B0-B3输出(段选)
DDRC |= (1<<BUZZER)|0xFF; // PC0-PC7输出(位选+蜂鸣器+LED)
// 输入端口:PIR、按键(上拉电阻)
DDRD &= ~((1<<PIR_PIN)|(1<<KEY_MODE)|(1<<KEY_ADD));
DDRC &= ~((1<<KEY_SUB)|(1<<KEY_START));
PORTD |= (1<<PIR_PIN)|(1<<KEY_MODE)|(1<<KEY_ADD); // 上拉
PORTC |= (1<<KEY_SUB)|(1<<KEY_START); // 上拉
}
// 定时器初始化(1ms中断)
void timer_init() {
TCCR0A = (1<<WGM01); // CTC模式
TCCR0B = (1<<CS01)|(1<<CS00); // 64分频,16MHz→250KHz
OCR0A = 249; // 250KHz / 250 = 1KHz → 1ms中断
TIMSK0 = (1<<OCIE0A); // 使能比较匹配中断
sei(); // 开启全局中断
}
// 外部中断初始化(INT0,PIR触发)
void interrupt_init() {
EICRA = (1<<ISC01)|(1<<ISC00); // 上升沿触发(PIR检测到人时输出高电平)
EIMSK = (1<<INT0); // 使能INT0中断
}
// 数码管显示函数(显示分钟:秒,如15→0015,5分30秒→0530)
void display(uint16_t time) {
uint8_t min = time / 60;
uint8_t sec = time % 60;
uint8_t num[4] = {min/10, min%10, sec/10, sec%10};
for(uint8_t i=0; i<4; i++) {
// 段选输出
SEG_PORT_D = (segCode[num[i]] & 0xE0) | (SEG_PORT_D & 0x1F); // D5-D7
SEG_PORT_B = (segCode[num[i]] & 0x1F) | (SEG_PORT_B & 0xE0); // B0-B3
// 位选输出(仅当前位亮)
BIT_PORT &= ~0x0F;
BIT_PORT |= (1<<i);
delay_ms(1); // 消影延时
}
BIT_PORT &= ~0x0F; // 关闭所有位
}
// 按键扫描函数
void key_scan() {
// 模式键
if(!(PIND & (1<<KEY_MODE))) {
delay_ms(20); // 消抖
if(!(PIND & (1<<KEY_MODE))) {
switch(currentMode) {
case MODE_STANDBY: currentMode = MODE_UV; break;
case MODE_UV: currentMode = MODE_OZONE; break;
case MODE_OZONE: currentMode = MODE_COMBO; break;
case MODE_COMBO: currentMode = MODE_STANDBY; break;
default: currentMode = MODE_STANDBY;
}
while(!(PIND & (1<<KEY_MODE))); // 等待释放
}
}
// 加键(时长+1分钟,最大60)
if(!(PIND & (1<<KEY_ADD)) && currentMode == MODE_STANDBY) {
delay_ms(20);
if(!(PIND & (1<<KEY_ADD))) {
setTime = (setTime + 1) % 61;
if(setTime == 0) setTime = 1;
while(!(PIND & (1<<KEY_ADD)));
}
}
// 减键(时长-1分钟,最小1)
if(!(PINC & (1<<KEY_SUB)) && currentMode == MODE_STANDBY) {
delay_ms(20);
if(!(PINC & (1<<KEY_SUB))) {
setTime = (setTime - 1) % 61;
if(setTime == 0) setTime = 60;
while(!(PINC & (1<<KEY_SUB)));
}
}
// 启停键
if(!(PINC & (1<<KEY_START))) {
delay_ms(20);
if(!(PINC & (1<<KEY_START))) {
isRunning = !isRunning;
if(isRunning) {
remainTime = setTime * 60; // 转换为秒
// 根据模式启动继电器
switch(currentMode) {
case MODE_UV: PORTD |= (1<<UV_RELAY); break;
case MODE_OZONE: PORTD |= (1<<OZONE_RELAY); break;
case MODE_COMBO: PORTD |= (1<<UV_RELAY)|(1<<OZONE_RELAY); break;
default: isRunning = false;
}
} else {
// 停止所有继电器
PORTD &= ~((1<<UV_RELAY)|(1<<OZONE_RELAY));
remainTime = 0;
}
while(!(PINC & (1<<KEY_START)));
}
}
}
// 报警函数(蜂鸣器响+红灯闪烁)
void alarm() {
PORTC |= (1<<PC7); // 红灯亮
PORTC ^= (1<<BUZZER); // 蜂鸣器翻转
delay_ms(200);
PORTC &= ~(1<<PC7); // 红灯灭
delay_ms(200);
}
// 外部中断服务函数(PIR检测到人)
ISR(INT0_vect) {
if(isRunning) {
currentMode = MODE_ALARM;
isRunning = false;
PORTD &= ~((1<<UV_RELAY)|(1<<OZONE_RELAY)); // 停止消毒
pirDetect = true;
}
}
// 定时器中断服务函数(1ms)
ISR(TIMER0_COMPA_vect) {
static uint16_t cnt = 0;
cnt++;
if(cnt >= 1000) { // 1秒
cnt = 0;
if(isRunning && remainTime > 0) {
remainTime--;
// 倒计时结束
if(remainTime == 0) {
isRunning = false;
PORTD &= ~((1<<UV_RELAY)|(1<<OZONE_RELAY));
currentMode = MODE_STANDBY;
}
}
}
}
// 主函数
int main(void) {
port_init();
timer_init();
interrupt_init();
while(1) {
key_scan(); // 按键扫描
switch(currentMode) {
case MODE_STANDBY:
PORTC |= (1<<PC0); // 绿灯亮
display(setTime * 60); // 显示设定时长
break;
case MODE_UV:
PORTC |= (1<<PC1); // 蓝灯亮
if(isRunning) display(remainTime);
else display(setTime * 60);
break;
case MODE_OZONE:
PORTC |= (1<<PC2); // 绿灯亮
if(isRunning) display(remainTime);
else display(setTime * 60);
break;
case MODE_COMBO:
PORTC |= (1<<PC1)|(1<<PC2); // 蓝+绿=紫灯亮
if(isRunning) display(remainTime);
else display(setTime * 60);
break;
case MODE_ALARM:
alarm(); // 报警
pirDetect = false;
currentMode = MODE_STANDBY;
break;
default:
currentMode = MODE_STANDBY;
}
// 清除LED(避免叠加)
PORTC &= ~((1<<PC0)|(1<<PC1)|(1<<PC2));
}
}
四、系统调试与优化
1. 硬件调试
- 最小系统调试:烧录测试程序,验证晶振、复位、ISP 下载功能正常;
- 传感器调试:用手靠近 PIR 传感器,检测 INT0 中断是否触发,确保 "有人即停";
- 继电器调试:测试继电器吸合 / 断开是否正常,紫外灯 / 臭氧发生器能否可靠启停;
- 数码管调试:校准显示精度,消除重影(增加消影延时),确保倒计时准确;
- 电源调试:测试满载时电压稳定性,避免水泵 / 紫外灯启动时电压跌落。
2. 软件优化
- 按键消抖:增加 20ms 消抖延时,避免误触发;
- 倒计时精度:采用 16 位定时器(Timer1)替代 8 位定时器,提升计时准确性;
- 异常处理:增加继电器粘连检测(通过反馈引脚),防止设备失控;
- 低功耗优化:待机时关闭定时器以外的外设,降低功耗;
- 报警逻辑:区分 "人体闯入" 和 "时长结束" 报警(不同蜂鸣频率)。
3. 安全验证
- 人体感应响应时间:≤100ms,确保及时停止消毒;
- 急停按键:按下后立即切断所有继电器,优先级最高;
- 过流保护:保险丝在短路时及时熔断,防止火灾隐患;
- 绝缘处理:220V/12V 电路隔离,避免触电风险。
五、功能扩展建议
- 蓝牙 / 红外遥控:增加 HC-05 蓝牙模块,支持手机 APP 远程设置时长 / 模式;
- 消毒记录存储:外接 AT24C02 EEPROM,记录每次消毒时长、时间;
- 环境适配:增加温湿度传感器(DHT11),根据湿度自动调整臭氧消毒时长;
- 语音提示:增加 SYN6288 语音模块,播报 "消毒开始 / 结束 / 有人闯入";
- 联网功能:替换为 ATMEGA168+ESP8266 组合,接入物联网平台,远程监控设备状态。
六、总结
本设计基于 ATMEGA168 单片机实现了消毒机的核心功能,硬件电路简洁可靠,软件逻辑兼顾实用性与安全性。通过人体感应防护、定时控制、多模式切换等设计,满足不同场景的消毒需求;同时具备易扩展、低成本的特点,可适配家庭、办公室、医院等多种场所的消毒应用。调试过程中需重点关注安全防护逻辑,确保紫外线 / 臭氧不会对人体造成伤害。