蓝桥杯------第十二届

目录

题目要求

考察内容

1、数码管,LED,按键(矩阵按键)

2、onewire:温度测量

3、iic:DAC

太懒了不想分析题目了

程序

1、主函数

2、iic

3、onewire

总结


题目要求

在这里插入图片描述

在这里插入图片描述 

 在这里插入图片描述

在这里插入图片描述 

 

考察内容

1、数码管,LED,按键(矩阵按键)

2、onewire:温度测量

3、iic:DAC

太懒了不想分析题目了

        能实现正确的温度读取,DAC写入,LED显示应该就差不多了。其他的数码管和按键没啥难度!至于图像,会求一次函数和会写分段函数就明白了。

程序

1、主函数

#include<stc15f2k60s2.h>

#include"onewire.h"
#include"iic.h"
#define uchar unsigned char
#define uint unsigned int

sbit Buzzer = P0^6;			 //蜂鸣器
sbit Relay = P0^4;			 //继电器

/*************  本地常量声明    **************/
uchar code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46,0x77};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

uchar code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码
uchar smg_table[]={16,16,16,16,16,16,16,16};
uchar ReadData,Trg,Cont;
bit key_flag;

//温度
uint Read_Temp;
float Temp;
uchar set_number=25;//温度参数
float DA_Number;//DA

uchar mode=0;//界面:0温度显示界面,1参数设置界面,2DAC输出界面
uchar set_mode=0;	   //0为模式1,1为模式2
uchar LED;			//LED
//关闭外设
void Initer()		 
{
	P2=0xa0; Buzzer	=0;	Relay=0;P2=0x00;
   	P2=0x80; P0=0xff;P2=0x00;
}

void Set_Led()
{
  	P2=0x80; 
	P0=~LED;
	P2=0x00;
}
void Timer0Init(void)		//1毫秒@12.000MHz
{
	EA=1;ET0=1;
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
void Timer1Init(void)		//1毫秒@12.000MHz
{
	EA=1;ET1=1;
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初值
	TH1 = 0xD1;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
}

void Timer0() interrupt 1
{
	static uint smg_count,key_count,i;
	if(++smg_count>=2)
	{
		smg_count=0;
		P2=0xe0; P0=0xff;P2=0x00;
		P2=0xc0; P0=T_COM[i];P2=0x00;
		P2=0xe0; P0=~t_display[smg_table[i]];P2=0x00;	
		i++;
		if(i>=8)i=0;
	}
	if(++key_count>=10)
	{
	   key_count=0;
	   key_flag=1;
	}
}
void Timer1() interrupt 3
{
	static uint Temp_count;
	if(++Temp_count>=100)
	{
		Temp_count=0;
		Temp=DS18b20_Get();
		Read_Temp=Temp*100;	
	}
}
void ReadKey()
{
	uchar KeyPress;
	P3=0xf0;
	P44=P42=1;
	P37=P44;
	P36=P42;
	KeyPress=P3;

	P3=0x0f;
	P44=P42=0;

	ReadData=(KeyPress|P3)^0xff;
	Trg=ReadData&(ReadData^Cont);
	Cont=ReadData;
}

void dis_key()
{
	if(key_flag)
	{
		key_flag=0;
		ReadKey();
		switch(Trg)
		{
		   case 0x88:		 //s4
			  mode++;
			  if(mode>=3)mode=0;
		   break;
		   case 0x84:		 //s5
			 set_mode++;
			 if(set_mode>=2)set_mode=0;
		   break;
		   case 0x48:		 //s8
			 	if(mode==1)
				{
				   set_number--;
				}
		   break;
		   case 0x44:		  //s9
			 	if(mode==1)
				{
				   set_number++;
				}
		   break;
		}
	}
}
void dis_set_mode()
{
	if(set_mode==0)
	{
		 if(Temp<set_number)
		 {
		 	DA_Number=0;		 //0V
			Set_DAC(0);
		 }
		 else if(Temp>=set_number) 
		 {
		 	 DA_Number=5;		//5V
			 Set_DAC(255);
		 }
	 }
	 else if(set_mode==1)
	 {
		 if(Temp<=20)
		 {
		 	DA_Number=1;
			Set_DAC(51);
		 }
		 else if(20<Temp&&Temp<40)
		 {
		   DA_Number=Temp*0.15-2;
		   Set_DAC(DA_Number*255/5);
		 }
		 else if(Temp>=40)
		 {
		  	DA_Number=4;
			Set_DAC(204);
		 }
	 }
}

int main()
{
	uchar i;
   Initer();//关闭外设
   Timer0Init();//定时器0
   Timer1Init();	//定时器1
   for(i=0;i<3;i++)
   {
   	while((int)DS18b20_Get()==85);		//等返回值不为85时显示while(1)
   }
	while(1)
	{
		dis_set_mode();
		if(set_mode==0)				//模式1
		{
		   LED|=1;				//L1点亮
		}
		else{
		   LED&=~1;				//L1灭
		}
		if(mode==0)			  //温度界面 L2
		{
		  LED|=2;
		}
		else{
		   LED&=~2;	
		}
		if(mode==1)			//参数设置界面 L3
		{
		  LED|=4;
		}
		else{
		   LED&=~4;	
		}
		if(mode==2)		   //DAC界面
		{
		  LED|=8;
		}
		else{
		   LED&=~8;	
		}
		switch(mode)
		{
			case 0:
				smg_table[0]=12;
				smg_table[1]=16;
				smg_table[2]=16;
				smg_table[3]=16;
				smg_table[4]=Read_Temp/1000;
				smg_table[5]=Read_Temp/100%10+32;
				smg_table[6]=Read_Temp/10%10;
				smg_table[7]=Read_Temp%10;
			break;
			case 1:
				smg_table[0]=24;
				smg_table[1]=16;
				smg_table[2]=16;
				smg_table[3]=16;
				smg_table[4]=16;
				smg_table[5]=16;
				smg_table[6]=set_number/10;
				smg_table[7]=set_number%10;
			break;
			case 2:
				smg_table[0]=43;
				smg_table[1]=16;
				smg_table[2]=16;
				smg_table[3]=16;
				smg_table[4]=16;
				smg_table[5]=(uint)(DA_Number*100)/100+32;
				smg_table[6]=(uint)(DA_Number*100)/10%10;
				smg_table[7]=(uint)(DA_Number*100)%10;
			break;
		}
		Set_Led();
		dis_key();
	}
}

2、iic


#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}


//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}


//DAC
void Set_DAC(unsigned char dat)
{

	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendByte(unsigned char byt); 

//DAC
void Set_DAC(unsigned char dat);
#endif

3、onewire

#include<stc15f2k60s2.h>

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t=t*10;
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

//返回温度值
float DS18b20_Get()
{
	int high,low;
	float temp;
	init_ds18b20();					  //初始化
	Write_DS18B20(0xcc);			   //跳过ROM
	Write_DS18B20(0x44);			  //转换为温度

	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);			   //读暂存器

	low=Read_DS18B20();				   //低字节
	high=Read_DS18B20();			   //高字节

	temp=((high<<8)|low)*0.0625;
	return temp;		//返回温度值
}
#ifndef __ONEWIRE_H
#define __ONEWIRE_H

void Delay_OneWire(unsigned int t);  //STC89C52RC
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
float DS18b20_Get();
#endif

总结

         当时写题目的时候if条件语句用得太多了导致那个else 和那个if匹配都弄错了,导致程序没成功。但是后面想了下还是解决了,加上改bug成功的两个小时解决了,但是好像有两个警告,但不影响程序跑起来实现功能。不想去找那两个警告了。我得出个经验以后可以多使用switch语句,真好用!!!

        后期有时间再把代码改改,越简洁越好!!!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值