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

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

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 pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

在macOS上安装jenv管理JDK版本的详细步骤

《在macOS上安装jenv管理JDK版本的详细步骤》jEnv是一个命令行工具,正如它的官网所宣称的那样,它是来让你忘记怎么配置JAVA_HOME环境变量的神队友,:本文主要介绍在macOS上安装... 目录前言安装 jenv添加 JDK 版本到 jenv切换 JDK 版本总结前言China编程在开发 Java

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

如何在Java Spring实现异步执行(详细篇)

《如何在JavaSpring实现异步执行(详细篇)》Spring框架通过@Async、Executor等实现异步执行,提升系统性能与响应速度,支持自定义线程池管理并发,本文给大家介绍如何在Sprin... 目录前言1. 使用 @Async 实现异步执行1.1 启用异步执行支持1.2 创建异步方法1.3 调用

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三