51单片机设计篮球计分器程序
时间: 2023-12-10 14:04:00 浏览: 136
以下是基于51单片机的篮球计分器程序的示例代码:
```c
#include <reg51.h>
sbit SCL = P2^1; // I2C时钟线
sbit SDA = P2^0; // I2C数据线
unsigned char code LED_Num[10] = { // 数码管显示数字编码表
0x3f, // 0
0x06, // 1
0x5b, // 2
0x4f, // 3
0x66, // 4
0x6d, // 5
0x7d, // 6
0x07, // 7
0x7f, // 8
0x6f // 9
};
unsigned char code IIC_Address = 0xa0; // I2C设备地址
unsigned char code Key_Value[4][4] = { // 键盘扫描码表
{0xee, 0xde, 0xbe, 0x7e},
{0xed, 0xdd, 0xbd, 0x7d},
{0xeb, 0xdb, 0xbb, 0x7b},
{0xe7, 0xd7, 0xb7, 0x77}
};
unsigned char code Team_Name[2][6] = { // 球队名称
{'H', 'O', 'M', 'E', ' ', ' '},
{'G', 'U', 'E', 'S', 'T', ' '}
};
unsigned char code Display_Name[7] = { // 显示名称
'F', 'O', 'U', 'L', ' ', 'S', ' '
};
unsigned char code IIC_Command[12] = { // I2C命令序列
0x00, // 控制字节
0xc0, // 数据字节1:设置数据指针
0x00, // 数据字节2:设置数据指针
0x40, // 数据字节3:设置写入模式
0x00, // 数据字节4:设置写入模式
0x00, // 数据字节5:设置数据偏移量
0x00, // 数据字节6:设置数据偏移量
0x00, // 数据字节7:设置数据偏移量
0x00, // 数据字节8:设置数据偏移量
0x00, // 数据字节9:设置数据偏移量
0x00, // 数据字节10:设置数据偏移量
0x00 // 数据字节11:设置数据偏移量
};
unsigned char Team_Score[2] = {0, 0}; // 球队得分
unsigned char Team_Foul[2] = {0, 0}; // 球队犯规数
unsigned char Team_Index = 0; // 当前球队编号
unsigned char Key_Buffer = 0xff; // 键盘扫描缓存
void Delay(unsigned int n) // 延时函数,n为延时时间
{
unsigned int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < 125; j++);
}
void IIC_Start() // I2C起始信号
{
SDA = 1;
SCL = 1;
Delay(1);
SDA = 0;
Delay(1);
SCL = 0;
}
void IIC_Stop() // I2C停止信号
{
SDA = 0;
SCL = 1;
Delay(1);
SDA = 1;
Delay(1);
}
void IIC_SendByte(unsigned char dat) // I2C发送一个字节
{
unsigned char i;
for (i = 0; i < 8; i++) {
SDA = dat & 0x80;
SCL = 1;
Delay(1);
SCL = 0;
dat <<= 1;
}
}
unsigned char IIC_ReadByte() // I2C读取一个字节
{
unsigned char i, dat = 0;
SDA = 1;
for (i = 0; i < 8; i++) {
dat <<= 1;
SCL = 1;
Delay(1);
dat |= SDA;
SCL = 0;
Delay(1);
}
return dat;
}
void IIC_Write(unsigned char addr, unsigned char *buf, unsigned char len) // I2C写入数据
{
unsigned char i;
IIC_Start();
IIC_SendByte(addr);
for (i = 0; i < len; i++) {
IIC_SendByte(buf[i]);
}
IIC_Stop();
}
void LED_Display(unsigned char num, unsigned char dot) // 数码管显示
{
unsigned char i;
for (i = 0; i < 8; i++) {
P1 = LED_Num[num];
if (dot && i == 7) { // 显示小数点
P1 &= 0x7f;
}
Delay(1);
P1 = 0x00;
Delay(1);
num >>= 1;
}
}
void Key_Scan() // 键盘扫描
{
unsigned char i, j;
Key_Buffer = 0xff;
for (i = 0; i < 4; i++) {
P3 = ~(1 << i);
for (j = 0; j < 4; j++) {
if ((P3 & (1 << (j + 4))) == 0) {
Key_Buffer = Key_Value[i][j];
return;
}
}
}
}
void IIC_Init() // I2C初始化
{
IIC_Start();
IIC_SendByte(IIC_Address);
IIC_Stop();
}
void Update_Display() // 更新显示
{
unsigned char i, buf[20];
IIC_Init();
IIC_Command[1] = 0x00;
IIC_Command[2] = 0x00;
IIC_Command[9] = 0x07;
IIC_Command[10] = 0x00;
for (i = 0; i < 6; i++) {
buf[i] = Team_Name[Team_Index][i];
}
for (i = 0; i < 7; i++) {
buf[i + 6] = Display_Name[i];
}
buf[13] = Team_Score[Team_Index] / 10;
buf[14] = Team_Score[Team_Index] % 10;
buf[15] = 10;
buf[16] = Team_Foul[Team_Index] / 10;
buf[17] = Team_Foul[Team_Index] % 10;
buf[18] = 10;
buf[19] = 0xff;
IIC_Write(IIC_Address, IIC_Command, 12);
IIC_Write(IIC_Address, buf, 20);
}
void main()
{
unsigned char i, j;
TMOD = 0x01; // 定时器0工作在模式1:16位定时器
TH0 = 0x3c; // 定时器初值
TL0 = 0xb0;
TR0 = 1; // 启动定时器
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许所有中断
P1 = 0x00; // 数码管初始化
P3 = 0xff; // 键盘初始化
Update_Display(); // 显示初始化
while (1) {
Key_Scan();
switch (Key_Buffer) {
case 0xee: // HOME得分
Team_Score[0]++;
break;
case 0xde: // HOME犯规
Team_Foul[0]++;
break;
case 0xbe: // HOME清零
Team_Score[0] = 0;
Team_Foul[0] = 0;
break;
case 0x7e: // 切换到HOME
Team_Index = 0;
break;
case 0xed: // GUEST得分
Team_Score[1]++;
break;
case 0xdd: // GUEST犯规
Team_Foul[1]++;
break;
case 0xbd: // GUEST清零
Team_Score[1] = 0;
Team_Foul[1] = 0;
break;
case 0x7d: // 切换到GUEST
Team_Index = 1;
break;
default:
break;
}
Key_Buffer = 0xff;
Update_Display();
}
}
void Timer0_Isr() interrupt 1 // 定时器0中断服务程序
{
static unsigned char i;
TH0 = 0x3c;
TL0 = 0xb0;
i++;
if (i == 20) { // 200ms刷新一次数码管
i = 0;
LED_Display(Team_Score[Team_Index] / 10, 0);
LED_Display(Team_Score[Team_Index] % 10, 1);
}
}
```
这个程序使用了一个单片机、一个I2C液晶屏、一个4x4矩阵键盘和两个七段数码管。程序实现了计分、犯规和切换球队等功能,并通过I2C液晶屏显示当前的比分和犯规数。程序中的键盘扫描码表、球队名称、显示名称、I2C命令序列等可以根据实际情况进行修改。
阅读全文