17年电子设计竞赛题

1.题目

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

2.程序

main.c

******************************************************************************
* 文件名:17电赛试题
* 描  述:
* 作  者:思索与猫
* 日  期: 19/5/12
* 备  注: 
*         
******************************************************************************
#include <stc15f2k60s2.h>
#include <sys.h>

void main()
{	
		CloseFucker();
	    Timer0Init();
		while(1)
		{
				ShowTable();
				KeyDriver();
		}
}

sys.c

#include<sys.h>

void Timer0Init()		//1ms@12.000MHz
{
		AUXR |= 0x80;		
		TMOD &= 0xF0;		
		TL0 = 0x20;		
		TH0 = 0xD1;		
		TF0 = 0;		
		TR0 = 1;	
		ET0 = 1;
		EA = 1;
}

void T0_time() interrupt 1
{
		static uint time_count = 0,sec_count = 0,PWM = 0;
		KeyScan();
		Display();
		if(mode == 0&&++time_count >= 3000)   //3秒换行
		{
				time_count = 0;
				x++;	
				if(x >= 4) x = 0;
				if(view == 2&&x >= 3) x = 0;
				ShowLed(x);                   //根据行数亮灯
		}
		
		if(mode == 1&&sec_flag == 1&&++sec_count >= 1000)   //计秒
		{
				sec_count = 0;
				sec++;
				if(sec >= 50) sec = 0;
		}
		
		if(mode == 2)            //序列信号发生器,使用PWM
		{
				if(++PWM >= 80) PWM = 0;
				if(PWM < 10)
				{
						P10 = 1;
				}
				else if(PWM < 30)
				{
						P10 = 0;
				}
				else if(PWM < 40)
				{
						P10 = 1;
				}
				else if(PWM < 50)
				{
						P10 = 0;
				}
				else if(PWM < 80)
				{
						P10 = 1;
				}
		}
}

void CloseFucker()
{
		P2 = P2&0x1f|0xa0;
		P0 = 0xaf;
		P2 = P2&0x1f;
}

sys.h

#ifndef __SYS_H_
#define __SYS_H_

#include<stc15f2k60s2.h>
#include<fun.h>

typedef unsigned char uchar;
typedef unsigned int uint;
//sys
void Timer0Init();
void CloseFucker();
//show
void Display();
void ShowTable();
void ShowLed(uchar led_dat);
//key
void KeyDriver();
void KeyAction(uchar keyvalue);
void KeyScan();

extern uchar Array1[4][3];
extern uchar Array2[4][3];
extern uchar Array3[3][3];
extern uchar x;
extern uchar mode,view;
extern bit sec_flag;
extern uchar sec;

#endif

display.c

#include<sys.h>
uchar code duan[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x80};//10black,11-
uchar Table[8];
uchar Array1[4][3] = {0,0,0,
					  0,0,0,
				      0,0,0,
				      0,0,0};
uchar Array2[4][3] = {0,0,0,
					  0,0,0,
					  0,0,0,
					  0,0,0};
uchar Array3[3][3] = {0,0,0,
					  0,0,0,
					  0,0,0,};
uchar x = 0;
uchar sec = 0;
											
void Display()
{
		static uchar index = 0;
	
		P2 = P2&0x1f|0xe0;
		P0 = 0xff;
		P2 = P2&0x1f;
	
	    P2 = P2&0x1f|0xc0;
		P0 = 1<<index;
		P2 = P2&0x1f;
	
	    P2 = P2&0x1f|0xe0;
		P0 = ~duan[Table[index]];
		P2 = P2&0x1f;
	
		index++;
		index &= 0x07;
}

void ShowTable()
{
		if(mode == 0&&view == 0)      //矩阵显示界面
		{
				Table[0] = 10;
				Table[1] = Array1[x][0]/10;
				Table[2] = Array1[x][0]%10;;
				Table[3] = Array1[x][1]/10;;
				Table[4] = Array1[x][1]%10;;
				Table[5] = Array1[x][2]/10;;	
				Table[6] = Array1[x][2]%10;;
				Table[7] = 10;
		}
		else if(mode == 0&&view == 1)
		{
				Table[0] = 10;
				Table[1] = Array2[x][0]/10;
				Table[2] = Array2[x][0]%10;;
				Table[3] = Array2[x][1]/10;;
				Table[4] = Array2[x][1]%10;;
				Table[5] = Array2[x][2]/10;;	
				Table[6] = Array2[x][2]%10;;
				Table[7] = 10;
		}
		else if(mode == 0&&view == 2)
		{
				Table[0] = 10;
				Table[1] = Array3[x][0]/10;
				Table[2] = Array3[x][0]%10;;
				Table[3] = Array3[x][1]/10;;
				Table[4] = Array3[x][1]%10;;
				Table[5] = Array3[x][2]/10;;	
				Table[6] = Array3[x][2]%10;;
				Table[7] = 10;
		}
		else if(mode == 1)       //计秒显示
		{
				Table[0] = 10;
				Table[1] = 10;
				Table[2] = 10;;
				Table[3] = sec/10;;
				Table[4] = sec%10;;
				Table[5] = 10;;	
				Table[6] = 10;;
				Table[7] = 10;
		}
		else if(mode == 2)       //序列信号发生器界面(自定义)
		{
				Table[0] = 1;
				Table[1] = 0;
				Table[2] = 0;;
				Table[3] = 1;
				Table[4] = 0;;
				Table[5] = 1;;	
				Table[6] = 1;;
				Table[7] = 1;
		}
		
}

void ShowLed(uchar led_dat)
{
		P2 = P2&0x1f|0x80;
		P0 = ~led_dat;
		P2 = P2&0x1f;
}

key.c

#include<sys.h>
#define  add 55     //使用宏定义
#define  sort 56
#define  conv 57
#define  change 58
sbit Key_Out_1 = P3^0;
sbit Key_Out_2 = P3^1;
sbit Key_Out_3 = P3^2;
sbit Key_Out_4 = P3^3;

sbit Key_In_1 = P4^4;
sbit Key_In_2 = P4^2;
sbit Key_In_3 = P3^5;
sbit Key_In_4 = P3^4;

uchar KeySta[4][4] = {{1, 1, 1, 1},
					  {1, 1, 1, 1},
					  {1, 1, 1, 1},
					  {1, 1, 1, 1}};
uchar KeyCodeMap[4][4] = {{0, 1, 2, change},    //键盘图
					      {10, 11, 12, add},
					      {20, 21, 22, sort},
						  {30, 31, 32, conv}};
uchar mode = 0;
uchar view = 0;
bit sec_flag;
													
void KeyDriver()
{
		uchar i = 0,j = 0;
		static uchar KeyBack[4][4] = {{1, 1, 1, 1},
									  {1, 1, 1, 1},
									  {1, 1, 1, 1},
									  {1, 1, 1, 1}};
		for(i=0; i<4; i++)
		{
				for(j=0; j<4; j++)
				{
						if(KeySta[i][j] != KeyBack[i][j])
						{
								if(KeySta[i][j] != 0)
								{
										KeyAction(KeyCodeMap[i][j]);
								}
								KeyBack[i][j] = KeySta[i][j];
						}
				}
		}		
}	

void KeyAction(uchar keyvalue)
{
		if(keyvalue == change)           //切换按钮
		{
				mode++;
				if(mode == 3) mode = 0;
		}
		if(mode == 0)
		{
				if(keyvalue == sort)     //排序按钮
				{
						ArrayTwoSort();
				}
				else if(keyvalue == add) //加法按钮
				{
						view++;
						ShowLed(0x08);
						if(view >= 2)
						{
								ArrayAdd();
								view = 0;
						}											
				}
				else if(keyvalue == conv)     //乘法按钮
				{
						view++;
						ShowLed(0x10);
						if(view == 2)
						{
								ArrayConv();
						}	
						if(view >= 3) view = 0;
				}
				else
				{
						if(view == 0)        //矩阵元素加
						{
								Array1[keyvalue/10][keyvalue%10]++;
								if(Array1[keyvalue/10][keyvalue%10] >= 100) 
								{
										Array1[keyvalue/10][keyvalue%10] = 0;
								}
						}
						else if(view == 1)
						{
								Array2[keyvalue/10][keyvalue%10]++;
								if(Array2[keyvalue/10][keyvalue%10] >= 100) 
								{
										Array2[keyvalue/10][keyvalue%10] = 0;
								}
						}						
				}				
		}
		if(mode == 1)
		{
				if(keyvalue == 21)       //计秒开始
				{
						sec_flag = 1;
						sec = 0;
						x = 0;
				}
				else if(keyvalue == 20)  //计秒结束
				{
						sec_flag = 0;
				}
		}
		
}

void KeyScan()
{
		static uchar KeyBuf[4][4] = {{0xff, 0xff, 0xff, 0xff},
									 {0xff, 0xff, 0xff, 0xff},
									 {0xff, 0xff, 0xff, 0xff},
									 {0xff, 0xff, 0xff, 0xff}};
		uchar i = 0;
		static uchar keyout = 0;
																 
		switch(keyout)
		{
			case 0:Key_Out_1 = 0;Key_Out_4 = 1;break;
			case 1:Key_Out_2 = 0;Key_Out_1 = 1;break;
			case 2:Key_Out_3 = 0;Key_Out_2 = 1;break;
			case 3:Key_Out_4 = 0;Key_Out_3 = 1;break;
		}
		
		KeyBuf[keyout][0] = KeyBuf[keyout][0]<<1|Key_In_1;
		KeyBuf[keyout][1] = KeyBuf[keyout][1]<<1|Key_In_2;
		KeyBuf[keyout][2] = KeyBuf[keyout][2]<<1|Key_In_3;
		KeyBuf[keyout][3] = KeyBuf[keyout][3]<<1|Key_In_4;
		
		for(i=0; i<4; i++)
		{
				if(KeyBuf[keyout][i] == 0x0f)
				{
						KeySta[keyout][i] = 1;
				}
				if(KeyBuf[keyout][i] == 0x00)
				{
						KeySta[keyout][i] = 0;
				}
		}
		keyout++;
		keyout &= 0x03;		
}

fun.c

#include<sys.h>

void ArrayTwoSort()         //二维矩阵排序(从大到小)
{
		uchar i,z = 0,temp=0;
				
		for(z=1; z<12; z++)
		{
				for(i=0; i<11; i++)
				{
						if(Array1[i/3][i%3]<Array1[(i+1)/3][(i+1)%3])
						{
								temp = Array1[i/3][i%3];
								Array1[i/3][i%3] = Array1[(i+1)/3][(i+1)%3];
								Array1[(i+1)/3][(i+1)%3] = temp;
						}
				}
		}	
}

void ArrayAdd()           //二维矩阵相加
{
		uchar i,j;
	
		for(i=0; i<4; i++)
		{
				for(j=0; j<3; j++)
				{
						Array1[i][j] += Array2[i][j];
				}
		}
}

void ArrayConv()          //二维矩阵乘法
{
		uchar i,j,k;
	
		for (i = 0; i <= 2; i++) 
		{
				for ( j = 0; j <= 2; j++) 
				{
						for ( k = 0; k <= 1; k++) 
						{
								Array3[i][j] += Array1[i+1][k] * Array2[k][j];
						}
				}
		}
}

fun.h

#ifndef __FUN_H_
#define __FUN_H_

#include<sys.h>

void ArrayTwoSort();
void ArrayAdd();
void ArrayConv();

#endif

3.总结

这道题并没有很难的算法,即使不会大部分也能在网上找,一次简单练习。
序列信号发生器那部分可以也使用DA输出。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值