2020-07-14

有没有大佬帮我看看程序哪来出错,仿真时按下按键也没见数码管跳出对应数字,,很急急急急急,拜托大佬帮帮忙,感谢🙏。

/*******************************************************************************  
* 文件名称: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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值