蓝桥杯单片机第九届省赛,“彩灯控制器“

 

 

 

 

 

 

目录

Main.c

IIC.h


控制亮度的部分暂时没有写上,利用定时器控制PWM即可完成。

Main.c

#include"stc15f2k60s2.h"
#include"intrins.h"
#include"IIC.h"

unsigned char code Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//0,1,2,3,4,5,6,7,8,9,全灭,'-'
unsigned char LED_Mode3_4[]={0x7E,0xBD,0xDB,0xE7};//0111 1110,1011 1101,1101 1011,1110 0111
unsigned char Key_Value,Flag=0;
unsigned char Mode,Mode1=1,Mode2=0;//Mode1为运转模式编号,Mode2为切换运行模式和流转间隔
unsigned int Time=4,Time1;
unsigned char Count=0,Count1=0,Set_Count=0;
unsigned char i=0;
char Flag1=0;Flag2=3,Flag3=0,Flag4=0;
unsigned char AD;
void Delay5ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}

void Delay1ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}

void Timer0_Init()//定时器初始化
{
	TH0=0XD1;
	TL0=0x20;
	TMOD=0X01;
	EA=1;
	ET0=1;
	TR0=1;
}
void All_Init()//关闭LED,蜂鸣器
{
	P2=0X80;P0=0XFF;P2=0XA0;P0=0X00;
}

void Key_Board()//按键判断函数
{
	unsigned char Temp;
	P44=0;P42=1;P3=0X7F;
	Temp=P3;
	Temp=Temp&0x0F;
	if(Temp!=0x0F)
	{
		Delay5ms();
		Temp=P3;
		Temp=Temp&0x0F;
		if(Temp!=0x0F)
		{
			Temp=P3;
			switch(Temp)
			{
				case 0x7E:Key_Value=7;break;
				case 0x7D:Key_Value=6;break;
				case 0x7B:Key_Value=5;break;
				case 0x77:Key_Value=4;break;
			}
			while(Temp!=0x0F)
			{
				Temp=P3;
				Temp=Temp&0x0f;
			}
			Flag=1;
		}
	}	
}

void Key_Dig()
{
	if(Flag==1)
	{
		Flag=0;
		
		
		if(Key_Value==4)
		{
			if(Mode2==1)//当处在模式编号设置的时候,按下四
			{
				Mode1--;//当处在模式编号设置的时候,按下四,编号减一
				if(Mode1==0){Mode1=4;}
				EEPROM_Write(0x01,Mode1);//每按下一次,将运转模式编号保存到EEPROM地址1中.
			}
			
			if(Mode2==2)//当处在流转间隔设置的时候,按下四
			{
				Time-=1;//时间加减100,此处设放小100,因为EEPROM最大保存255,处理数据时乘100恢复
				if(Time==3){Time=12;}
				EEPROM_Write(0x02,Time);//每按下一次,将流转间隔保存到EEPROM地址2中.
			}
			if(Mode2==0)
			{
				Flag3++;
				if(Flag3==2){Flag3=0;}//如果不在设置状态按下0,进入亮度等级状态
				if(Flag3==0){P2=0x80;P0=0xff;}//设置完毕关闭LED。
			}
		}
		
		
		if(Key_Value==5)//同按键4
		{
			if(Mode2==1)
			{
				Mode1++;
				if(Mode1==5){Mode1=1;}
				EEPROM_Write(0x01,Mode1);				
			}
			
			if(Mode2==2)
			{
				Time+=1;
				if(Time==13){Time=4;}
				EEPROM_Write(0x02,Time);
			}
		}
		
		
		if(Key_Value==6)//设置模式切换.
		{
			Mode2++;
			if(Mode2==3){Mode2=0;}
			if(Mode2==0){Set_Count=100;}//用于闪烁LED。模拟选择哪个模式
		}
		if(Key_Value==7)
		{
			Flag4++;if(Flag4==2){Flag4=0;}//启动停止LED
		}
	}
}


void SMG_LIGHT()
{
	unsigned int yi=10,er,san ,si,dengji;
if(Flag3==0)//处在正常模式下,即非电压等级模式下时候,正常显示
{
		if((81<Set_Count&&Set_Count<162)|	Mode2==0)//当Mode2==0时,即非设置模式下时,数码管正常显示(此时已初始化Set_Count为100)
		{
	Time1=Time*100;
	yi=Time1/1000;er=Time1/100%10;san=Time1/10%10;si=Time1%10;
	if(yi==0){yi=10;}
	P2=0XC0;P0=0x01;P2=0XE0;P0=Tab[11];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<1;P2=0XE0;P0=Tab[Mode1];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<2;P2=0XE0;P0=Tab[11];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<3;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<4;P2=0xE0;P0=Tab[yi];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<5;P2=0xE0;P0=Tab[er];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<6;P2=0xE0;P0=Tab[san];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<7;P2=0xE0;P0=Tab[si];Delay1ms();P0=0xff;
		}
	if(Mode2==1)//设置模式下,开始闪烁,可参考定时器内参数设置.
	{
		if(0<Set_Count&&Set_Count<82)
{
	Time1=Time*100;
	yi=Time1/1000;er=Time1/100%10;san=Time1/10%10;si=Time1%10;
	if(yi==0){yi=10;}
	P2=0XC0;P0=0x01;P2=0XE0;P0=Tab[11];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<1;P2=0XE0;P0=Tab[10];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<2;P2=0XE0;P0=Tab[11];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<3;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<4;P2=0xE0;P0=Tab[yi];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<5;P2=0xE0;P0=Tab[er];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<6;P2=0xE0;P0=Tab[san];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<7;P2=0xE0;P0=Tab[si];Delay1ms();P0=0xff;
}
	}
	if(Mode2==2)//设置模式下,开始闪烁,可参考定时器内参数设置.
	{
		if(0<Set_Count&&Set_Count<82)
{
	Time1=Time*100;
	yi=Time1/1000;er=Time1/100%10;san=Time1/10%10;si=Time1%10;
	if(yi==0){yi=10;}
	P2=0XC0;P0=0x01;P2=0XE0;P0=Tab[11];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<1;P2=0XE0;P0=Tab[Mode1];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<2;P2=0XE0;P0=Tab[11];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<3;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<4;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<5;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<6;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
	P2=0XC0;P0=0x01<<7;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
}
	}
}
	if(Flag3==1&&Mode2==0)//当处在非设置模式下按下S4时,查看电压等级
	{
		AD=AD_Read(0x03);
		P2=0XC0;P0=0x01<<0;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
		P2=0XC0;P0=0x01<<1;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
		P2=0XC0;P0=0x01<<2;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
		P2=0XC0;P0=0x01<<3;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
		P2=0XC0;P0=0x01<<4;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
		P2=0XC0;P0=0x01<<5;P2=0xE0;P0=Tab[10];Delay1ms();P0=0xff;
		P2=0XC0;P0=0x01<<6;P2=0XE0;P0=Tab[11];Delay1ms();P0=0xff;
		P2=0XC0;P0=0x01<<7;P2=0xE0;P0=Tab[dengji];Delay1ms();P0=0xff;
		if(0<AD&&AD<64){dengji=1;}
		if(63<AD&&AD<128){dengji=2;}
		if(127<AD&&AD<193){dengji=3;}
		if(192<AD&&AD<256){dengji=4;}
	}
}
void LED_LIGHT()
{
	if(Flag4==0)//S7用于控制停止和流动
	{
		if(Count==Count1)
	{
		Count=0;
		if(Flag3==0)
		{
		if(Mode1==1)
			{
				P2=0x80;
				P0=~(0x01<<i);
				i++;
				if(i==8){i=0;}
			}
		if(Mode1==2)
			{
				P2=0x80;
				P0=~(0x80>>i);
				i++;
				if(i==8){i=0;}
			}
		if(Mode1==3)
			{
			P2=0x80;P0=LED_Mode3_4[Flag1];
			Flag1++;if(Flag1==4){Flag1=0;}
			};
		if(Mode1==4)
			{
			P2=0x80;P0=LED_Mode3_4[Flag2];
			Flag2--;if(Flag2==-1){Flag2=3;}
			}
}
	}
	}
}

void main()
{
	All_Init();
	Timer0_Init();
	Mode1=EEPROM_Read(1);//启动读取上次保存的设置.
	Time=EEPROM_Read(2);
	while(1)
	{
		Key_Board();
		SMG_LIGHT();
		Key_Dig();
		LED_LIGHT();
	}
}

void Timer0() interrupt 1
{
	TH0=0XD1;
	TL0=0X20;
	Count++;//计时流动间隔
	Count1=Time*10;//计时流动间隔
	if((Mode2==2)|(Mode2==1))//当处在选择模式的时候,开始计时.
	{
			Set_Count++;
		if(Set_Count==163){Set_Count=1;}
	}
}

IIC.h

#include"stc15f2k60s2.h"
#include"intrins.h"
sbit SDA=P2^1;
sbit SCL=P2^0;

void Delay6us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 15;
	while (--i);
}



void IIC_Start()
{
	SDA=1;
	SCL=1;
	Delay6us();
	SDA=0;
	Delay6us();
	SCL=0;
}

void IIC_Stop()
{
	SDA=0;
	SCL=1;
	Delay6us();
	SDA=1;
}

//void IIC_Ack()
//{
//	SDA=0;
//	Delay6us();
//	SCL=1;
//	Delay6us();
//	SCL=0;
//	Delay6us();
//	SDA=1;
//}

bit IIC_WaitAck()
{
	SDA=1;
	Delay6us();
	SCL=1;
	Delay6us();
	if(SDA)
	{
		SCL=0;
		IIC_Stop();
		return 0;
	}
	else
	{
		SCL=0;
		return 1;
	}
}

void IIC_Write_Byte(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		if(dat&0x80)
		{SDA=1;}
		else
		{SDA=0;}
		Delay6us();
		SCL=1;
		dat=dat<<1;
		Delay6us();
		SCL=0;
	}
}

unsigned char IIC_Read_Byte()
{
	unsigned char i;
	unsigned char dat;
	for(i=0;i<8;i++)
	{
		SCL=1;
		Delay6us();
		dat<<=1;
		if(SDA){dat|=0x01;}
		SCL=0;
		Delay6us();
	}
	return dat;
}

void EEPROM_Write(unsigned char add,unsigned char date)
{
	IIC_Start();
	IIC_Write_Byte(0xa0);
	IIC_WaitAck();
	IIC_Write_Byte(add);
	IIC_WaitAck();
	IIC_Write_Byte(date);
	IIC_WaitAck();
	IIC_Stop();
}

unsigned char EEPROM_Read(unsigned char add)
{
	unsigned char temp;
	IIC_Start();
	IIC_Write_Byte(0xa0);
	IIC_WaitAck();
	IIC_Write_Byte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_Write_Byte(0xa1);
	IIC_WaitAck();
	temp=IIC_Read_Byte();
	IIC_Stop();
	
	return temp;
}

unsigned char AD_Read(unsigned char add)
{
	unsigned char temp;
	IIC_Start();
	IIC_Write_Byte(0x90);
	IIC_WaitAck();
	IIC_Write_Byte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_Write_Byte(0x91);
	IIC_WaitAck();
	temp=IIC_Read_Byte();
	IIC_Stop();
	
	return temp;
}

有疑问与不足欢迎交流与指出

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值