第九届省赛程序设计题--彩灯控制器蓝桥杯真题—02

Posted 谏书稀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九届省赛程序设计题--彩灯控制器蓝桥杯真题—02相关的知识,希望对你有一定的参考价值。

【题目要求】

1.基本功能描述

通过单片机控制8个LED指示灯按照特定的顺序(工作模式)亮灭;指示灯的流转间隔可通过按键调整,亮度可由电位器RB2进行控制;各工作模式的流转间隔时间需在E2PROM中保存,并可在硬件重新上电后,自动载入。

2.设计说明
  • <1> 关闭蜂鸣器、继电器等与本试题程序设计无关的外设资源。
  • <2> 设备上电后默认数码管、LED指示灯均为熄灭状态。
  • <3> 流转间隔可调整范围为400ms-1200ms。
  • <4> 设备固定安照模式1、模式2、模式3、模式4的次序循环往复运行。
3.LED指示灯工作模式
  • <1> 模式1:按照L1、L2…L8的顺序,从左到右单循环点亮。

  • <2> 模式2:按照L8、L7…L1的顺序,从右到左单循环点亮。

  • <3> 模式3:

  • <4> 模式4:

4.亮度等级控制

检测电位器RB2的输出电压,控制8个LED指示灯的亮度,要求在0V~5V的可调区间内,实现4个均匀分布的LED指示灯亮度等级。

5.按键功能
  • <1> 按键S7定义为"启动/停止"按键,按下后启动或停止LED的流转。
  • <2> 按键S6定义为"设置"按键,按键按下后数码管进入"流转间隔"设置界面,如下图所示:
  • <3> 按键S5定义为"加"按键,在设置界面下,按下该键,若当前选择的是运行模式,则运行模式编号加1,若当前选择的是流转间隔,则流转间隔增加100ms。
  • <4> 按键S4定义为"减"按键,在设置界面下,按下该键,若当前选择的是运行模式,则运行模式编号减1,若当前选择的是流转间隔,则流转间隔减少100ms。
  • <5> 按键S4、S5的"加"、"减"功能只在"设置状态"下有效,数值的调整应注意边界属性。
  • <6> 在非"设置状态"下,按键S4按键可显示指示灯当前的亮度等级,4个亮度等级从暗到亮,依次用数字1、2、3、4表示;松开按键S4,数码管显示关闭,亮度等级的显示格式如下图所示:
#include <STC15F2K60S2.H>
#include <absacc.h>
#include <IIC.H>
unsigned char Read_AIN3();
void Write_24c02(unsigned char addr,unsigned char dat);
unsigned char Read_24c02(unsigned char dat);

sbit s7=P3^0; //启动/停止"按键,按下后启动或停止LED的流转。
sbit s6=P3^1; //S6定义为"设置"按键,按键按下后数码管进入"流转间隔"设置界面
sbit s5=P3^2; //S5定义为"加"按键
sbit s4=P3^3; //S4定义为"减"按键

unsigned char table[]=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff;
unsigned char dat_rb2;		//保存电位器rb2的电压
unsigned int count=0;		//长定时计数变量
unsigned int count_smg=0;	//数码管闪烁计数变量
unsigned int time_m[4];		//四个模式的流转间隔时间数组
unsigned char stat=0;		//彩灯当前状态
unsigned char mode=1;		//彩灯工作模式
unsigned char mode_s6=1;	//彩灯设置模式
unsigned char pwm_duty=20;	//pwm的脉宽
unsigned char t_pwm=0;		//pwm的计数变量
unsigned char level=0;		//彩灯亮度等级
unsigned char dat_led=0;	//彩灯当前的工作参数
unsigned char f_set=0;		//按键s6的状态切换变量
unsigned char f_open=0;     //启动与停止变量
unsigned char f_t800=0;		//0.8秒时间间隔标志

void LED_Working(); //声明彩灯模式变换函数
/*===============================================数码管=================================================*/
void delaysmg(unsigned int n)

	while(n--);

void displaysmg_bit(unsigned char pos,unsigned char value)

	XBYTE[0xe000]=0xff;
	XBYTE[0xc000]=0x01<<pos;
	XBYTE[0xe000]=value;

void displaysmg_off()

	XBYTE[0xc000]=0xff;
	XBYTE[0xe000]=0xff;


/*========================================显示彩灯亮度等级============================================*/
void display_level()

	displaysmg_bit(0,0xff);
	delaysmg(100);
	displaysmg_bit(1,0xff);
	delaysmg(100);
	displaysmg_bit(2,0xff);
	delaysmg(100);
	displaysmg_bit(3,0xff);
	delaysmg(100);
	displaysmg_bit(4,0xff);
	delaysmg(100);
	displaysmg_bit(5,0xff);
	delaysmg(100);
	displaysmg_bit(6,table[10]);
	delaysmg(100);
	displaysmg_bit(7,table[level]);
	delaysmg(100);
	displaysmg_bit(7,0xff);
	delaysmg(100);


/*=======================================显示彩灯运行模式设置函数=======================================*/
void display_mode()

	if(f_t800==0)	//0.8秒闪烁,表示选中
	
		displaysmg_bit(0,table[10]);
		delaysmg(100);
		displaysmg_bit(1,table[mode_s6]);
		delaysmg(100);
		displaysmg_bit(2,table[10]);
		delaysmg(100);
	
	else 
	
		displaysmg_bit(0,0xff);
		displaysmg_bit(1,0xff);
		displaysmg_bit(2,0xff);
	
	if(time_m[mode_s6-1]/1000!=0)
	
		displaysmg_bit(4,table[time_m[mode_s6-1]/1000]);
	
	delaysmg(100);
	displaysmg_bit(5,table[(time_m[mode_s6-1]%1000)/100]);
	delaysmg(100);
	displaysmg_bit(6,table[0]);
	delaysmg(100);
	displaysmg_bit(7,table[0]);
	delaysmg(100);


/*=======================================显示彩灯流转间隔的设置函数=======================================*/
void display_time()

	displaysmg_bit(0,table[10]);
	delaysmg(100);
	displaysmg_bit(1,table[mode_s6]);
	delaysmg(100);
	displaysmg_bit(2,table[10]);
	delaysmg(100);
	if(f_t800==0)	//0.8秒闪烁,表示选中
	
		if(time_m[mode_s6-1]/1000!=0)
		
			displaysmg_bit(4,table[time_m[mode_s6-1]/1000]);
		
		delaysmg(100);
		displaysmg_bit(5,table[(time_m[mode_s6-1]%1000)/100]);
		delaysmg(100);
		displaysmg_bit(6,table[0]);
		delaysmg(100);
		displaysmg_bit(7,table[0]);
		delaysmg(100);
	
	else 
	
		displaysmg_bit(4,0xff);
		displaysmg_bit(5,0xff);
		displaysmg_bit(6,0xff);
		displaysmg_bit(7,0xff);
	


/*=========================================初始化定时器0的函数=========================================*/
void InitTimer0()

	TMOD=0X01;
	TH0=(65536-1000)/256;	//定时1ms
	TL0=(65536-1000)%256;
	
	ET0=1;
	EA=1;
	TR0=1;

/*=========================================定时器0中断服务函数=========================================*/
void ServiceTimer0() interrupt 1

	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	t_pwm++;   //产生PWM信号,控制灯光亮度
	if(t_pwm<pwm_duty)
		XBYTE[0X8000]=dat_led;
	else if(t_pwm<20)
		XBYTE[0X8000]=0XFF;
	else 
	
		XBYTE[0X8000]=dat_led;
		t_pwm=0;
		LED_Working();	//彩灯工作模式控制
	
	count++;
	if(count==time_m[mode-1]) //流转间隔处理
	
		count=0;
		if(f_open==1)
  			stat++;
		if(stat==25)
		    stat=0;
	
	
	count_smg++;
	if(count_smg==800) //0.8秒间隔定时
	
		count_smg=0;
		f_t800=~f_t800;
	


/*=========================================RB2电压彩灯亮度控制函数=========================================*/
void level_change()

	if(dat_rb2<60)
	
		pwm_duty=5;
		level=1;
	
	else if(dat_rb2<120)
	
		pwm_duty=10;
		level=2;
	
	else if(dat_rb2<180)
	
		pwm_duty=15;
		level=3;
	
	else
	
		pwm_duty=20;
		level=4;
	


/*=======================================彩灯的四种工作模式变化函数========================================*/
void LED_Working()

	switch(stat)
	
	    //模式1的彩灯变化
		case 0:dat_led=0xff; break;
		case 1:dat_led=0xfe; break;
		case 2:dat_led=0xfc; break;
		case 3:dat_led=0xf8; break;
		case 4:dat_led=0xf0; break;
		case 5:dat_led=0xe0; break;
		case 6:dat_led=0xc0; break;
		case 7:dat_led=0x80; break;
		case 8:dat_led=0x00; break;
		//模式二的彩灯变化
		case 9:dat_led=0x7f; break;
		case 10:dat_led=0x3f; break;
		case 11:dat_led=0x1f; break;
		case 12:dat_led=0x0f; break;
		case 13:dat_led=0x07; break;
		case 14:dat_led=0x03; break;
		case 15:dat_led=0x01; break;
		case 16:dat_led=0x00; break;
		//模式三的彩灯变化
		case 17:dat_led=0x7e; break;
		case 18:dat_led=0xbd; break;
		case 19:dat_led=0xdb; break;
		case 20:dat_led=0xe7; break;
		//模式四的彩灯变化
		case 21:dat_led=0xe7; break;
		case 22:dat_led=0xdb; break;
		case 23:dat_led=0xbd; break;
		case 24:dat_led=0x7e; break;

		//四种工作模式的循环切换
		if(stat==0)
		
			mode=1;
		
		else if(stat==9)
		
			mode=2;
		
		else if(stat==17)
		
			mode=3;
		
		else if(stat==21)
		
			mode=4;
		
	


/*==========================================按键扫描与处理函数===========================================*/
void scan_keys()

	if(s7==0)
	
		delaysmg(100);
		if(s7==0)
		
			if(f_open==0)  //启动彩灯变化
			
				f_open=1;
			
			else  //停止彩灯变化
			
				f_open=0;
				f_set=0;
				stat=0;
				mode=1;
			
			while(s7==0);
		
	
	if(s6==0)
	
		delaysmg(100);
		if(s6==0)
		
			f_set++;     
			while(s6==0)
			
				if(f_set==1)
				
					display_mode();
				
				else if(f_set==2)
				
					display_time();
				
			
		
	
	if(s5==0)
	
		delaysmg(100);
		if(s5==0)
		
			if(f_set==1)
			
				mode_s6+=1;//模式加1
				if(mode_s6>4) //边界处理
				
					mode_s6=4;
				
				while(s5==0)
				
					display_mode();
				
			
			else if(f_set==2)
			
				time_m[mode_s6-1]+=100; //流转间隔加100
				if(time_m[mode_s6-1]>1200)
				
					time_m[mode_s6-1]=1200;
				
				while(s5==0)
				
					display_time();
				
			
		
	
	if(s4==0)
	
		delaysmg(100);
		if(s4==0)
		
			if以上是关于第九届省赛程序设计题--彩灯控制器蓝桥杯真题—02的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥日记②2018第九届省赛(软件类)JavaA组★答案解析

第七届省赛程序设计题--模拟风扇控制系统蓝桥杯真题—04

第九届蓝桥杯JavaA组(2018年)省赛真题解析

第九届蓝桥杯省赛B组 做题记录(python)

第八届省赛程序设计题--电子钟程序设计蓝桥杯真题—03

第九届蓝桥杯省赛B组 做题记录(python)