硬件组成:
LCD1602+脉搏测量电路(带灯)+蜂鸣器报警+按键设置+AT24C02
功能:
(1)LCD1602主页显示脉搏、报警上限、报警下限;
(2)五个按键:按键1:切换设置上限和设置下限;
按键2:查看存的脉搏数值;
按键3:设置的时候加数值功能,查看存储的时候上翻页功能;
按键4:设置的时候减数值功能,查看存储的时候下翻页功能;
(3)脉搏不在上下限范围就报警;
(4)在正常测量中,每次测量出一次脉搏后,程序自动保存此次测量结果。
(5)使用AT24C02芯片存储100组脉搏信息,可以掉电保存;同时也存储设置的上下限,可以掉电保存;
随意加个时间显示
实验报告:ATmega8控制脉搏测量与显示系统
实验目的
设计并实现一个基于ATmega8微控制器的脉搏测量与显示系统,主要功能包括脉搏测量、上下限设置、报警功能和数据存储。
背景与原理
在本实验中,我们使用ATmega8微控制器、LCD1602显示器、DS1302时钟芯片以及AT24C02存储芯片构建了一个简易的脉搏测量与显示系统。系统通过脉搏测量电路获取脉搏信号,并在LCD1602上显示测量结果和设定的上下限值。当脉搏不在设定范围内时,系统会触发报警。此外,测量数据会存储在AT24C02芯片中,即使断电也能保持数据完整。
硬件组成
- ATmega8微控制器
- LCD1602显示器
- DS1302时钟芯片
- AT24C02存储芯片
- 脉搏测量电路
- 蜂鸣器报警
- 按键
电路连接
- ATmega8与LCD1602连接:
- 数据线:PD0-PD7
- 控制线:PC0(RS)、PC1(RW)、PC2(E)
- DS1302与ATmega8连接:
- RST:PC5
- SCLK:PD6
- IO:PD5
- AT24C02与ATmega8连接:
- SDA:PC4
- SCL:PC5
- 脉搏测量电路:通过模拟输入端口连接到ATmega8
- 蜂鸣器与按键:分别连接到ATmega8的不同IO端口
软件设计
主要模块介绍
-
初始化模块:
- 初始化LCD1602、DS1302和AT24C02。
- 设置定时器和中断。
-
I2C通信模块:
- 实现I2C通信的启动、停止、读写等基本功能,用于与AT24C02存储芯片通信。
-
脉搏测量与显示模块:
- 通过定时中断测量脉搏频率。
- 实时显示脉搏值和上下限设定值。
- 判断是否超出设定范围并触发报警。
-
数据存储与读取模块:
- 将每次测量的脉搏值存储到AT24C02中。
- 读取存储的历史数据供用户查看。
-
按键处理模块:
- 处理按键输入,实现上下限设置、历史数据查看等功能。
程序原理
主程序流程
- 初始化各模块。
- 进入主循环,不断监测按键输入并处理。
- 定时获取脉搏测量数据并更新显示。
- 判断是否超出设定范围,触发报警。
- 存储测量数据。
关键函数
- x24c02_init:初始化I2C通信和AT24C02存储芯片。
- ds1302_init:初始化DS1302时钟芯片。
- get_time:获取当前时间。
- x24c02_read/write:读写AT24C02芯片中的数据。
- deal_key:处理按键输入。
- display:更新LCD1602显示内容。
程序代码
#include <iom8v.h>
#include <macros.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lcd1602.h"
// 函数声明
void flash_24c02(void);
void x24c02_init(void);
void start(void);
void stop(void);
void writex(unsigned char j);
unsigned char readx(void);
void ack(void);
unsigned char x24c02_read(unsigned char address);
void x24c02_write(unsigned char address, unsigned char info);
void ds1302_init(void);
void get_time(struct RTCTIME *p);
void time_write_1(unsigned char time_tx);
unsigned char time_read_1(void);
unsigned char getKeyBoardValue(void);
void display(void);
void deal_key(unsigned char button);
void main(void);
// 全局变量
unsigned int xinlv_cnt;
unsigned char xinlv, xinlv_h, xinlv_l, index, sum_xinlv, page;
struct RTCTIME rtctime;
// 主程序
void main(void) {
// 初始化代码
LCD_init();
DDRD &= ~(0x08 + 0x03 + 0x10);
DDRD |= 0x80; // BEEP
SREG = 0x80; // 使能全局中断
TIMSK |= (1 << TOIE1); // 使能定时溢出中断
TCCR1A = 0x00; // 配置定时器工作在普通模式
TCCR1B = 0x01; // 无分频
TCNT1H = (65535 - 20000) / 256; // 5ms
TCNT1L = (65535 - 20000) % 256; // 5ms
MCUCR &= ~( (1 << ISC01) | (1 << ISC00) ); // 低电平触发中断
GICR = (1 << INT0); // 使能外部中断0请求
ds1302_init();
LCD_write_str(0, 0, " ");
LCD_write_str(0, 1, " ");
x24c02_init();
delay_nms(10);
xinlv_h = x24c02_read(100);
delay_nms(10);
xinlv_l = x24c02_read(101);
delay_nms(10);
index = x24c02_read(102);
delay_nms(10);
sum_xinlv = x24c02_read(103);
while (1) {
// 按键检测与处理
unsigned char button = getKeyBoardValue();
if (button) {
deal_key(button);
while (getKeyBoardValue());
}
// 定时获取时间与脉搏数据
static unsigned char timecyc = 0;
timecyc = (timecyc + 1) % 10;
if (timecyc == 0) {
get_time(&rtctime);
static unsigned char temp_sec;
if (temp_sec != rtctime.miao) {
temp_sec = rtctime.miao;
display();
if((xinlv < xinlv_l) || (xinlv > xinlv_h)) {
PORTD &= ~0x80;
} else {
PORTD |= 0x80;
}
}
}
delay_nms(5);
}
}
// 定时器中断服务程序
#pragma interrupt_handler Timer1_ovf:9
void Timer1_ovf(void) {
TCNT1H = (65535 - 20000) / 256; // 5ms
TCNT1L = (65535 - 20000) % 256; // 5ms
xinlv_cnt++; // 时间加5ms
}
// 外部中断服务程序
#pragma interrupt_handler int0:2
void int0(void) {
if (xinlv_cnt != 0) {
xinlv = 60000 / (xinlv_cnt * 5); // 计算出心率
x24c02_write(index, xinlv); // 写入心率
index++;
if (index == 100) {
index = 0;
sum_xinlv = 1;
x24c02_write(103, sum_xinlv);
flash_24c02();
}
x24c02_write(102, index);
}
xinlv_cnt = 0;
}
结果与分析
系统成功实现了脉搏测量与显示功能,并且可以通过按键设置报警上下限。当脉搏不在设定范围内时,系统能够正确触发报警。此外,测量数据能实时存储并掉电保持。
总结
本实验通过硬件与软件的结合,实现了一个简易的脉搏测量与显示系统。通过对各模块的合理设计与调试,使系统具备了脉搏实时监测、上下限设置、报警和数据存储等功能,为相关领域的进一步研究和应用提供了良好的基础。
资源代码
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2