同学问我这个题目,然后我就做了,刚好最近断更,就用这个来凑个数吧,也检验看看寒假退步了多少,顺便记录这次做题。

题目

“彩灯控制器”的程序设计
一、基本要求:
a)单片机竞赛板限于使用MCS-51单片机或者STM32系列单片机。
b)电脑自带,编程所需软件需提前完成安装。
c)实现相同功能,用时短者优先排名。
d)比赛时长: 5月11日 14:00 ~ 17:00
二、功能描述:
a)基本功能描述:通过单片机控制LED指示灯的工作模式。
b)设计说明
i.关闭与本试题无关的外设资源,
ii.8个LED指示灯开机默认为熄灭状态
iii.8个LED指示灯工作模式如下:
1.模式1:8个LED指示灯按照顺序从左往右逐个点亮,接着从右往左逐个点亮,循环执行。单个LED点亮时间为1000ms。
2.模式2:8个LED指示灯同时以0.5Hz频率,50%占空比点亮
iv.按键工作模式:
1.按键1(模式切换按键):按下按键,将LED指示灯模式从模式1切换成模式2,再次按下按键,LED显示从模式2切换成模式1,模式循环切换。当模式2切换回模式1时,起始的亮灯顺序从上次跳到模式2开始,当模式1切换回模式2时,LED闪烁频率占空比与上次跳到模式1前一样。
2.按键2(加按键):按下按键,若当前处于模式1,则会增加100ms的单个LED点亮时间,当增加到2000ms时,再次按下该按键,点亮时间将改为1000ms。若当前处于模式2,则会增加10%占空比,当占空比增加到100%时,再次按下该按键,占空比将改为50%。
3.按键3(减按键):按下按键,若当前处于模式1,则会减少100ms的单个LED点亮时间,当减少到500ms时,再次按下该按键,点亮时间将改为1000ms。若当前处于模式2,则会减少10%占空比,当占空比减少到10%时,再次按下该按键,占空比将改为50%。
v.按键模式需在数码管上或液晶上显示,显示格式
如 1 时间 或 2 占空比
三、评分细则
功能 分值(总分100分)
模式1,实现LED左右来回循环闪烁 10
模式2,实现LED闪烁 10
按键1实现模式1和模式2切换功能 20
模式1下,按键2和按键3功能实现 20
模式2下,按键2和按键3功能实现 20
数码管或液晶能够正确显示当前操作信息 20
四、注意事项
提交材料为(工程项目和Hex可执行文件),工程项目和Hex文件的命名为给定编号。不得含有专业、个人等信息,发现扣20分。本科以B开头,大专组以C开头。

代码

//sys.h

#ifndef __SYS_H_
#define __SYS_H_#include <STC15F2K60S2.H>
#include <intrins.h>sbit s4=P3^3;  //实现按键按下模式一和模式二相互转换
sbit s5=P3^2;  //实现按键按下模式一情况下LED移动时间增加100ms,模式二情况下占空比增加10%
sbit s6=P3^1;  //实现按键按下模式一情况下LED移动时间减少100ms,模式二情况下占空比减少10%#ifndef uint
#define uint unsigned int
#endif#ifndef uchar
#define uchar unsigned char
#endifextern uint t;
extern uint y;
extern uchar led_flag;
extern uchar KeySta[3],Key_backup[3];//led.c
void LED_Init(void);
void led_disp(uchar led);
void LED_disp1();//key.c
void Key_Scan(void);
void Key_Deal(void);
void led_flag_change(uint led_flag,uint i);//seg.c
void Nixie_Scan(void);
void Nixie_Show(void);
void Nixie_change(void);//tim.c
void ALL_Init(void);
void Timer_Init(void);
void Timer_change(uchar led_flag);
#endif

//led.c

#include "sys.h"void led_disp(uchar led){//LED基本点亮函数P2 = P2 & 0x1f | 0x80;P0 = led;P2 &= 0x1f;
}void LED_disp1(){//模式1流水灯函数static uchar led1 = 0xFE;static uint index = 0;static uint flag = 0;//左移右移标志位led_disp(led1);//放判断外面,使得第一个灯不被忽视if(!flag){//flag为0时,先右移led1 = _crol_(led1,1);if(++index == 7){flag = 1;index = 0;}}else{//flag为1时,左移led1 = _cror_(led1,1);if(++index == 7){flag = 0;index = 0;}}
}

//key.c

#include "sys.h"
//按键扫描
void Key_Scan(void)
{uint i;static uchar keybuff[] = {0xff,0xff,0xff};keybuff[0] = (keybuff[0] << 1) | s4;keybuff[1] = (keybuff[1] << 1) | s5;keybuff[2] = (keybuff[2] << 1) | s6;for(i = 0;i < 3;i ++){if(keybuff[i] == 0xff)        //连续扫描8次都是1,16ms内都是弹起状态,按键已松开{KeySta[i] = 1;}else if(keybuff[i] == 0x00)  //连续扫描8次都是0,16ms内都是按下状态,按键已按下{KeySta[i] = 0;}else    //其他状态键值不稳定,不作处理{}}
}//按键处理
void Key_Deal(void)
{uchar i;for(i = 0;i < 3;i ++){if(KeySta[i] == 0){switch(i){case 0:led_flag = ~led_flag;break;case 1:led_flag_change(led_flag,0);break;//加按键case 2:led_flag_change(led_flag,1);break;//减按键}}}
}void led_flag_change(uint led_flag,uint i){//设置0为加按键,1为减按键if(!i){//加按键时if(!led_flag){//若为模式1,则时长增加t*100msif(++ t > 20)t = 10;}else{//若为模式2,高电平时间增加4*100ms,即增加10%占空比y = y + 4;if(y > 40)y = 20;}}else{//减按键时if(!led_flag){//若为模式1,则时长减少t*100msif(-- t < 5)t = 10;}else{//若为模式2,高电平时间减少4*100ms,即减少10%占空比y = y - 4;if(y < 4)y = 20;}}
}

//seg.c

#include "sys.h"//共阳数码管码字
uchar code Nixie[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,//0-9字符0xbf};  //符号-
uchar NixieBuff[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; //数码管显示缓冲区,初值0xff确保启动时都不亮uchar smg1,smg2,smg3,smg4,smg5,smg6,smg7,smg8;//数码管显示
void Nixie_Scan(void)
{static uchar index = 0;P2 = (P2 & 0x1f) | 0xe0;  //数码管消隐P0 =0xff;P2 = (P2 & 0x1f) | 0xc0;  //数码管位选P0 = 0x01 << index;P2 = (P2 & 0x1f) | 0xe0;  //数码管段选P0 = NixieBuff[index];P2 &= 0x1f;index ++;index &= 0x07;
}//数码管显示
void Nixie_Show(void)
{NixieBuff[0] = Nixie[smg1];NixieBuff[1] = Nixie[smg2];NixieBuff[2] = Nixie[smg3];NixieBuff[3] = Nixie[smg4];NixieBuff[4] = Nixie[smg5];NixieBuff[5] = Nixie[smg6];NixieBuff[6] = Nixie[smg7];NixieBuff[7] = Nixie[smg8];
}//显示处理
void Nixie_change(void)
{if(!led_flag){//模式1时,输出为 1----1000/1----500smg1 = 1;smg2 = smg3 = smg4 = 10;if(t > 9)smg5 = t / 10;else smg5 = 10;smg6 = t % 10;smg7 = smg8 = 0;}else{//模式2时,输出为2----100/2-----50smg1 = 2;smg2 = smg3 = smg4 = smg5 = 10;if(y == 40){smg6 = y / 40;smg7 = 0;}else{smg6 = 10;smg7 = y / 4;}smg8 = 0;}//0.5hz,两秒闪一次,50%占空比,高电平为2000ms,每次加减10%占空比,每次加减400ms
}

//tim.c

#include "sys.h"
void ALL_Init(void){//单片机初始化P0 = 0xff;P2 = P2 & 0x1f | 0x80;//初始化LEDP2 = P2 & 0x1f | 0xE0;//初始化SEGP2 &= 0x1f;P0 = 0;P2 |= 0xA0;//初始化蜂鸣器P2 &= 0x1f;
}void Timer_Init(void){AUXR &= 0x3F;       //定时器时钟12T模式TMOD &= 0x00;      //设置定时器模式TL0 = 0x18;         //设置定时初值TH0 = 0xFC;        //设置定时初值TL1 = 0x18;        //设置定时初值TH1 = 0xFC;        //设置定时初值TF0 = 0;         //清除TF0标志TR0 = 1;          //定时器0开始计时TF1 = 0;         //清除TF1标志TR1 = 1;          //定时器1开始计时ET0 = 1;        //允许定时器0中断ET1 = 1;        //允许定时器1中断
}
//转换定时器函数,使得不同的模式用不同的定时器
void Timer_change(uchar led_flag){if(!led_flag){TR0 = ET0 = 1;TR1 = ET1 = 0;}else{TR0 = ET0 = 0;TR1 = ET1 = 1;}}void Timer0(void) interrupt 1{static uint t0 = 0;Key_Scan();//扫描按键if(++t0 == t*100){LED_disp1();//运行模式1流水灯t0 = 0;}Nixie_change();//seg显示Nixie_Show();Nixie_Scan();
}void Timer1(void) interrupt 3{static uint t1 = 0;Key_Scan();//按键扫描if(t1 <= y*100){//设置占空比led_disp(0x00);}else{led_disp(0xFF);}if(++ t1 == 4000)t1 = 0;Nixie_change();//SEG显示Nixie_Show();Nixie_Scan();
}

//main.c

#include <STC15F2K60S2.H>
#include "sys.h"
uint t = 10;//LED点亮时间
uint y = 20;//高电平时长uchar led_flag = 0;//模式标志位,0为模式1,1为模式2
uchar KeySta[3] = {1,1,1};     //当前按键状态
uchar Key_backup[3] = {1,1,1}; //按键状态备份,保存前一次的按键值uint i;//主函数循环里的小变量
void main(){ALL_Init();Timer_Init();EA = 1;//打开总中断while(1){for(i = 0;i < 3;i++){if(Key_backup[i] != KeySta[i]){if(Key_backup[i] != 0)Key_Deal();Key_backup[i] = KeySta[i];}}//更新按键键值Timer_change(led_flag);//转换定时器}}

挺容易的一道题,关键在于思路。思路想通了,编程就很容易了。
这句话送给我那做了三四天模式1都还没做出来的同学(吃瓜)。

蓝桥杯单片机——“”彩灯控制器”的程序设计相关推荐

  1. 第十三届“蓝桥杯”单片机省赛——程序设计题

    第十三届"蓝桥杯"单片机省赛--程序设计题 在比赛时候编写,代码仅供参考 如有不足,多多指教 1.题目 2.代码 main.c程序 #include "reg52.h&q ...

  2. 【蓝桥杯单片机进阶强化-04】PCF8591与24C02综合应用-智能照明自动控制器

    [1]题目要求 在蓝桥杯大赛"单片机设计与开发"的在CT107D综合训练平台上,利用竞赛提供的IIC底层驱动代码,设计程序,实现以下的功能: 1- 系统上电后,通过采样PCF859 ...

  3. 第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf

    第九届蓝桥杯单片机组省赛试题 "彩灯控制器"的程序设计与调试 (70 分) 一.基本要求 1.1 使用CT107D 单片机竞赛板,完成"彩灯控制器"功能的程序设 ...

  4. 【蓝桥杯单片机(24)】历届单片机客观题及答案解析

    目录 考前冲刺,专栏完结篇 ## 推荐链接: 推荐视频–小蜜蜂老师讲解 赛点资源包下载,提取码:brno 三极管基本知识总结 运算放大电路的基础 第十三届蓝桥杯单片机官方直播课录屏 目录 一些刷题后的 ...

  5. 【蓝桥杯单片机11】单总线温度传感器DS18B20的基本操作

    [蓝桥杯单片机11]单总线温度传感器DS18B20的基本操作 广东职业技术学院 欧浩源 单总线数字温度传感器DS18B20几乎成了各类单片机甚至ARM实验板的标配模块来,在蓝桥杯的往届省赛和国赛中,这 ...

  6. 【蓝桥杯单片机组】备赛实战问题记录

    微信搜索:ReCclay,也可免费阅读博主蓝桥系列所有文章,后台回复"代码"即可获取蓝桥所有备赛代码!关注博主公众号,还可拥有加入博主粉丝群实时沟通技术难题.免费下载CSDN资源等 ...

  7. 蓝桥杯单片机串口通信学习提升笔记

    今日得以继续蓝桥杯国赛备赛之旅: 有道是 "不知何事萦怀抱,醒也无聊,醉也无聊,梦也何曾到谢桥." 那我们该如何 让这位诗人纳兰 "再听乐府曲 ,畅解相思苦"呢 ...

  8. 蓝桥杯单片机组——榨干选手资源包(芯片数据手册)

    文章目录 前言 DS18B20 原理图 1-Wire协议简介 赛场技巧 DS1302 原理图 SPI协议简介 赛场技巧 AT24C02 原理图 IIC协议简介 赛场技巧 PCF8591 原理图 赛场技 ...

  9. 蓝桥杯省赛考点_【蓝桥杯单片机01】从历年决赛真题中寻找单片机常见的考点...

    [蓝桥杯单片机01]从历年决赛真题中寻找单片机常见的考点 广东职业技术学院  欧浩源 [第三届:门禁系统] 1.功能简述 "门禁系统"主要有两种工作模式: 模式1:7:00-22: ...

  10. 蓝桥杯单片机DS18B20代码注释及部分时序图

    蓝桥杯单片机蓝桥杯单片机DS18B20代码注释及部分时序图 #include<STC15F2K60S2.H> #include<intrins.h>#define uchar ...

最新文章

  1. iOS培训教程——设置默认语言
  2. 服务器与本地时间的倒计时
  3. 【Python小游戏】当当当当 万众瞩目得《滑雪大冒险》来啦~(附源码)
  4. C语言socket bind()函数(为socket套接字关联了一个相应的地址与端口号)
  5. WaitForMultipleObject与MsgWaitForMultipleObjects用法
  6. 数学建模:1.概述 监督学习--回归分析模型
  7. 如何解决光端机的开关量问题?
  8. 不可用于python编程开发的是_Python编程语言可做而不应做的一些事是什么_Python视频_Python视频教程_编程语言_课课家...
  9. Netty工作笔记0054---EventLoop组件
  10. linux v4l2进行视频采集编程介绍
  11. 设备树与驱动的关系_9 Linux设备树的原理与应用实例(一)—— 什么是设备树...
  12. python 回调函数的使用_Python回调函数用法实例详解
  13. 如何将超大文件传输给别人,超大文件如何传输
  14. 【随笔 || 逐源·极简学习法】
  15. 老司机通过后视镜辨别车距 完爆倒车影像功能
  16. 接口地址没错但是报404
  17. CAD软件中沿墙镜像功能的使用技巧
  18. centos7 SFTP
  19. 【RAII】RAII 技术(内存安全解决技术/自动化解锁技术)
  20. EXCEL中如何使用正则表达式

热门文章

  1. dp动态规划分类详解
  2. 2022年4月树莓派系统初始用户名密码
  3. 国标:PAAS应用程序管理要求
  4. java dagger2_mvp+dagger2+retrofit2+rxjava 项目框架 最佳实践
  5. windows上pip安装及使用详解
  6. 弹性系数和线径的计算公式_弹簧计算公式
  7. python3写360图库爬虫
  8. 创客教室-中小学创客教育课程介绍
  9. Cypress下载安装+问题记录
  10. 微信小程序从云开发到上线