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

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
欢迎在博客中留言代码中的问题,以及存在的疑惑
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/532681.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java GC了解

Jstack找到线程的快照 jvm提供其他命令作用 jps&#xff1a; 虚拟机进程状况工具&#xff0c;类似linux的ps命令 jstat&#xff1a;虚拟机统计信息监视工具&#xff0c;经常看gc情况的会使用到 jinfo: java配置信息工具 jmap&#xff1a; java内存映射工具&#xff0c;dump&am…

别催了!超真实格行5G随身WiFi问答它来了!格行5G随身WiFi靠谱吗? 看完这篇文章你就懂了?

总让我测格行5G随身WiFi&#xff0c;一直催催催。这下别催了&#xff0c;你们要的格行5G随身WiFi真实测评它来了&#xff01;这次着重回答大家最关心&#xff0c;问的最多的几个问题&#xff01; 一、问&#xff1a;格行5G随身WiFi网速怎么样&#xff1f; 答&#xff1a;格行5G…

网络编程套接字(一)

目录 一、源IP和目的IP 二、端口号 三、UDP协议和TCP协议 四、网络字节序 五、socket编程 1、socket 常见接口 2、struct sockaddr结构体 一、源IP和目的IP IP地址是IP协议提供的一种统一的地址格式&#xff0c;它为互联网上的每一个网络和每一台主机分配一个逻辑地址&am…

原子操作和竞争条件

所有系统调用都是以原子操作方式执行的。之所以这么说&#xff0c;是指内核保证了某系统调用中的所有步骤会作为独立操作而一次性加以执行&#xff0c;其间不会为其他进程或线程所中断。原子性是某些操作得以圆满成功的关键所在。特别是它规避了竞争状态&#xff08;race condi…

解决ModuleNotFoundError: No module named ‘exceptions‘

一、问题描述 使用python语言处理docx文档&#xff0c;在安装docx库时出现问题&#xff0c;No module named ‘exceptions‘ 二、解决方法 卸载docx&#xff0c;安装python-docx。 pip uninstall docx pip install python-docx 问题解决&#xff01;

SSRF靶场

SSRF概述 ​ 强制服务器发送一个攻击者的请求 ​ 互联网上的很多web应用提供了从其他服务器&#xff08;也可以是本地)获取数据的功能。使用用户指定的URL&#xff0c;web应用可以获取图片&#xff08;载入图片&#xff09;、文件资源&#xff08;下载或读取)。如下图所示&…

[lesson17]对象的构造(上)

对象的构造(上) 对象的初始化 从程序设计的角度&#xff0c;对象只是变量&#xff0c;因此&#xff1a; 在栈上常见对象时&#xff0c;成员变量初始为随机值在堆上创建对象时&#xff0c;成员变量初始为随机值在静态存储区创建对象时&#xff0c;成员变量初始为0值 生活中的对…

算法打卡day41|动态规划篇09| Leetcode198.打家劫舍、213.打家劫舍II、337.打家劫舍 III

算法题 Leetcode 198.打家劫舍 题目链接:198.打家劫舍 大佬视频讲解&#xff1a;198.打家劫舍视频讲解 个人思路 偷还是偷&#xff0c;这取决于前一个和前两个房是否被偷了&#xff0c;这种存在依赖关系的题目可以用动态规划解决。 解法 动态规划 动规五部曲&#xff1a;…

生鲜蔬果配送小程序开发攻略

随着互联网的快速发展&#xff0c;电商行业也在不断壮大。生鲜蔬果作为日常生活必需品&#xff0c;在线销售的需求也在不断增加。为了满足这一需求&#xff0c;开发一款生鲜蔬果配送小程序成为了必要的事情。下面就给大家介绍开发这款小程序的攻略。 1. 确定开发需求 首先&…

Java Swing游戏开发学习23

内容来自RyiSnow视频讲解 这一节讲的是Character Status角色状态或属性。 前言 这一节讲的是实现角色状态或属性的显示&#xff0c;就有点像RPG游戏中&#xff0c;人物属性显示的面板&#xff0c;其中有玩家的装备、玩家的等级&#xff0c;各种防御值、闪避值、跑速什么的。…

基于BP神经网络的分类预测模型matlab代码

基于BP神经网络的分类预测模型matlab代码&#xff0c;该数据集下&#xff0c;本模型的表现优异&#xff0c;训练集准确率可达97%&#xff0c;测试集准确率可达93.5%&#xff0c;表现优异。注释十分齐全适合新手学习。 代码获取链接&#xff1a;基于BP神经网络的分类预测模型ma…

SpringBoot3 + uniapp 对接 阿里云0SS 实现上传图片视频到 0SS 以及 0SS 里删除图片视频的操作(最新)

SpringBoot3 uniapp 对接 阿里云0SS 实现上传图片视频到 0SS 以及 0SS 里删除图片视频的操作 最终效果图uniapp 的源码UpLoadFile.vuedeleteOssFile.jshttp.js SpringBoot3 的源码FileUploadController.javaAliOssUtil.java 最终效果图 uniapp 的源码 UpLoadFile.vue <tem…

第十一届蓝桥杯省赛真题(C/C++大学B组)

试题A &#xff1a;门牌制作 #include <bits/stdc.h> using namespace std;const int N 100000; int arr[N];int main() {int ans 0,t;for(int i 1;i < 2020;i){t i;while(t > 0){if(t % 10 2) ans;t / 10;}}cout<<ans<<endl;return 0; } 试题B …

操作系统(第四周 第一堂)

目录 回顾 进程调度&#xff08;process schedule&#xff09; 进程角度 计算机整体——调度队列 队列图 调度程序 总结 回顾 上一篇文章的重点只有一个————进程 对进程的了解包含以下几个方面&#xff1a;1、程序如何变为进程 2、进程在内存中的存储形式 3、进…

Centos7配置秘钥实现集群免密登录

设备&#xff1a;MacBook Pro、多台Centos7.4服务器(已开启sshd服务) 大体流程&#xff1a;本机生成秘钥&#xff0c;将秘钥上传至服务器即可实现免密登录 1、本地电脑生成秘钥&#xff1a; ssh-keygen -t rsa -C "邮箱地址 例&#xff1a;*****.163.com"一路回车…

Bezier曲线的绘制 matlab

式中&#xff1a; 称为基函数。 。 因为n表示次数&#xff0c;点数为n1&#xff0c;显然i表示第i个控制点。 显然在Matlab中可以同矩阵的形式来计算C(u)。 关键代码为&#xff1a; clc clear % 假设控制点P取值为&#xff1a; P [4,7;13,12;19,4;25,12;30,3]; % 因此&a…

Vue2创建过程记录

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、搭建node二、安装Vue CLI三、搭建新项目四、Elemet安装&#xff08;参照官网步骤[Element官网](https://element.eleme.cn/#/zh-CN/component/installation)&am…

Hibernate多事务同时调用update(T t) ,字段被覆盖问题

前言 今天现网有个订单卡单了&#xff0c;经过排查发现没有任何异常日志&#xff0c;根据日志定位发现本应该更新的一个状态&#xff0c;也sql肯定执行了(使用了Hibernate的ORM框架)&#xff0c;但是数据库里面的状态没有更新。大概逻辑如下 String hql from orderInfo where…

Could not resolve all files for configuration

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、 推荐阅读 一、导…

《前端防坑》- JS基础 - 你觉得typeof nullValue === null 么?

问题 JS原始类型有6种Undefined, Null, Number, String, Boolean, Symbol共6种。 在对原始类型使用typeof进行判断时, typeof stringValue string typeof numberValue number 如果一个变量(nullValue)的值为null&#xff0c;那么typeof nullValue "?" const u …