蓝桥杯第九届省赛真题代码——彩灯控制器-附详细讲解思路

本文主要是介绍蓝桥杯第九届省赛真题代码——彩灯控制器-附详细讲解思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 比赛题目要求

2. 功能实现推荐步骤

首先,添加头文件,搭建最底层的代码,实现基本的流水灯运转与数码管显示rb2的电阻值

然后,进行pwm脉宽调制,实现rb2数值不同,从而灯光亮度不同。并作出数码管的多窗口切换

接着,完成4个独立按键的功能配置,每写一个按键,就把一个按键的功能完善好

再是,测试数码管的显示效果,这个至关重要,保证每个数码管显示效果较好

最后,编写24c02的程序

3. 各个功能模块实现思路

以下内容由chatgpt4.0生成:

  1. PWM调节亮度相关变量:

    • pwm_50us:用于产生PWM信号的基础时间计数器,每50微秒增加一次。
    • pwm_duty:PWM占空比控制变量,决定LED亮度级别。
    • value_led:传入P0口的LED的亮度数值
  2. 数码管闪烁与动态显示相关变量:

    • SMG_flag:数码管窗口切换标志位,控制数码管是显示LED亮度值还是流水灯的速度。
    • flash_count:用于控制数码管刷新的计数器。
  3. 数码管显示窗口切换相关变量:

    • key6_state:用于控制数码管显示内容切换的按键状态变量,其值改变时会切换显示内容。
    • if_800ms:控制数码管是否闪烁的标志,以800ms为周期。
  4. 模拟信号读取相关变量:

    • rb2_value:存储从模拟转换器读取的模拟值,该值用于根据模拟信号的大小调节LED灯的亮度。
  5. LED流水灯控制相关变量:

    • led_move:控制LED流水灯流动的计数器。
    • led_mode_value:LED模式值,决定了LED灯亮度调节的模式。

        程序中,通过定时器init_timer0init_timer1的设置,实现了基于时间的任务调度,如PWM信号的生成、数码管的动态显示和闪烁等。数码管的具体显示由state_SMGstate_SMG_all函数控制,通过这些函数可以将要显示的数字或模式对应的码传送到数码管上显示。而valuerunning函数则根据模拟信号(通过rb2_value读取)调整PWM占空比(pwm_duty),进而调节LED亮度。此外,通过按键的检测(keyrunning函数),用户可以切换显示模式和调整亮度或流水灯速度。

4. 代码参考

/**
该代码为蓝桥杯单片机组第九届省赛程序——彩灯控制器
作者:archie474:CSDN
欢迎在博客中留言代码中的问题,以及存在的疑惑
*/#include <reg52.h>
#include <intrins.h>
#include <absacc.h>
#include <iic.h>sbit AUXR = 0x8e;
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;unsigned char code duanma[18] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};unsigned char code ledmode2[8] = { 0x7f , 0xbf , 0xdf , 0xef , 0xf7 , 0xfb , 0xfd , 0xfe };
unsigned char code ledmode1[8] = { 0xfe , 0xfd , 0xfb , 0xf7 , 0xef , 0xdf , 0xbf , 0x7f };
unsigned char code ledmode3[4] = { 0x7e , 0xbd , 0xdb , 0xe7 };
unsigned char code ledmode4[4] = { 0xe7 , 0xdb , 0xbd , 0x7e };unsigned char sys_stop = 0;
unsigned char pwm_50us = 0;
unsigned char pwm_5ms = 0;
unsigned char pwm_duty = 0;
unsigned char value_led = 0;bit led_stop = 0;
unsigned char key6_state = 0;
bit key5_state = 0;
bit key4_state = 0;void SMG_flashing ();
void save_data();void state_SMG ( unsigned char pos_SMG , unsigned char value_SMG )
{XBYTE[0xe000] = 0xff;XBYTE[0xc000] = 0x01 << pos_SMG;XBYTE[0xe000] = value_SMG;
}void state_SMG_all ( unsigned char value_SMG_all )
{XBYTE[0xc000] = 0xff;XBYTE[0xe000] = value_SMG_all;
}	void init_sys ()
{XBYTE[0x8000] = 0xff;XBYTE[0xa000] = 0x00;state_SMG_all ( 0xff );
}void write_at24c02 ( unsigned char addr_write , unsigned char value_write )
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(addr_write);I2CWaitAck();I2CSendByte(value_write);I2CWaitAck();I2CStop();
}/**
void write_at24c02a ( unsigned char addr_write , unsigned char value_write )
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(addr_write);I2CWaitAck();I2CSendByte(value_write);I2CWaitAck();I2CStop();
}unsigned char read_at24c02 ( unsigned char addr_read )
{unsigned char power_count_temp;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(addr_read);I2CWaitAck();I2CStart();I2CSendByte(0xa1);I2CWaitAck();power_count_temp = I2CReceiveByte();I2CSendAck(1);I2CStop();return power_count_temp;
}
*/unsigned char rb2_value = 0;
void rb2running()
{I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(0x03);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0x91);I2CWaitAck();rb2_value = I2CReceiveByte();I2CSendAck(1);I2CStop();	
}void init_timer0 (void)		//50微秒@11.0592MHz,定时器0
{AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x02;		//设置定时器模式TL0 = 0xD2;		//设置定时初值TH0 = 0xD2;		//设置定时重载值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时EA = 1;ET0 = 1;
}void init_timer1(void)		//50毫秒@11.0592MHz,定时器1
{AUXR &= 0xBF;		//定时器时钟12T模式TMOD &= 0x0F;		//设置定时器模式TMOD |= 0x10;		//设置定时器模式TL1 = 0x00;		//设置定时初值TH1 = 0x4C;		//设置定时初值TF1 = 0;		//清除TF1标志TR1 = 1;		//定时器1开始计时EA = 1;ET1 = 1;
}bit SMG_flag = 0;
unsigned char flash_count = 0;
void timer0_service () interrupt 1
{TL0 = 0x98;		//设置定时初值TH0 = 0xF1;		//设置定时初值if ( sys_stop == 0 ){return ;}if ( ++pwm_50us == 100 ){pwm_50us = 0;}if ( pwm_50us % 20 == 0 ){if ( SMG_flag == 0 ){if ( ++flash_count == 7 ){flash_count = 0;}}else if ( SMG_flag == 1 ){if ( ++flash_count > 1 ){flash_count = 0;}	}SMG_flashing ();}if ( pwm_50us < pwm_duty ){XBYTE[0x8000] = value_led;}else{XBYTE[0x8000] = 0xff;}
}unsigned char led_move = 0;
unsigned char set_time = 4;    //设定的流转时间,取值4~12
unsigned char led_bit = 0;	//设定led的对应位
unsigned char count_50ms = 0;
unsigned char count_100ms = 0;
bit if_800ms = 0;
void timer1_service () interrupt 3
{TL1 = 0x00;		//设置定时初值TH1 = 0x4C;		//设置定时初值count_50ms ++;if ( count_50ms % 2 == 0 ){if ( ++count_100ms >= set_time ){if ( led_stop == 0 ){led_move ++;}count_100ms = 0;}rb2running ();}if ( count_50ms == 16 ){count_50ms = 0;save_data();	//将数据写入at24c02存储起来if_800ms = ~if_800ms;}}bit set_flag = 0;
unsigned char led_mode_value = 0;
void valuerunning ()
{if ( set_flag == 0 ){if ( rb2_value < 53 ){pwm_duty = 5;led_mode_value = 1;}else if ( rb2_value < 106 ){pwm_duty = 35;led_mode_value = 2;}else if ( rb2_value < 159 ){pwm_duty = 65;led_mode_value = 3;}else if ( rb2_value < 255 ){pwm_duty = 95;led_mode_value = 4;}}else if ( set_flag == 1 ){if ( led_mode_value == 1 ){pwm_duty = 5;}else if ( led_mode_value == 2 ){pwm_duty = 35;}else if ( led_mode_value == 3 ){pwm_duty = 65;}else if ( led_mode_value == 4 ){pwm_duty = 95;}}if ( key6_state != 0 ){set_flag = 1;}else{set_flag = 0;}if ( led_move < 8 ){value_led = ledmode1[led_move];		}else if ( led_move < 16 ){value_led = ledmode2[led_move-8];		}else if ( led_move < 20 ){value_led = ledmode3[led_move-16];		}else if ( led_move < 24 ){value_led = ledmode4[led_move-20];		}else{led_move = 0;}if ( key6_state == 1 && key5_state == 1 ){key5_state = 0;if ( ++led_mode_value == 5 ){led_mode_value = 4;}}else if ( key6_state == 1 && key4_state == 1 ){key4_state = 0;if ( --led_mode_value == 255 ){led_mode_value = 0;}}else if ( key6_state == 2 && key4_state == 1 ){key4_state = 0;if ( --set_time == 255 ){set_time = 4;}}else if ( key6_state == 2 && key5_state == 1 ){key5_state = 0;if ( ++set_time == 13 ){set_time = 12;}}
}void SMG_flashing ()
{state_SMG_all ( 0xff );if ( SMG_flag == 0 ){if ( key6_state == 0 ){state_SMG_all ( 0xff );}else {switch ( flash_count ){case 0:state_SMG ( 0 , duanma[16] );break;case 1:if ( key6_state == 1 && if_800ms == 0 ){state_SMG ( 1 , 0xff );}else{state_SMG ( 1 , duanma[led_mode_value] );}break;case 2:state_SMG ( 2 , duanma[16] );break;case 3:if ( key6_state == 2 && if_800ms == 0 ){state_SMG ( 5 , 0xff );}else{			if ( set_time > 9 ){			state_SMG ( 4 , duanma[1] );}}break;case 4:if ( key6_state == 2 && if_800ms == 0 ){state_SMG ( 5 , 0xff );}else{state_SMG ( 5 , duanma[set_time%10] );}break;case 5:if ( key6_state == 2 && if_800ms == 0 ){state_SMG ( 6 , 0xff );}else{state_SMG ( 6 , duanma[0] );}break;case 6:if ( key6_state == 2 && if_800ms == 0 ){state_SMG ( 7 , 0xff );}else{state_SMG ( 7 , duanma[0] );}break;}}}else if ( SMG_flag == 1 && key6_state == 0 ){switch ( flash_count ){case 0 :state_SMG ( 6 , duanma[led_mode_value/10] );break;case 1 :state_SMG ( 7 , duanma[led_mode_value%10] );break;}}
}void Delay2ms()		//@11.0592MHz
{unsigned char i, j;_nop_();_nop_();i = 22;j = 128;do{while (--j);} while (--i);
}void keyrunning ()
{if ( S7 == 0 ){Delay2ms();if ( S7 == 0 ){while ( S7 == 0 );led_stop = ~led_stop;sys_stop = 1;}}else if ( S6 == 0 ){Delay2ms();if ( S6 == 0 ){while ( S6 == 0 );if ( ++key6_state == 3 ){key6_state = 0;}}}else if ( S5 == 0 ){Delay2ms();if ( S5 == 0 ){while ( S5 == 0 );if ( key6_state != 0 ){key5_state = ~key5_state;}}}else if ( S4 == 0 ){Delay2ms ();if ( S4 == 0 ){while ( S4 == 0 ){SMG_flag = 1;}SMG_flag = 0;if ( key6_state != 0 ){key4_state = ~key4_state;}}}
}/**功能要求中,没有提到要实现写入内存存储的功能。但是硬件图里花了外部存储器,因此我还是把代码写出来了
//针对小蜜蜂老师提到的内存中原有数据会影响读取数据,这里的逻辑应该可以规避该错误
unsigned char sys_count = 1;	//开机次数记录
void init_at24c02 ()
{unsigned char tmp_mode = 0;unsigned char tmp_time = 0;tmp_mode = read_at24c02 ( 0x02 );tmp_time = read_at24c02 ( 0x03 );if ( tmp_mode > 4 && tmp_time > 12 )	//判断是不是第一次开机,如果内存中没有有效数据,则为第一次开机{write_at24c02a ( 0x01 , sys_count );}sys_count = read_at24c02 ( 0x01 );sys_count ++;
}
*/void save_data()
{
//	write_at24c02 ( 0x01 , sys_count );write_at24c02 ( 0x02 , led_mode_value );write_at24c02 ( 0x03 , set_time );
}void main ()
{init_sys();init_timer1 ();init_timer0 ();
//	init_at24c02 ();while ( 1 ){valuerunning ();keyrunning();}
}/**
该代码为蓝桥杯单片机组第九届省赛程序
作者:archie474:CSDN
欢迎在博客中留言代码中的问题,以及存在的疑惑
*/

这篇关于蓝桥杯第九届省赛真题代码——彩灯控制器-附详细讲解思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/891822

相关文章

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

SpringBoot改造MCP服务器的详细说明(StreamableHTTP 类型)

《SpringBoot改造MCP服务器的详细说明(StreamableHTTP类型)》本文介绍了SpringBoot如何实现MCPStreamableHTTP服务器,并且使用CherryStudio... 目录SpringBoot改造MCP服务器(StreamableHTTP)1 项目说明2 使用说明2.1

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注