适合普中的51开发板,也可以用与自己的课设,工程链接失效了记得
代码,原理图PCB链接
http://链接:https://pan.baidu.com/s/1kcMKkNcIq45z6v0zLAPjeg?pwd=1234 提取码:1234
篮球场计分板
要求:
开机1602显示:
两个按键实现A队的分数加减
两个按键实现B队的分数加减
一个启动键一个暂停键一个按键控制节数一个复位键
(1)开机数码管显示单节比赛时间12分00秒;
(2)矩阵键盘,sw1负责启动,倒计时开始; sw2暂停,sw3清零,清零后显示比赛时间12分00秒,LED显示也清零。
(3)设定每队每次进攻时间为24秒时间,当24秒时间到,进攻方违例,报警LED1~LED3闪烁三次,比赛时间暂停,换方开球进攻并启动计时时间;
(4)单节比赛结束4位数码管闪烁。
(5)进球:分A、B两队进球,两个按键分别表示得分,例如当A队进分球则按下A-SW三下分数加3分,当B队进分球则按下B-SW两下分数加2分 有问题可以加Q3492181286
主函数
#include <REGX52.H>
#include "Delay.h" //包含Delay头文件
#include "Nixie.h" //包含数码管头文件
#include "MatrixKey.h" //矩阵按键头文件
#include "LCD1602.h" //液晶屏头文件
#define NixieTable //定义数码管
unsigned int a=0,i,b=0; //a,b分别为A,B队分数,i为节数
unsigned char KeyNum; //键盘
int min=12;sec=0;sec_24=24; //开机显示
void Timer1Init() //定时器方式1
{
TMOD|=0X10;
TH1=0XFC;
TL1=0X18;
ET1=1;
EA=1;
TR1=1;
}
void main()
{
Timer1Init(); //定时器初始化
LCD_Init(); //LCD初始化
LCD_ShowChar(1,2,'A'); //在1行1列显示字符A
LCD_ShowString(1,8,"VS"); //在1行8列显示字符串VS
LCD_ShowChar(1,15,'B'); //在1行14列显示字符B
LCD_ShowNum(2,14,b,3); //在LCD的2行14列显示b,长度为3位
LCD_ShowNum(2,1,a,3); //在LCD的2行14列显示a,长度为3位
LCD_ShowNum(2,8,i,1); //在LCD的2行8列显示i,长度为1位
TR1=0;
while(1)
{
Nixie(1,min/10); //在数码管的第1位置显示1
Nixie(2,min%10); //在数码管的第2位置显示2
Nixie(3,sec/10); //在数码管的第3位置显示0
Nixie(4,sec%10); //在数码管的第4位置显示0
Nixie(5,sec_24/10); //在数码管的第5位置显示2
Nixie(6,sec_24%10); //在数码管的第6位置显示4
KeyNum=MatrixKey();
if(KeyNum)
{
if(KeyNum==1) //启动
{
TR1=1;
}
if(KeyNum==2) //按键2按下比赛时间暂停
{
TR1=0;
}
if(KeyNum==3) //按键3按下比赛时间复位
{
min=12;
sec=0;
sec_24=24;
}
if(KeyNum==5) //按键5按下A队分数加1
{
LCD_ShowNum(2,1,a=a+1,3);
}while(KeyNum==5);
if(KeyNum==6) //按键6按下B队分数加1
{
LCD_ShowNum(2,14,b=b+1,3);
}while(KeyNum==6);
if(KeyNum==4) //按键4按下节数1
{
LCD_ShowNum(2,8,i=i+1,1);
}while(KeyNum==4);
}
if(sec_24==0) //24秒违规后led闪烁三次
{
TR1=0;
sec_24=24;
P2_3=1;P2_1=1;P2_2=1;
Delay(500);
P2_3=0;P2_1=0;P2_2=0;
Delay(500);
P2_3=1;P2_1=1;P2_2=1;
Delay(500);
P2_3=0;P2_1=0;P2_2=0;
Delay(500);
P2_3=1;P2_1=1;P2_2=1;
Delay(500);
P2_3=0;P2_1=0;P2_2=0;
Delay(500);
}
if(min==0) //12分钟后lcd清零
{
LCD_ShowNum(2,1,0,3);
LCD_ShowNum(2,14,0,3);
LCD_ShowNum(2,8,0,1);
P0=0;
P0=1;
Delay(500);
P0=0;
P0=1;
Delay(500);
}
}
}
void Timer1() interrupt 3 //实现数码管时间变化
{
unsigned int i;
TH1=0XFC;
TL1=0X18;
i++; //以上四行为一秒的函数
if(i==1000) //1000次计次时间为1秒
{
i=0;
sec--;
sec_24--; //秒自减
}
if(sec==0)
{
sec=59;
min--; //分自减
}
}
延时函数<Delay.c>
//延时子函数
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
<Delay.h>
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
#endif
数码管配置函数<Nixie.c>
#include <REGX52.H>
#include "Delay.h" //包含Delay头文件
//数码管段码表
unsigned char NixieTable[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
switch(Location) //位码输出
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number]; //段码输出
Delay(1); //显示一段时间
P0=0x00; //段码清0,消影
}
<Nixie.h>
#ifndef __NIXIE_H__
#define __NIXIE_H__
void Nixie(unsigned char Location,Number);
#endif
矩阵按键<Key.c>
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 矩阵键盘读取按键键码
* @param 无
* @retval KeyNumber 按下按键的键码值
如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0
*/
unsigned char MatrixKey()
{
unsigned char KeyNumber=0;
P1=0xFF;
P1_3=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
P1=0xFF;
P1_2=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
P1=0xFF;
P1_1=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
P1=0xFF;
P1_0=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
return KeyNumber;
}
<Key.h>
#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__
unsigned char MatrixKey();
#endif
LCD1602.c
#include <REGX52.H>
//引脚定义
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_DataPort P0
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay() //@12.000MHz 1ms
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_E=1;
LCD_Delay();
LCD_E=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_E=1;
LCD_Delay();
LCD_E=0;
LCD_Delay();
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init(void)
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0C);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else
{
LCD_WriteCommand(0x80|(Column-1)+0x40);
}
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10);
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
unsigned char SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData('0'+SingleNumber);
}
else
{
LCD_WriteData('A'+SingleNumber-10);
}
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);
}
}
LCD1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__
void LCD_Init(void);
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
#endif