第九届蓝桥杯 模拟彩虹灯系统

   日期:2021-03-28     浏览:97    评论:0    
核心提示:【冉冰的成长日记003】课设耽误的,可不怪我咕!!先说程序的问题,我感觉不到那个亮度等级变化的区别,好似有又好似没有0.0。。。。。第二,按键的刷新和LED模块有冲突,需要长按按键才好使。。。其他没啥了,,,就这样吧看看代码吧,据说分块写也并不能使变量增加,我就还是写到一个main.c里了,不要跟我学,hhhh#include<STC15F2K60S2.h>#include<iic.h>#include "intrins.h"sbit S7=P3^0;sbit

【冉冰的成长日记003】
课设耽误的,可不怪我咕!!

先说程序的问题,我感觉不到那个亮度等级变化的区别,好似有又好似没有0.0。。。。。
第二,按键的刷新和LED模块有冲突,需要长按按键才好使。。。

其他没啥了,,,就这样吧

看看代码吧,据说分块写也并不能使变量增加,我就还是写到一个main.c里了,不要跟我学,hhhh

#include<STC15F2K60S2.h>
#include<iic.h>
#include "intrins.h"

sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;

unsigned char code LED[]={ 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF ,0xFF ,0xC6};//数码管
unsigned char LEDbuff[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; //数码管缓冲区

unsigned char code LED_M1[]={ 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};
unsigned char code LED_M2[]={ 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE};
unsigned char code LED_M3[]={ 0x7E, 0xBD, 0xDB, 0xE7};
unsigned char code LED_M4[]={ 0xE7, 0xDB, 0xBD, 0x7E};

unsigned int cnt=0,num=0,clock=0;//中断计时
unsigned char AD=0,PWM_flag=0;//AD获取模拟量,PWM_flag用于亮度显示 
unsigned int EEPROM,EEPROM_flag=6;//EEPROM用于设置流转时间间隔
bit S7_start=0,S7_LED=0;//S7_LED停止和启动led ,S7_start用于数码管启动
unsigned char S6_M=1,S6_flag=0; // S6_M模式切换模式,S6_flag用于切换运行和间隔两个单元
bit check_S7=0,check_S6=0,check_S5=0,check_S4=0,Fl=0;//check用来按键消抖,Fl用来选中是以0.8s闪烁

void Timer0Init();	//定时器0,1ms
void Initial();		//模块初始化
void KEY();			//按键模块,包括S7.S6.S5.S4
void Display_3();		//数码管模块
void delay(unsigned int x);	  //延时函数
void Get();	   //每次上电后读取EEPROM内的数据,判断是否在4-12之间,如果在就不需要改变,如果不在默认重装初值为4,,
//我觉得这个思想好厉害,20级的大佬讲给我听的(p.s.:其实是大四的学长讲给他听的)
void LED_1();//彩虹灯的四种模式

void main()
{ 
	Timer0Init();
	Initial();	 //初始化函数
	AD_Init();	 //AD初始化
	Get();
	while(1)
	{ 
		delay(5);
		EEPROM_Write(0x01,EEPROM_flag);				 //将每次变化后的值再写入EEPROM内
		if(clock>=500)
		{ 
			AD=AD_Get();						   //AD值读取
			clock=0;
		}
		KEY();
		Display_3();
		LED_1();					 
	}
}

void delay(unsigned int x)			 //延时函数,ms单位
{ 
	int X=0,Y=0;
	for(X=0;X<x;X++)
	{ 
		for(Y=846;Y>0;Y--);
	}
		
}

void Get()
{ 
	EEPROM_flag = EEPROM_Get(0x01);
	if(EEPROM_flag<=4||EEPROM_flag>=12)	EEPROM_flag=4;
}

void Initial()		//初始化函数
{ 
	P2 = (P2&0x1F)|0x80;
	P0 = 0xFF;		//初始化LED

	P2 = (P2&0x1F)|0xA0;
	P0 = 0x00;		//初始化继电器和蜂鸣器

	P2 = (P2&0x1F)|0xC0;
	P0 = 0xFF;
	P2 = (P2&0x1F)|0xE0;
	P0 = 0xFF;      //初始化数码管
}

void Timer0Init(void)		//1毫秒@11.0592MHz
{ 
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA = 1;
	ET0 = 1;
}

void Display_1()		 //把数码管拆成前四位和后四位,方便管理
{ 
	LEDbuff[7] = LED[10];
	LEDbuff[6] = LED[S6_M];
	LEDbuff[5] = LED[10];
	LEDbuff[4] = LED[11];
}

void Display_2()
{ 
 	if(EEPROM/1000==0)	LEDbuff[3] = LED[11];
	else	LEDbuff[3] = LED[EEPROM/1000];
	LEDbuff[2] = LED[EEPROM/100%10];
	LEDbuff[1] = LED[EEPROM/10%10];
	LEDbuff[0] = LED[EEPROM%10];		
}

void LED_1()		   //写成for语句和按键冲突,只好改变成switch语句了,即便如此,按键也需要长按才能百分百起作用
{ 
	static unsigned char j=0;
	if(S6_M==1&&S7_LED==1)
	{ 
		switch(j)
		{ 
			case 0:P2 = 0x80;P0 = LED_M1[0];j++;delay(EEPROM);break;
			case 1:P2 = 0x80;P0 = LED_M1[1];j++;delay(EEPROM);break;
			case 2:P2 = 0x80;P0 = LED_M1[2];j++;delay(EEPROM);break;
			case 3:P2 = 0x80;P0 = LED_M1[3];j++;delay(EEPROM);break;
			case 4:P2 = 0x80;P0 = LED_M1[4];j++;delay(EEPROM);break;
			case 5:P2 = 0x80;P0 = LED_M1[5];j++;delay(EEPROM);break;
			case 6:P2 = 0x80;P0 = LED_M1[6];j++;delay(EEPROM);break;
			case 7:P2 = 0x80;P0 = LED_M1[7];j=0;delay(EEPROM);break;
			default : break;
		}
	}

	if(S6_M==2&&S7_LED==1)
	{ 
		switch(j)
		{ 
			case 0:P2 = 0x80;P0 = LED_M2[0];j++;delay(EEPROM);break;
			case 1:P2 = 0x80;P0 = LED_M2[1];j++;delay(EEPROM);break;
			case 2:P2 = 0x80;P0 = LED_M2[2];j++;delay(EEPROM);break;
			case 3:P2 = 0x80;P0 = LED_M2[3];j++;delay(EEPROM);break;
			case 4:P2 = 0x80;P0 = LED_M2[4];j++;delay(EEPROM);break;
			case 5:P2 = 0x80;P0 = LED_M2[5];j++;delay(EEPROM);break;
			case 6:P2 = 0x80;P0 = LED_M2[6];j++;delay(EEPROM);break;
			case 7:P2 = 0x80;P0 = LED_M2[7];j=0;delay(EEPROM);break;
			default : break;
		}
	}

	if(S6_M==3&&S7_LED==1)
	{ 
		if(j>=4)	j =0;
		switch(j)
		{ 
			case 0:P2 = 0x80;P0 = LED_M3[0];j++;delay(EEPROM);break;
			case 1:P2 = 0x80;P0 = LED_M3[1];j++;delay(EEPROM);break;
			case 2:P2 = 0x80;P0 = LED_M3[2];j++;delay(EEPROM);break;
			case 3:P2 = 0x80;P0 = LED_M3[3];j=0;delay(EEPROM);break;
			default : break;
		}
	}

	if(S6_M==4&&S7_LED==1)
	{ 
		if(j>=4)	j =0;
		switch(j)
		{ 
			case 0:P2 = 0x80;P0 = LED_M4[0];j++;delay(EEPROM);break;
			case 1:P2 = 0x80;P0 = LED_M4[1];j++;delay(EEPROM);break;
			case 2:P2 = 0x80;P0 = LED_M4[2];j++;delay(EEPROM);break;
			case 3:P2 = 0x80;P0 = LED_M4[3];j=0;delay(EEPROM);break;
			default : break;
		}
	}

	if(S7_LED==0)
	{ 
	  P2 = (P2&0x1F)|0x80;	P0 = 0xFF;
	}
}

void Display_1_2()			   //数码管闪烁时的灭的状态
{ 
    LEDbuff[7] = LED[11];
	LEDbuff[6] = LED[11];
	LEDbuff[5] = LED[11];
	LEDbuff[4] = LED[11];
}

void Display_2_2()			   //数码管闪烁时的灭的状态
{ 							 
	LEDbuff[3] = LED[11];
	LEDbuff[2] = LED[11];
	LEDbuff[1] = LED[11];
	LEDbuff[0] = LED[11];
}

void Display_PWM()				//S4按键按下时的亮度等级
{ 
	LEDbuff[1] = LED[10];
	LEDbuff[0] = LED[PWM_flag];	
}
void Display_3()
{ 
	if(S7_start==1&&S6_flag==0)	{ Display_1();Display_2();}
	if(S7_start==1&&S6_flag==1)  { Display_1_2();Display_2_2();}
	if(S7_start==1&&S6_flag==2)	
	{ 
		if(Fl==0)   { Display_1();Display_2();}
		if(Fl==1)	{ Display_1_2();Display_2();}
	}
	if(S7_start==1&&S6_flag==3)
	{ 
		if(Fl==0)   { Display_1();Display_2();}
		if(Fl==1)	{ Display_1();Display_2_2();}
	}
}

void KEY_S7()
{ 
	if(S7==0)
	{ 
		delay(5);
		if(S7==0)
			check_S7=1;
	}
	if((S7==1)&&(check_S7==1))
	{ 
		check_S7 = 0;
		S7_start = 1;
		S7_LED = ~S7_LED;	
	}	
}

void KEY_S6()
{ 
	if(S6==0)
	{ 
		delay(5);
		if(S6==0)
			check_S6=1;
	}
	if((S6==1)&&(check_S6==1))
	{ 
		check_S6=0;
		S6_flag++;
		if(S6_flag>=4)
			S6_flag=0;	
	}
}

void KEY_S5()
{ 
	if(S5==0)
	{ 
		delay(5);
		if(S5==0)
			check_S5=1;
	}
	if((S5==1)&&(check_S5==1))
	{ 
		check_S5=0;
		if(S6_flag==2)
		{ 
			S6_M++;
			if(S6_M>=5)
				S6_M=1;
		}
		if(S6_flag==3)
		{ 
			EEPROM_flag++;
			if(EEPROM_flag>=13)
				EEPROM_flag=4;
		}
	}	
}

void KEY_S4()
{ 
	if(S4==0)
	{ 
		delay(5);
		if(S4==0)
			check_S4=1;
	}
	if((S4==1)&&(check_S4==1))
	{ 
		check_S4=0;S7_start=1;
		if(S6_flag==2)
		{ 
			S6_M--;
			if(S6_M<=0)
				S6_M=3;
		}
		if(S6_flag==3)
		{ 
			EEPROM_flag--;
			if(EEPROM_flag<=4)
				EEPROM_flag=12;
		}
	}
	if(S4==0&&S6_flag==0)	 
	{ S7_start=0;Display_PWM();}	
}

void KEY()
{ 
	KEY_S4();
	KEY_S5();
	KEY_S6();
	KEY_S7();
}

void PWM()
{ 
	if(AD>=0&&AD<64)	PWM_flag=1;
	if(AD>=64&&AD<128)	PWM_flag=2;
	if(AD>=128&&AD<192)	PWM_flag=3;
	if(AD>=192&&AD<256)	PWM_flag=4;

	if(PWM_flag==1&&S7_start==1)	
	{ 
		if(cnt<=EEPROM*0.25) S7_LED=1;
		if(cnt>=EEPROM*0.25&&cnt<=EEPROM) S7_LED=0;
		cnt=0;
	} 

	if(PWM_flag==2&&S7_start==1)	
	{ 
		if(cnt<=EEPROM*0.5) S7_LED=1;
		if(cnt>=EEPROM*0.5&&cnt<=EEPROM) S7_LED=0;
		cnt=0;
	} 

	if(PWM_flag==3&&S7_start==1)	
	{ 
		if(cnt<=EEPROM*0.75) S7_LED=1;
		if(cnt>=EEPROM*0.75&&cnt<=EEPROM) S7_LED=0;
		cnt=0;
	} 

}

void InterruptTimer0() interrupt 1
{ 
	static unsigned char i=0,j=0;
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	if(S7_start==1)
	{ 
		switch(i)
		{ 
			case 0:P2 = 0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];P2=0x00;i++;break;
			case 1:P2 = 0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];P2=0x00;i++;break;
			case 2:P2 = 0xC0;P0=0x20;P2=0xE0;P0=LEDbuff[2];P2=0x00;i++;break;
			case 3:P2 = 0xC0;P0=0x10;P2=0xE0;P0=LEDbuff[3];P2=0x00;i++;break;
			case 4:P2 = 0xC0;P0=0x08;P2=0xE0;P0=LEDbuff[4];P2=0x00;i++;break;
			case 5:P2 = 0xC0;P0=0x04;P2=0xE0;P0=LEDbuff[5];P2=0x00;i++;break;
			case 6:P2 = 0xC0;P0=0x02;P2=0xE0;P0=LEDbuff[6];P2=0x00;i++;break;
			case 7:P2 = 0xC0;P0=0x01;P2=0xE0;P0=LEDbuff[7];P2=0x00;i=0;break;
			default : break;
		}
	}
	if(S7_start==0&&S4==0)
	{ 
		switch(j)
		{ 
			case 0:P2 = 0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];P2=0x00;j++;break;
			case 1:P2 = 0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];P2=0x00;j=0;break;
			default : break;
		}
	}
    EEPROM= EEPROM_flag*100;	   //EEPROM写成4-12方便获取初值,不需要高八位低八位的或运算
	cnt++;clock++;
	num++;if(num>=800){ num=0;Fl=~Fl;}
	PWM();
}

嗯,我觉得我写的超级短,而且满简洁的,就是按键需要长按,要不好使的很,上方是main.c文件



#include<STC15F2K60S2.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 AD_Init()			 //AD初始化
{ 
	 IIC_Start();
	 IIC_SendByte(0x90);
	 IIC_WaitAck();
	 IIC_SendByte(0x43);
	 IIC_WaitAck();
	 IIC_Stop();
}

unsigned char AD_Get()	   //AD获取
{ 
	 unsigned char temp=0;

	 IIC_Start();
	 IIC_SendByte(0x91);
	 IIC_WaitAck();
	 temp = IIC_RecByte();
	 IIC_Stop();
	 return temp;
} 

void EEPROM_Write(unsigned char add,unsigned char dat)				 //EEPROM数据写入
{ 
	IIC_Start();
	IIC_SendByte(0xA0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

unsigned char EEPROM_Get(unsigned char add)			   //EEPROM数据读取
{ 
	unsigned char temp =0;
	IIC_Start();
	IIC_SendByte(0xA0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();

	IIC_Start();
	IIC_SendByte(0xA1);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_Stop();

	return temp;
}

iic里写了EEPROM和AD的内容,应该没人需要看,还是放上吧。。。。

#ifndef _IIC_H
#define _IIC_H
sbit SDA = P2^1;  
sbit SCL = P2^0;  

#include<STC15F2K60S2.h>
#include "intrins.h"
void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void);
void AD_Init();
unsigned char AD_Get(); 
void EEPROM_Write(unsigned char add,unsigned char dat);
unsigned char EEPROM_Get(unsigned char add);


#endif

IIC.h文件。。。。。。。

其实写了好久,还是太差了,就这吧,感谢观看

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服