单片机技术应用(期末大作业)——彩灯控制器

题目:裁定控制器

## 项目相关要求
程序功能: 利用实验开发板,完成“彩灯控制器” 功能的程序设计与调试。

在这里插入图片描述
在这里插入图片描述

所用到的相关知识

流水灯,数码管的动态显示,定时器,独立按键

项目分析

本次项目主要分成三个部分,第一部分:四种模式的流水灯,该部分使四个自定义函数来实现。第二部分:数码管的显示,分为左右两边,左边为运行模式的选择。右边为流水间隔。第三部分:独立按键的控制,分别使用s7,s6,s5,s4来控制不同的功能。 整个项目实现的主要思想:先将实现四种流水灯模式,并将四种模式封装成四个函数,方便调用。定义count,和sum变量,count用来计数,即中断次数,用来实现流水灯的时间间隔。sum用来记录流转间隔,初始为400ms,即sum = 8,每加100ms,sum加2,最多为24,即1200ms。定义mod:记录模式,默认为第一种模式、stop_start:记录启动/暂停状态(0为暂停,1为启动)、run_time:1为"运行模式" 2为 “流转间隔” 3其他数码管全灭(默认为全灭)。每当按下s7时,便让TR1在0和1之间来回替换,以达到暂停和开始的效果,并使用stop_start来记录每次的状态。当按下s6时,依次切换三种状态,即运行状态、流水间隔状态、数码管全灭状态,并使用run_time来记录。s3,s4必须要在run_time等于1或者2才由效果。当按下s3时,并且run_time等于1时,让mod减一,但是mod最小为1,当run_time等于2时让sum减2(即减100ms),最小为8(即400ms)。s4同理。最后显示流水灯和数码管,流水灯根据mod来实现不同的模式;数码管根据run_time来动态显示不同的效果。

相关代码

#include<reg52.h>
#include<intrins.h>
void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}
void Delay10ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 108;
	j = 145;
	do
	{
		while (--j);
	} while (--i);
}
unsigned char code t[4]={0x7e,0xbd,0xdb,0xe7};
unsigned char code duan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//控制数码管的段线
sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;
int count = 0;
int sum = 8;//记录流转间隔,初始为400ms,即sum = 8,每加100ms,sum加2,最多为24
int mod = 1;//记录模式,默认为第一种模式
int a = 0xfe;
int b = 0x7f;
int i = 3;//中间往两边走的下标
int j = 0;//两边往中间的下标
int stop_start = 0;//记录启动/暂停状态(0为暂停,1为启动)
int run_time = 0;//1为"运行模式"  2为 "流转间隔" 3其他数码管全灭(默认为全灭)
int ge,shi,bai,qian;
int shu = 0;
//灯模式
void mod1(){//左往右
		count=0;
		P2=0x80;
    P0=a;
		a=_crol_(a,1);
}
void mod2(){//右往左
	count=0;
	P2=0x80;
  P0=b;
  b=_cror_(b,1);
}
void mod3(){//两边往中间走
	count=0;
	P2=0x80;
	P0=t[j];
	j++;
	if(j == 4){
		j = 0;
	}
}
void mod4(){//中间往两边走
	count=0;
	P2=0x80;
	P0=t[i];
	i--;
	if(i < 0){
		i = 3;
	}
}
void main(){
	P2=0xa0;P0=0x00;//关闭蜂鸣器
	P2 = 0xc0;//刚开始关闭数码管
	P0 = 0x00;
	P2 = 0xe0;
	P0 = 0xff;
	P2 = 0x80;P0 = 0xff;//刚开始关闭灯
	TMOD=0x10;
	TH1=(65536-50000)/256;
	TL1=(65536-50000)%256;
	EA=1;//总中断
	ET1=1;//中断原的中断允许位
	TR1=0;//启动定时器(默认为停止)
	while(1){
		if(s7==0){//启动或者停止流水灯流转
			Delay10ms();//消除抖动
			if(s7==0){
				count = 0;
				if(stop_start == 0){//如果为暂停状态,则让其开始
					stop_start = 1;
					TR1=1;
					while(s7==0){TR1=1;};//判断是否松开
					TR1=1;
				}else{
					stop_start = 0;
					TR1=0;
				  while(s7==0){TR1=0;};//判断是否松开
				  TR1=0;
				}
			}
		}
		
		if(s6==0){//可切换选择"运行模式",或者"流转间隔"
			Delay10ms();//消除抖动
			if(s6==0){
				count = 0;
				if(run_time == 1){
					run_time = 2;
					while(s6==0){};//判断是否松开
				}else if(run_time == 2){
					run_time = 3;
					while(s6==0){};//判断是否松开
				}else{//关闭所以数码管
					run_time = 1;
					while(s6==0){};//判断是否松开
				}
			}
		}
		
		//s5,s4在运行模式或者流转间隔模式下才其作用
		if(run_time == 1 || run_time == 2){
		if(s5==0){//加键,在运行模式时模式加一,但是不能超过,在流转间隔时时间加100ms,最多到1200
			Delay10ms();//消除抖动
			if(s5==0){
				count = 0;
				if(run_time == 1){
					if(mod < 4){//判断是否到边界
						mod++;
					}
				}
				else if(run_time == 2){
					if(sum < 24){//判断是否到边界
						sum += 2;
					}
				}
				while(s5==0){};//判断是否松开
			}
		}
		if(s4==0){//减,在运行模式时模式减一,但是不能为0,在流转间隔时时间减100,最少到400
			Delay10ms();//消除抖动
			if(s4==0){
				count = 0;
				if(run_time == 1){
					if(mod > 1){//判断是否到边界
						mod--;
					}
				}
				if(run_time == 2){
					if(sum > 8){//判断是否到边界
						sum -= 2;
					}
				}
				while(s4==0){};//判断是否松开
			}
		}
	}
	//显示灯
	switch(mod){
		case 1: 
			if(count == sum){
				mod1();
			}
			break;
		case 2: 
			if(count == sum){
				mod2();
			}
			break;
		case 3: 
			if(count == sum){
				mod3();
			}
			break;
		case 4: 
			if(count == sum){
				mod4();
			}
			break;
	}
	//显示数码管
	if(run_time == 3){
		P2 = 0xc0;
		P0 = 0x00;
		P2 = 0xe0;
		P0 = 0xff;
	}else{
		if(run_time == 1){//运行模式1
			shu = sum*50;//计算毫秒
			qian = shu/1000;
			bai = shu%1000/100;
			shi = shu%100/10;
			ge = shu%10;
			//显示模式
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x02;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[1];
			Delay1ms();
			//显示两个横杠
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x01;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = 0xbf;
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x04;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = 0xbf;
			Delay1ms();
			//显示数字
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x10;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[qian];
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x20;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[bai];
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x40;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[shi];
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x80;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[ge];
			Delay1ms();
			
		}else if(run_time == 2){//运行模式2
			shu = sum*50;//计算毫秒
			qian = shu/1000;
			bai = shu%1000/100;
			shi = shu%100/10;
			ge = shu%10;
			//显示模式
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x02;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[2];
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x10;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[qian];
			Delay1ms();
			//显示两个横杠
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x01;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = 0xbf;
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x04;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = 0xbf;
			Delay1ms();
			//显示数字
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x20;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[bai];
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x40;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[shi];
			Delay1ms();
			P2 = 0x00;P0 = 0x00;//消隐
			P2 = 0xc0;P0 = 0x80;
			P2 = 0x00;P0 = 0xff;//消隐
			P2 = 0xe0;P0 = duan[ge];
			Delay1ms();
		}
	}
	}
	
}
void time0() interrupt 3{
	TH1=(65536-50000)/256;
	TL1=(65536-50000)%256;
	count++;//记录中断次数   
}

效果图

模式1(可以调整跳转模式):
在这里插入图片描述
在这里插入图片描述

模式2(可以调整跳转速度):
在这里插入图片描述

总结以及遇到的问题

仿真时,当我们通过按键来对流水灯进行控制,按下按键时,有时候流水会卡住,再按下其他按键,流水灯没有反应,有时候直接出现按键失灵的情况(该问题在仿真时会出现,在使用开发板时不知道会不会出现)。解决问题办法:每当按下任何一个按键时,都让用于中断计数的变量从新0开始计数,便能解决所遇到的问题。

存在的问题:每次调整模式或者调整速度时,会停顿一下,该问题暂时未解决,还请大家多多指教。出现原因:每当按下任何一个按键时,都让用于中断计数的变量从新0开始计数(如果在开发板上,不会出现卡住或者按键失灵问题,则不存在该问题)

本次实验由于疫情原因,只能在家里面使用仿真来做,因为仿真时会出现一些问题。使用开发板可能不会出现上述的问题。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
物联网技术是近年来飞速发展的一项技术,可以将各种物理设备和感知器件通过互联网进行连接和通信,实现智能化的数据传输和控制。在国赛单片机开发中,串口收发是一个重要的功能,而物联网技术应用可以进一步提升其功能和便利性。 物联网技术可以将国赛单片机开发中的串口收发功能与云平台相连接,实现远程控制和监测。通过在云平台上搭建服务器和数据库,可以实时监测和采集国赛单片机的传感器数据,并将其传输到服务器上进行存储和分析。同时,可以通过云平台向单片机下发控制指令,实现对单片机硬件的远程控制。 此外,物联网技术还可以实现多个国赛单片机之间的通信和协同工作。通过互联网的连接,可以将多个单片机通过串口进行数据的传输和接收,实现多个设备之间的数据共享和协同操作。这样一来,在国赛单片机开发中可以实现更复杂和多功能的应用,提高整体系统的性能和效率。 同时,物联网技术还可以通过手机应用与国赛单片机进行无线连接和控制。通过手机应用,可以设置单片机的参数、控制执行器、查看传感器数据等,实现对单片机的远程控制和监测。这样,不仅可以方便用户进行操作和管理,还可以提供更加智能化和便捷的使用体验。 综上所述,物联网技术应用能够将国赛单片机开发中的串口收发功能与互联网相连接,实现远程控制和监测,实现多个单片机之间的通信和协同工作,以及通过手机应用进行无线控制,提高国赛单片机开发的功能和便利性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值