标题:
单片机设计求助,现在lcd显示脉搏特别奇怪,数字特别小,特别容易报警?
[打印本页]
作者:
cq995
时间:
2023-5-12 16:57
标题:
单片机设计求助,现在lcd显示脉搏特别奇怪,数字特别小,特别容易报警?
屏幕截图 2023-05-12 165440.jpg
(81.1 KB, 下载次数: 24)
下载附件
2023-5-12 16:54 上传
单片机源程序如下:
#include <reg52.h> //调用单片机头文件
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
uchar menu_1; //设置不同报警参数的变量
uchar flag_200ms ; //200毫秒的变量
unsigned char i=0,rate=0,timecount=0;
unsigned int time[6]={0};
uchar rate_l=2,rate_h=200; //脉搏上下限报警值
sbit rs=P1^0; //寄存器选择信号 H:数据寄存器 L:指令寄存器
sbit rw=P1^1; //寄存器选择信号 H:数据寄存器 L:指令寄存器
sbit e =P1^2; //片选信号 下降沿触发
sbit beep = P3^7; //蜂鸣器IO口定义,仿真
sbit key1 = P3^6; //按键IO口定义,仿真
sbit key2 = P3^5; //按键IO口定义,仿真
sbit key3 = P3^4; //按键IO口定义,仿真
/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/********************************************************************
* 名称 : delay_uint()
* 功能 : 小延时。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay_uint(uint q)
{
while(q--);
}
/********************************************************************
* 名称 : write_com(uchar com)
* 功能 : 1602指令函数
* 输入 : 输入的指令值
* 输出 : 无
***********************************************************************/
void write_com(uchar com)
{
rs=0; //写指令
rw=0; //对1602写操作
P0=com; //P0口对1602写指令
delay_uint(25);
e=1; //e=1使能信号
delay_uint(100); //延时一下等1602完成操作
e=0;
}
/********************************************************************
* 名称 : write_data(uchar dat)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void write_data(uchar dat)
{
rs=1; //写数据
rw=0; //对1602写操作
P0=dat; //P0口对1602写数据
delay_uint(25);
e=1; //e=1使能信号
delay_uint(100); //延时一下等1602完成操作
e=0;
}
/********************************************************************
* 名称 : write_string(uchar hang,uchar add,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
write_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void write_string(uchar hang,uchar add,uchar *p)
{
if(hang==1)
write_com(0x80+add); //写1602第一行的地址
else
write_com(0x80+0x40+add); //写1602第二行的地址
while(1)
{
if(*p == '\0') break; //\0字符串的结尾标志 break结束while循环 结束写字符
write_data(*p); //写数据
p++; //指针地址加1
}
}
/*****************控制光标函数********************/
void write_guanbiao(uchar hang,uchar add,uchar date)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
if(date == 1)
write_com(0x0f); //显示光标并且闪烁
else
write_com(0x0c); //关闭光标
}
/***********************lcd1602上显示3位十进制数************************/
void write_lcd3(uchar hang,uchar add,uint date)
{
if(hang==1)
write_com(0x80+add); //写1602第一行的地址
else
write_com(0x80+0x40+add); //写1602第二行的地址
write_data(0x30+date/100%10); //显示百位数,加0x30转换为ASCII字符
write_data(0x30+date/10%10); //显示十位数
write_data(0x30+date%10); //显示个位数
}
/***********************lcd1602初始化设置************************/
void init_1602()
{
write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口 不检测忙信号
write_com(0x0c); //开显示 不显示光标
write_com(0x06); //当写一个字符是,地址指针加 1
write_string(1,0," 000/min "); //初始化1602显示
write_string(2,0," H:000 L:000 "); //初始化1602显示
write_lcd3(2,4,rate_h);
write_lcd3(2,11,rate_l);
}
/*************定时器0初始化程序***************/
void time_init()
{
EA = 1; //开总中断
TMOD = 0X01; //定时器0工作方式1
ET0 = 1; //开定时器0中断
TR0 = 1; //允许定时器0定时
}
/***********外部中断0初始化程序****************/
void init_int0() //外部中断0初始化程序
{
EX0=1; //允许外部中断0中断
EA=1; //开总中断
IT0 = 1; //外部中断0负跳变中断
}
/********************独立按键程序*****************/
uchar key_can; //按键值
void key() //独立按键程序
{
static uchar key_new; //key_new 这个变量的功能是做按键松手检测的
key_can = 0; //按键值还原成0
if(key1 == 0 || key2 == 0 || key3 == 0) //有按键按下
{
delay_1ms(1); //按键延时消抖动
if(key_new == 1)
{
key_new = 0; //key_new = 0 说明按键已按下
if(key1 == 0) //确认是按键按下
key_can = 1; //得到按键值
if(key2 == 0) //确认是按键按下
key_can = 2; //得到按键值
if(key3 == 0) //确认是按键按下
key_can = 3; //得到按键值
}
}
else
key_new = 1; //key_new = 1 说明按键已经松开了
}
/**********************设置函数************************/
void key_with()
{
if(key_can == 1) //设置键
{
menu_1++;
if(menu_1 > 2)
{
menu_1 = 0; //menu_1 = 0 退出设置了,在正常显示界面下
init_1602(); //初始化液晶显示
}
}
/***************设置*********************/
if(menu_1 != 0)
{
if(menu_1 == 1) //设置脉搏上限报警值
{
if(key_can == 2) //加键
{
rate_h ++; //设置脉搏上限报警值 加1
if(rate_h >= 255)
rate_h = 0;
}
if(key_can == 3) //减键
{
rate_h -- ; //设置脉搏上限报警值 减1
if(rate_h <= rate_l)
rate_h = rate_l + 1; //限制脉搏上限不能低于脉搏下限
}
}
if(menu_1 == 2) //设置脉搏下限报警值
{
if(key_can == 2) //加键
{
rate_l ++; //设置脉搏下限报警值 加1
if(rate_l >= rate_h)
rate_l = rate_h - 1; //限制脉搏下限不能高于脉搏上限
}
if(key_can == 3) //减键
{
if(rate_l == 0)
rate_l = 1;
rate_l -- ; //设置脉搏下限报警值 减1
}
}
write_lcd3(2,4,rate_h); //显示上限报警值
write_lcd3(2,11,rate_l); //显示下限报警值
delay_1ms(10);
}
}
/****************报警函数***************/
void clock_h_l()
{
if(rate != 0)
{
if((rate <= rate_l) || (rate >= rate_h))
{
beep = ~beep; //蜂鸣器报警
}
else
{
beep = 1; //取消报警
}
}else
{
beep = 1; //取消报警
}
}
/****************主函数***************/
void main()
{
init_1602(); //1602初始化
time_init(); //初始化定时器
init_int0(); //外部中断0初始化程序
while(1)
{
key(); //按键函数
key_with(); //按键设置函数
rate=60000/(time[1]+time[2]+time[3]+time[4]+time[5])/5; //计算脉搏次数
write_lcd3(1,5,rate); //显示脉搏
clock_h_l(); //报警函数
delay_1ms(1); //延时1毫秒
}
}
void int0() interrupt 0 //外部中断0,由P3.2端口引入,低电平或下降沿引起
{
if(timecount<8) //当连续两次检测时间间隔小于8*50ms=400ms不处理
{
TR0=1;//开定时器
}
else
{
time[i]=timecount*50+TH0+TL0;//算出间隔时间,timecount是50ms计数,每隔50ms timecount加1
// time[i]=timecount*50+TH0*0.256+TL0/1000;
// time[i]=TH0*256+TL0;
TH0 = 0x3c;
TL0 = 0xb0; // 50ms 12M
timecount=0;//50ms计数清零
i++;
if(i==6)//记录到超过等于6次时间
{
i=1;//计数从1开始
}
}
}
void time0_int() interrupt 1
{
TH0 = 0x3c;
TL0 = 0xb0; // 50ms 12M
timecount++;//每50ms一次计数
if(timecount>25) //当超过25*50ms=1.5s没有检测到信号停止显示
{
i=0;//数据个数清零
timecount=0;//50ms计数清零
TR0=0;//定时器关
TH0 = 0x3c;
TL0 = 0xb0; // 50ms 12M
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1