有没有大佬帮我看看程序哪来出错,仿真时按下按键也没见数码管跳出对应数字,,很急急急急急,拜托大佬帮帮忙,感谢🙏。
/*******************************************************************************
* 文件名称:DS18B20温度传感器实验
* 实验目的:2020年实训。
矩阵按键输入温度的上下限。在设置温度上下限时,数码管显示温度设置情况。
平时8个共阴数码管显示温度值,并且有温度区间提示。
有led显示灯,会提示温度区间。
有继电器,当温度超限时,会动作。
具体参看第六届蓝桥杯任务书
默认上限是30度,下限是20度。
外接晶振11.0592Mhz
串口同学们可以自己增加
*******************************************************************************/
#include <REGX51.H>
#include<INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define set 10
#define clear 11
//#include "reg52.h" //定义51单片机特殊功能寄存器
#include "onewire.h" //单总线函数库
unsigned char temperature;
unsigned char state = 0; //一共7个状态,从0-6. 开始的状态是0——没有设置温度参数
unsigned char dspbuf1[8] = {11,1,11,10,10,10,2,5};//温度显示缓冲区:-区间-熄灭熄灭熄灭熄灭温度温度,
unsigned char dspbuf2[8] = {11,3,0,10,10,11,2,0};//参数设置显示缓冲区:-上限上限熄灭熄灭-下限下限
unsigned char dspcom = 0;
unsigned int intr;
unsigned int cnt; //led执行机构的时间计数
bit temper_flag = 0;//温度读取标志
bit display_flag = 0; //界面显示标志
sbit led = P3^3;
uchar key_value;
//数码管显示译码,共阴连接。 0 ·1 2 3 4 5 6 7 8 9 熄灭 -
code unsigned char tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};
unsigned char Tmax = 30;
unsigned char Tmin = 20;
void display(void);
void dspbuf1_change();
void dspbuf2_change();
void TempSet(unsigned char state);
uchar key_scan();
void Delay_2us(uint i);
//主函数
void main(void)
{
TMOD |= 0x01; //配置定时器工作模式
TH0 = (65536-2000)/256; //2ms,按照12Mhz计算 2ms是数码管动态显示的最小时间,每个管子。
TL0 = (65536-2000)%256;
EA = 1;
ET0 = 1; //打开定时器中断
TR0 = 1; //启动定时器
while(1)
{
//每隔2s读一次温度
if(temper_flag)
{
temper_flag = 0;
temperature = rd_temperature(); //读温度
//显示数据更新
dspbuf1_change();
}
//按键扫描,扫描是否有用户设置温度的上下限
key_value = key_scan();
if(key_value != -1)
{
TempSet(state);//温度设置状态机函数
}
if (state == 0)
display_flag = 0;
else
display_flag = 1;
}
}
//串口数据发送函数
void send(unsigned char str)
{
SBUF=str;
while(!TI);
TI=0; }
void delay(unsigned int x)
{
while(x--);
}
//显示函数
void display(void)
{
P0 = 0x00; //关显示
P2 = _crol_(0xfe,dspcom); //位选
if (display_flag == 0) //段选
P0 = tab[dspbuf1[dspcom]];
else
P0 = tab[dspbuf2[dspcom]] ;
if(++dspcom == 8){
dspcom = 0;
}
}
//温度显示数据更新
void dspbuf1_change()
{
dspbuf1[6] = temperature/10;
dspbuf1[7] = temperature%10;
//区间
if (temperature > Tmax)
dspbuf1[1] = 2;
else if (temperature < Tmin )
dspbuf1[1] = 0;
else
dspbuf1[1] = 1;
}
//温度设置的过程,状态机方法
void TempSet(unsigned char x)
{
unsigned char TempBoundary[4]; //上下限的按键值缓存
switch (x)
{
case 0:
if (key_value == set) state = 1;
break;
case 1 :
dspbuf2[1] = dspbuf2[2] = dspbuf2[6] = dspbuf2[7] = 10; //熄灭
if (key_value == set) { state = 0; break; } //设置
else if (key_value == clear) break; //清除
else { state = 2; TempBoundary[0] = key_value;
dspbuf2[1] = TempBoundary[0];} //数码管显示数字} //数字,上限的十位数
break;
case 2:
if (key_value == set) { state = 0; break; } //设置
else if (key_value == clear) //清除
{dspbuf2[1] = 10; //显示‘熄灭’的显示编码
state = 1;
break;}
else { state = 3; TempBoundary[1] = key_value;
dspbuf2[2] = TempBoundary[1]; } //上限的个位数
break;
case 3:
if (key_value == set) { state = 0; break; }
else if (key_value == clear)
{ dspbuf2[2] = 10; //显示‘熄灭’的显示编码
state = 2;
break; }
else { state = 4; TempBoundary[2] = key_value;
dspbuf2[6] = TempBoundary[2]; } //下限的十位数}
break;
case 4:
if (key_value == set) { state = 0; break; }
else if (key_value == clear)
{ dspbuf2[6] = 10; //显示‘熄灭’的显示编码
state = 3;
break;}
else { state = 5; TempBoundary[3] = key_value;
dspbuf2[7] = TempBoundary[3]; } //下限的个位数
break;
case 5:
if (key_value == set)
{
Tmax = TempBoundary[0]*10+ TempBoundary[1];
Tmin = TempBoundary[2]*10+ TempBoundary[3];
state = 0;
break; } //完成温度设置
else if (key_value == clear)
{ dspbuf2[7] = 10; //显示‘熄灭’的显示编码
state = 4;
break;}
else { break; }
break;
}
}
//定时器中断服务函数
void isr_timer_0(void) interrupt 1 //默认中断优先级 1
{
TH0 = (65536-2000)/256;
TL0 = (65536-2000)%256; //定时器重载
display(); //数码管动态扫描
if(++intr == 1000) //2s执行一次
{
intr = 0;
temper_flag = 1; //200ms温度读取标志位置1
}
cnt++;
if(cnt == (400 >> dspbuf1[1]))
{
cnt = 0;
led = ~led;
}
}
//按键扫描 ,逐列扫描法
uchar key_scan()
{
bit flag=0;
uchar temp=0,num=0;
/************************扫描第一行**********************************************/
P1=0xfe; //1111 1110
Delay_2us(10);
temp=P1&0xf0; //f0:1111 0000, 跟1相与,还是它自身,跟0相与,一定是0. 读出了列的值
if(temp!=0xf0) //有按键按下,
{
Delay_2us(1250); //延时祛抖
if(temp!=0xf0) //依然有按键按下
{
flag=1;
switch(temp)
{
case 0xe0: num=0;break; //第0按键按下 1110 0000
case 0xd0: num=1;break; //第1按键按下 1101 0000
case 0xb0: num=2;break; //第2按键按下
// case 0x70: num=3;break; //第3按键按下
}
while(temp!=0xf0) //等待按键弹起
{
temp=P1;
temp=temp&0xf0; //读出的列线不为0, 表示没有按键按下。
}
}
}
/*****************************扫描第二行**************************************************/
P1=0xfd; //1111 1101
Delay_2us(10);
temp=P1&0xf0;
if(temp!=0xf0)
{
Delay_2us(1250);
if(temp!=0xf0)
{
flag=1;
switch(temp)
{
case 0xe0: num=3;break; //第4按键按下 1110 0000
case 0xd0: num=4;break; //第5按键按下
case 0xb0: num=5;break; //第6按键按下
//case 0x70: num=7;break; //第7按键按下
}
while(temp!=0xf0) //等待按键弹起
{
temp=P1;
temp=temp&0xf0;
}
}
}
/*****************************扫描第三行**************************************************/
P1=0xfb; //1111 1011
Delay_2us(10);
temp=P1&0xf0;
if(temp!=0xf0)
{
Delay_2us(1250);
if(temp!=0xf0)
{
flag=1;
switch(temp)
{
case 0xe0: num=6;break; //第8按键按下
case 0xd0: num=7;break; //第9按键按下
case 0xb0: num=8;break; //第10按键按下
// case 0x70: num=11;break; //第11按键按下
}
while(temp!=0xf0) //等待按键弹起
{
temp=P1;
temp=temp&0xf0;
}
}
}
/*****************************扫描第四行**************************************************/
P1=0xf7; //1111 1110
Delay_2us(10);
temp=P1&0xf0;
if(temp!=0xf0)
{
Delay_2us(1250);
{
if(temp!=0xf0)
flag=1;
switch(temp)
{
case 0xe0: num=9;break; //第12按键按下
case 0xd0: num=10;break; //第13按键按下
case 0xb0: num=11;break; //第14按键按下
// case 0x70: num=15;break; //第15按键按下
}
while(temp!=0xf0) //等待按键弹起
{
temp=P1;
temp=temp&0xf0;
}
}
}
if(flag==0)
{
return -1;
}
else
{
return num;
}
}
void Delay_2us(uint i)
{
while(--i);
}
```
## 标题![在这里插入图片描述](https://img-blog.csdnimg.cn/20200714181304219.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ5MjEwNzg3,size_16,color_FFFFFF,t_70)