十一届蓝桥51单片机自写练习

板子IAP15f2k60s2

第一次写才发现五个小时根本写不完,写了两三天,太菜了呜呜
在这里插入图片描述在这里插入图片描述在这里插入图片描述

main.c

#include "reg52.h"
#include "intrins.h"
#include "IIC.h"
#define u8 unsigned char 
#define u16 unsigned int
sfr P4   = 0xC0;	//P4
sbit P42 = P4^2;
sbit P44 = P4^4;

sfr AUXR=0x8e;

//deal !!!

u8  duan[]={   0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,
0x3e,0x73,0x54,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

u16 temp3=0,temp4=500;
u8  disbuff[8];
//              P    U    n
u8 falg_bit[]={0x73,0x3e,0x54};
u8 falg=1,key_value=0,Vpp=0,value_jishu=0;
u8 adc_value=0;
u16 value=0,s=0,i=0;
void display(u8 *duan_zhu,u8 wei);
void data_dis();
void cls_buzz()
{
	P2&=0xa0;
	P0=0x00;
	P2&=0x1f;
	
	P2&=0x80;
	P0=0xff;
	P2&=0x1f;
}


void Delay(u8 i)
	{
    do{_nop_();}
    while(i--);        
}

//按键检测函数
void Keys_down()
{
	unsigned char temp1,temp2;
	P3=0xf0;P42=1;P44=1;//列检测
	temp1=(P3&0xf0);
	Delay(100);
	if(temp1!=0xf0||P42==0||P44==0)
	{
		switch (temp1)
		{
			case 0xe0: key_value = 16;break; 
			case 0xd0: key_value = 12;break;
			default :key_value = 0;break;
		}
		
		P3=0x0f;P42=0;P44=0;
		temp1=(P3&0x0f);
		Delay(100);
		if(temp1!=0x0f)
		{
			switch(temp1) 
			{
				case 0x07: key_value+=0;break;
				case 0x0b: key_value+=1;break;
				case 0x0d: key_value+=2;break;
				case 0x0e: key_value+=3;break;
			}
			
			switch (key_value)
			{
				case 12: falg++;if(falg==4) falg=1;break;//切换界面
				case 13: if(falg==3) value_jishu=0;break; //计数界面 按下清零
				case 16: if(falg==2) Vpp++;break;//参考值加一
				case 17: if(falg==2) Vpp--;break;//参考值减一
			}
			data_dis();
			
			if(key_value!=12&&key_value!=13&&key_value!=16&&key_value!=17)//判断无效按键
			{
				i++;
			}
			else{i=0;}
			
			while(P3!=0x0f)  //根据最近一次赋值判断
			{
				//value=key_value;
				Delay(300);
				data_dis();
				
				if(falg==1||falg==2)
				display(duan,2);//即使一直按着也会显示
				
				else display(duan,0);
			}
				
		}
		if(temp2==2&&falg!=2)
			EEPROM_Write(0x00,Vpp);
		
		temp2=falg;

	}
}

bit reg_0=1;
bit reg_1=0;
bit flage=0;
bit flage1=0;
void data_dis()
{
	u16 adc_value;
	
		adc_value = read_adc(0x03);
		adc_value *=100*5/255.00f;
		
		P0=0xff;
		P2=P2&0x1f|0x80;
		P0=0xff;
	
		if(value_jishu%2)//指示灯L2:当前计数值为奇数时,L2点亮,否则熄灭。
		{
			P0&=0xfd;
		}
		else{P0|=0x02;}
		
		if(adc_value<Vpp*50)//指示灯L1:当V<V的状态持续时间超过5秒时,L1点亮,否则熄灭。
		{
			s++;
			if(s>=10224)
			P0&=0xfe;
			else{P0|=0x01;}
		}
		else{s=0;}
		
		if(i>=3)//指示灯L3:连续3次以上(含3次)的无效按键操作触发L3点亮,直到
		{
			P0&=0xfb;
		}
		else{P0|=0x04;}
		
		P2&=0x1f;

		
	
		//按键 功能要求	
		if(falg==1) //数据界面
		{
			value=adc_value;
		}
		
		if(falg==2) //参数界面
		{
			value=Vpp*50;
		}
		
		if(falg==3) //计数界面
		{

			value=value_jishu;
		}
		
		
		
		
			//下降沿检测
			if(!reg_1) //首先检测这个数大于参考值
			{
			if(adc_value>Vpp*50)//如果大于就不检测了
				reg_1=1;
			
			}
			
			if(reg_1)//如果大于就开始检测小于参考值
			{
			if(adc_value<Vpp*50)//如果小于就不检测了
				reg_0=0;
			}
			
			if(reg_1==1&&reg_0==0)
			{
				value_jishu++;
				reg_0=1;reg_1=0; //恢复reg_1 和reg_0的值,先检测大于,如果大于再小于
			}
		
			
			
			
		//参数模式 功能要求
		if(Vpp==255) //小于0就变255了
			{
				Vpp=10;
			}
			if(Vpp>=11) //大于就归0
			{
				Vpp=0;
			}
}

//数码管显示函数
void display(u8 *duan_zhu,u8 wei)
{
	
	static index=0;
	u8 j;
	
	disbuff[0]=10+falg;
	disbuff[1]=10;
	disbuff[2]=10;
	disbuff[3]=10;
	disbuff[4]=10;
	disbuff[5]=value/100;
	disbuff[6]=value/10%10;
	disbuff[7]=value%10;
	
	if(wei)
	disbuff[7-wei]+=14;
	
	for(j=5;j<7;j++)//从高到低检测是否为0 直到不为0
	{
		if(disbuff[j]==0)
			disbuff[j]=10;
		else break;
	}
		
	
	
	
	P2=P2&0x1f|0xe0; //消除干扰
	P0=0xff;         //
	P2&=0x1f;        //
	
	P2=P2&0x1f|0xc0;
	P0=1<<index;
	P2&=0x1f;
	
	P2=P2&0x1f|0xe0;
	P0=~duan_zhu [disbuff[index]];
	P2&=0x1f;
	
	index++;
	index&=0x07;
}

void Timer_Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0x1f;		//设置定时器模式
	
	TL1 = 0x17;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	
	TF1 = 0;		//清除TF0标志
	TR1 = 1;		//定时器0开始计时
	
	PT1=1;
	

	ET1=1;
	
	EA=1;
}



void timer1() interrupt 3 //中断主要用于按键检测和显示 适用于任何程序
{
	TF1=0;
	
	TL1 = 0x17;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	
	Keys_down();
	if(falg==1||falg==2)
	display(duan,2);//即使一直按着也会显示
	else display(duan,0);
	s++;
}

void main()
{
	cls_buzz();
	
	Timer_Init();
	Vpp=EEPROM_Read(0x00);
	
	while(1)
	{
		
		data_dis();

	}
	
	
}

IIC.C

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#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);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    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;  
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}

void EEPROM_Write(unsigned char add,unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0xa0);//芯片地址
	IIC_WaitAck();
	IIC_SendByte(add);//选择页
	IIC_WaitAck();
	IIC_SendByte(dat);//数据
	IIC_WaitAck();
	IIC_Stop();
}



unsigned char EEPROM_Read(unsigned char add)
{
	unsigned char temp;
	
	EA=0;
	
	IIC_Start();
	IIC_SendByte(0xa0);//芯片地址 
	IIC_WaitAck();
	IIC_SendByte(add);//选择页
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);//芯片地址 读
	IIC_WaitAck();
	temp=IIC_RecByte();//选择页
	IIC_WaitAck();
	IIC_Stop();
	
	EA=1;
	
	return temp;
}


void write_adc(unsigned char add)  //AIN3 RB2
{
	IIC_Start();
	IIC_SendByte(0x90);//写
	IIC_WaitAck();
	IIC_SendByte(add);//模式  channel 
	IIC_WaitAck();
	IIC_Stop();
}

unsigned char read_adc(unsigned char add)
{
	unsigned char temp;
	
	EA=0;
	IIC_Start();
	IIC_SendByte(0x90);//写
	IIC_WaitAck();
	IIC_SendByte(add);//模式选择channel
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);//读
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	
	EA=1;
	return temp;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值