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

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

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

相关文章

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

沁恒CH32在MounRiver Studio上环境配置以及使用详细教程

目录 1.  RISC-V简介 2.  CPU架构现状 3.  MounRiver Studio软件下载 4.  MounRiver Studio软件安装 5.  MounRiver Studio软件介绍 6.  创建工程 7.  编译代码 1.  RISC-V简介         RISC就是精简指令集计算机(Reduced Instruction SetCom

arduino ide安装详细步骤

​ 大家好,我是程序员小羊! 前言: Arduino IDE 是一个专为编程 Arduino 微控制器设计的集成开发环境,使用起来非常方便。下面将介绍如何在不同平台上安装 Arduino IDE 的详细步骤,包括 Windows、Mac 和 Linux 系统。 一、在 Windows 上安装 Arduino IDE 1. 下载 Arduino IDE 打开 Arduino 官网

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断