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

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

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

相关文章

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

利用Python调试串口的示例代码

《利用Python调试串口的示例代码》在嵌入式开发、物联网设备调试过程中,串口通信是最基础的调试手段本文将带你用Python+ttkbootstrap打造一款高颜值、多功能的串口调试助手,需要的可以了... 目录概述:为什么需要专业的串口调试工具项目架构设计1.1 技术栈选型1.2 关键类说明1.3 线程模

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

最详细安装 PostgreSQL方法及常见问题解决

《最详细安装PostgreSQL方法及常见问题解决》:本文主要介绍最详细安装PostgreSQL方法及常见问题解决,介绍了在Windows系统上安装PostgreSQL及Linux系统上安装Po... 目录一、在 Windows 系统上安装 PostgreSQL1. 下载 PostgreSQL 安装包2.

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析