当前位置: 首页 > news >正文

积分赛——光敏控制多功系统设计

竞赛板配置:

将IAP15F2K61S2单片机内部振荡器频率设定为12MHz。

键盘工作模式跳线J5配置为矩阵键盘(KBD)模式。

扩展方式跳线J13配置为IO模式。

硬件框图


图1 系统硬件框图 

功能描述


3.1 功能概述

1)通过PCF8591采集光敏电阻电压值。

2)通过数码管、按键完成题目要求的数据显示、界面切换、参数设置功能。

3)通过LED指示灯完成题目要求的输出指示功能。

4)通过继电器模拟开发板外的功率器件。

3.2 性能要求

1)按键动作响应时间:≤0.2.秒。

2)指示灯动作响应时间:≤0.1秒。

3)继电器响应时间:≤0.2秒。

3.3 显示功能

1)欢迎界面

   欢迎界面如图2所示,显示内容固定为(HELLO)。

图2 欢迎界面

2)工作界面

   工作界面如图3所示,显示内容包括标识符(C)、剩余时间组成。剩余时间固定由两位数码管显示,显示不足位数时高位(左侧)数码管熄灭。

图3 工作界面

**剩余时间的初始值为当前设置的时间参数,倒计时过程中从该值递减至0。当时间参数修改后,剩余时间将同步更新为新的参数值

3)设置界面

   设置界面如图4所示,显示内容包括标识符(E)、时间参数组成。时间参数数值范围为(5~30),显示不足位数时高位(左侧)数码管熄灭。

图4 设置界面

4)显示要求

按照题目要求的格式和切换方式设计

数码管显示无重影、闪烁、过暗、亮度不均匀等严重影响显示效果的缺陷。

3.5 按键功能

1、功能说明

使用S4完成界面切换与设置功能。

1)S4:定义为“多功能”按键。

   在“欢迎界面”时,定义为“切换”按键,按下S4按键,切换到“设置界面”。

   在“设置界面”时,定义为“加”按键,按下S4按键,“时间参数”增加5。

2、按键要求

1)按键应做好消抖处理,避免出现一次按键动作导致功能多次触发。

2)按键动作不影响数码管显示等其他功能。

3.6 工作模式

①当光敏电阻处于被遮挡状态时,自动切换到“工作界面”,开始倒计时,同时打开继电器。

②在倒计时过程中,若光敏电阻的遮挡被移开,则立即停止计时并关闭继电器,在“工作界面”继续停留3秒,显示剩余时间。若在这3秒内光敏电阻重新被遮挡,则再次打开继电器并继续计时;若未被遮挡则返回“欢迎界面”。准备下一次工作。

③在倒计时结束后(为0),无论光敏电阻是否被遮挡,均停止计时并关闭继电器,在“工作界面”继续停留3秒,之后返回“欢迎界面”。准备下一次工作。

④在“设置界面”无操作3秒后,自动返回“欢迎界面”。

3.7 LED指示灯功能

1、界面指示灯

1)L1:在“欢迎界面”下,指示灯L1点亮,否则指示灯L1熄灭。

2)L2:在“工作界面”下,指示灯L2点亮,否则指示灯L2熄灭。

3)L3:在“设置界面”下,指示灯L3点亮,否则指示灯L3熄灭。

2、其余试题未涉及的指示灯均处于熄灭状态。

初始状态


请严格按照以下要求设计作品的上电初始状态。

1)处于欢迎界面。

2)默认时间参数为5。

代码

other.h

#ifndef __OTHER_H__
#define __OTHER_H__

#include <STC15F2K60S2.H>
#include "intrins.h"
#define LINE 1.5	//判断光敏电阻是否被遮挡的电压底线
sbit sda=P2^1;
sbit scl=P2^0;
sbit s4=P3^3;
extern unsigned char time_remain;//剩余时间
extern unsigned char time_init;//时间参数
extern unsigned char Seg_Buff[8];//数码管缓存
extern unsigned char keyval;//按键标志
extern unsigned char UI;//界面选择标志,1为欢迎界面,2为工作界面,3为设置界面
extern float num_adc;//光敏电阻电压值

//other.c
void init74hc138(unsigned char n);//74hc138译码器选通
void no_relay(void);//关闭继电器
void relay(void);//打开继电器
void init(void);//系统初始化
void led(void);//LED功能

//seg.c
void Seg_Loop(void);//数码管刷新函数
void seg_ui();//界面显示选择

//key.c
void Key_Loop(void);//按键刷新函数

//iic.c
unsigned char r_adc(unsigned char addr);//AD转换函数

#endif

main.c

#include "other.h"
bit flag_seg=0;
bit flag_key=0;
bit flag_adc=0;
bit flag_time=0;//倒计时开始标志位

void Timer0_Init(void)		//100微秒@12.000MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x50;				//设置定时初始值
	TH0 = 0xFB;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
void Timer1_Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;			//定时器时钟1T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x20;				//设置定时初始值
	TH1 = 0xD1;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	ET1 = 1;				//使能定时器1中断
	EA = 1;
}
void main(){
	init();
	Timer0_Init();
	Timer1_Init();
	num_adc=(float)r_adc(0x01)*5.0/255;
	while((int)(num_adc*100)<(int)(LINE*100))
		num_adc=(float)r_adc(0x01)*5.0/255;
	while(1){
		led();
		if(flag_seg){
			flag_seg=0;
			seg_ui();
			Seg_Loop();
		}
		if(flag_key){
			flag_key=0;
			Key_Loop();
		}
		if(flag_adc){
			flag_adc=0;
			num_adc=(float)r_adc(0x01)*5.0/255;//0x01即选择AIN1通道
		}
		if((int)(num_adc*100)<(int)(LINE*100)){
			UI=2;//切换为工作模式
			relay();//打开继电器
			flag_time=1;
		}else{
			flag_time=0;
		}
	}
}
void Timer0_Isr(void) interrupt 1
{
	static unsigned char count1=0;//数码管定时刷新
	static unsigned char count2=0;//按键定时扫描
	static unsigned int count3=0;//AD转换
	count1++;count2++;count3++;
	if(count1==2){
		count1=0;
		flag_seg=1;
	}
	if(count2==50){
		count2=0;
		flag_key=1;
	}
	if(count3==1000){//0.1s进行一次AD转换
		count3=0;
		flag_adc=1;
	}
}
void Timer1_Isr(void) interrupt 3
{
	static unsigned int count4=0;
	static unsigned int count5=0;
	static unsigned int count6=0;
	static unsigned int count7=0;
	if(flag_time){
		count5=0;
		count4++;
		if(count4==1000){//定时1s
			count4=0;
			if(time_remain>0)
				time_remain--;
		}
	}else if(time_remain>0){
		count4=0;
		count5++;
		if(count5==3000){//定时3s
			count5=0;
			no_relay();
			UI=1;
			time_remain=time_init;
		}
	}else{
		count4=0;
		count5=0;
	}
	if(time_remain==0){
		no_relay();
		count6++;
		if(count6==3000){
			count6=0;
			flag_time=0;
			UI=1;
			time_remain=time_init;
		}
	}else{
		count6=0;
	}
	if(UI==3&&keyval==0){
		count7++;
		if(count7==3000){
			count7=0;
			UI=1;
		}
	}else{
		count7=0;
	}
}

other.c

#include "other.h"
unsigned char UI=1;
unsigned char time_init=5;
unsigned char time_remain=5;
float num_adc;

//74hc138译码器选通
void init74hc138(unsigned char n){
	P2=(P2&0x1f)|(n<<5);
	P2&=0x1f;
}
//系统初始化
void init(void){
	P0=0x00;
	init74hc138(5);//关闭蜂鸣器和继电器
	P0=0xff;
	init74hc138(4);//熄灭LED小灯
	UI=1;
}
//LED功能
void led(void){
	switch(UI){
		case 1://欢迎界面L1亮
			P0=0xfe;init74hc138(4);P0=0xff;break;
		case 2://工作界面L2亮
			P0=0xfd;init74hc138(4);P0=0xff;break;
		case 3://设置界面L3亮
			P0=0xfb;init74hc138(4);P0=0xff;break;
	}
}
//打开继电器
void relay(void){
	P0=0x10;
	init74hc138(5);
	P0=0xff;
}
//关闭继电器
void no_relay(void){
	P0=0x00;
	init74hc138(5);
	P0=0xff;
}

seg.c

#include "other.h"
code unsigned char Seg_Table[] = 
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xc6, //C 10
0x86, //E 11
0x89, //H 12
0xC7,	//L 13
0xff //熄灭 14
};
unsigned char Seg_Buff[8]={14,14,14,14,14,14,14,14};
void seg(unsigned char addr,unsigned char num){
	P0=0xff;	//消隐
	init74hc138(7);
	P0=0x01<<addr;
	init74hc138(6);
	P0=Seg_Table[num];
	init74hc138(7);
}
void Seg_Loop(void){
	static unsigned char i=0;
	seg(i,Seg_Buff[i]);
	i++;
	if(i==8)i=0;
}
void seg_u1(void){
	Seg_Buff[7]=14;
	Seg_Buff[6]=14;
	Seg_Buff[5]=14;
	Seg_Buff[4]=0; //O
	Seg_Buff[3]=13;//L
	Seg_Buff[2]=13;//L
	Seg_Buff[1]=11;//E
	Seg_Buff[0]=12;//H
}
void seg_u2(void){
	Seg_Buff[7]=time_remain%10;
	if(time_remain<10)
		Seg_Buff[6]=14;
	else
		Seg_Buff[6]=time_remain/10;
	
	Seg_Buff[5]=14;
	Seg_Buff[4]=14; 
	Seg_Buff[3]=14;
	Seg_Buff[2]=14;
	Seg_Buff[1]=14;
	Seg_Buff[0]=10;//C
}
void seg_u3(void){
	Seg_Buff[7]=time_init%10;
	if(time_init==5)
		Seg_Buff[6]=14;
	else
		Seg_Buff[6]=time_init/10;
	
	Seg_Buff[5]=14;
	Seg_Buff[4]=14; 
	Seg_Buff[3]=14;
	Seg_Buff[2]=14;
	Seg_Buff[1]=14;
	Seg_Buff[0]=11;//E
}
void seg_ui(){
	switch(UI){
		case 1:seg_u1();break;
		case 2:seg_u2();break;
		case 3:seg_u3();break;
	}
}

key.c

#include "other.h"
unsigned char keyval,keyold,keyup,keydown;

unsigned char Key_Scan(void){
	static unsigned char key_cnt = 0;
	unsigned char temp=0;
	P44=0;
	if(s4==0){
		key_cnt++;
		if(key_cnt >= 20){ // 消抖处理,20ms
			key_cnt = 20;
			
			//在欢迎界面按下,temp=1表示切换到设置界面
			if(UI==1)temp=1;
			
			//在设置界面按下,temp=2表示时间参数增加5
			if(UI==3)temp=2;
		}
	}else{
			key_cnt = 0;
	}
	return temp;
}
void Key_Loop(void){
	keyval=Key_Scan();
	keydown=keyval&(keyold^keyval);
	keyup=~keyval&(keyold^keyval);
	if(keyval==1&&keyold!=1){UI=3;}
	if(keyval==2&&keyold!=2){
		time_init+=5;
		if(time_init==35)time_init=5;
		time_remain=time_init;
	}
	keyold=keyval;
}

iic.c

#include "other.h"
#define DELAY_TIME	5
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}
unsigned char r_adc(unsigned char addr){
	unsigned char temp;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	temp=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return temp;
}

http://www.dtcms.com/a/99417.html

相关文章:

  • 区块链赋能,为木材货场 “智” 造未来
  • vue在线录音系统
  • Redis延时队列在订单超时未报到场景的应用补充说明
  • 利用 VSCode 配置提升 vibe coding 开发效率
  • 找python大数据就业,我应该学习Java哪些知识
  • dav_pg8_vacuum
  • c#的.Net Framework 的console 项目找不到System.Window.Forms 引用
  • VMware中新建Ubuntu虚拟机系统,并安装Anaconda
  • 1--当「穷举」成为艺术:CTF暴力破解漏洞技术从入门到入刑指南(知识点讲解版)
  • Android Architecture Components 深入解析
  • 【力扣刷题|第十七天】0-1 背包 完全背包
  • Linux进程管理的相关知识点以及我的相关笔记链接
  • 算法为舟 思想为楫:AI时代,创作何为?
  • Redis的ZSet有序集合
  • 深度剖析:U盘突然无法访问的数据拯救之道
  • 27. 移除元素【数组专题】Java\Python\JS\Go\C++
  • IP综合实验
  • 曲线拟合 | Matlab基于贝叶斯多项式的曲线拟合
  • Docker, Docker 镜像是什么,怎么创建, Docker有什么用
  • 微服务架构中的精妙设计:SpringCloud的概述
  • Dust3r、Mast3r、Fast3r
  • 信息学奥赛一本通 1609:【例 4】Cats Transport | 洛谷 CF311B Cats Transport
  • VectorBT:使用PyTorch+LSTM训练和回测股票模型 进阶三
  • 【C++初阶】---类和对象(下)
  • 每日一题之修建灌木
  • 2D视觉系统选型(待补充)
  • DHCP报文的详细流程
  • 高精度十进制数运算
  • Python库()
  • 【人工智能之大模型】哪些因素会导致大语言模型LLM的偏见?