第九届省赛程序设计题--彩灯控制器蓝桥杯真题—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的主要内容,如果未能解决你的问题,请参考以下文章